packages feed

hlibBladeRF 0.1.0.1 → 0.1.0.2

raw patch · 12 files changed

+213/−181 lines, 12 files

Files

+ ChangeLog view
@@ -0,0 +1,13 @@+Changes in 0.1.0.2++* Minor cabal file fixes.+* Documentation fixes.+* Remove references to 'bladerf_set_tx_gain()' missing symbol.+* Moved from malloc to alloca usage, resolves memory leaks.+* Provide bladeRF{Get,Set}Loopback actions and BladeRFLoopback type.++Changes in 0.1.0.1++* Add a change log.+* LibBladeRF/Flash.hs: Provide untested bladeRFWriteFlash action.+* hlibBladeRF.cabal: Move Bindings.X.Y into other-modules.
hlibBladeRF.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                hlibBladeRF-version:             0.1.0.1+version:             0.1.0.2 synopsis:            Haskell binding to libBladeRF SDR library description:         IO Monadic binding for libbladeRF software defined radio. homepage:            https://victoredwardocallaghan.github.io/hlibBladeRF@@ -14,7 +14,7 @@ copyright:           (c) Edward O'Callaghan, 2015 category:            FFI build-type:          Simple--- extra-source-files:  +extra-source-files:  ChangeLog cabal-version:       >=1.10  --------------------------------------------@@ -73,3 +73,4 @@   type:                git   location:            git://github.com/victoredwardocallaghan/hlibBladeRF   branch:              master+  tag:                 v0.1.0.2
src/Bindings/LibBladeRF/Gain.hsc view
@@ -15,9 +15,6 @@ #ccall bladerf_set_txvga1 , Ptr (<bladerf>) -> CInt -> IO CInt #ccall bladerf_get_txvga1 , Ptr (<bladerf>) -> Ptr (CInt) -> IO CInt --- symb not found--- #ccall bladerf_set_tx_gain , Ptr (<bladerf>) -> CInt -> IO CInt- #ccall bladerf_set_lna_gain , Ptr (<bladerf>) -> <bladerf_lna_gain> -> IO CInt #ccall bladerf_get_lna_gain , Ptr (<bladerf>) -> Ptr (<bladerf_lna_gain>) -> IO CInt 
src/Bindings/LibBladeRF/LibBladeRF.hsc view
@@ -39,8 +39,8 @@  #ccall bladerf_enable_module , Ptr (<bladerf>) -> <bladerf_module> -> Bool -> IO CInt -#ccall bladerf_set_loopback , Ptr (<bladerf>) -> <bladerf_loopback> -> CInt-#ccall bladerf_get_loopback , Ptr (<bladerf>) -> Ptr (<bladerf_loopback>) -> CInt+#ccall bladerf_set_loopback , Ptr (<bladerf>) -> <bladerf_loopback> -> IO CInt+#ccall bladerf_get_loopback , Ptr (<bladerf>) -> Ptr (<bladerf_loopback>) -> IO CInt  -- #ccall bladerf_set_sample_rate , Ptr (<bladerf>) -> <bladerf_module> -> CUInt -> Ptr (CUInt) -> CInt 
src/LibBladeRF/Flash.hs view
@@ -25,37 +25,35 @@ import LibBladeRF.LibBladeRF  --- | Erase regions of the bladeRF's SPI flash+-- | Erase regions of the bladeRF's SPI flash. ----- This function operates in units of 64KiB erase blocks+-- This function operates in units of 64KiB erase blocks. bladeRFEraseFlash :: DeviceHandle  -- ^ Device handle                   -> Word32        -- ^ Erase block to start erasing at                   -> Word32        -- ^ Number of blocks to erase.                   -> IO CInt bladeRFEraseFlash dev b c = c'bladerf_erase_flash (unDeviceHandle dev) b c --- | Read data from the bladeRF's SPI flash+-- | Read data from the bladeRF's SPI flash. -- -- This function operates in units of 256-byte pages. bladeRFReadFlash :: DeviceHandle -- ^ Device handle                  -> Word32       -- ^ Page to begin reading from                  -> Word32       -- ^ Number of pages to read                  -> IO (CInt, Word8)-bladeRFReadFlash dev p c = do-  bptr <- malloc :: IO (Ptr Word8)+bladeRFReadFlash dev p c = alloca $ \bptr -> do   ret <- c'bladerf_read_flash (unDeviceHandle dev) bptr p c   buffer <- peek bptr-  free bptr   return (ret, buffer) --- | Write data from the bladeRF's SPI flash--- XXX - Buffer allocation size must be `page` * BLADERF_FLASH_PAGE_SIZE bytes or larger.+-- | Write data from the bladeRF's SPI flash. bladeRFWriteFlash :: DeviceHandle     -- ^ Device handle                   -> BS.ByteString    -- ^ Data to write to flash                   -> Word32           -- ^ page  Page to begin writing at                   -> Word32           -- ^ count                   -> IO () bladeRFWriteFlash dev b p c = allocaBytes (fromIntegral $ p * c'BLADERF_FLASH_PAGE_SIZE) $ \bptr -> do+  -- XXX - Buffer allocation size must be `page` * BLADERF_FLASH_PAGE_SIZE bytes or larger.   pokeArray bptr (BS.unpack b) -- XXX can we overflow here??   _ <- c'bladerf_write_flash (unDeviceHandle dev) bptr p c   return () -- ignore ret
src/LibBladeRF/Frequency.hs view
@@ -25,7 +25,7 @@ import LibBladeRF.Types  --- | Write value to VCTCXO DAC+-- | Write value to VCTCXO DAC. bladeRFDACWrite :: DeviceHandle -- ^ Device handle                 -> Word16       -- ^ Data to write to DAC register                 -> IO ()@@ -33,15 +33,14 @@   c'bladerf_dac_write (unDeviceHandle dev) v   return () -- ignores ret --- | Get module's current frequency in Hz+-- | Get module's current frequency in Hz. bladeRFGetFrequency :: DeviceHandle  -- ^ Device handle                     -> BladeRFModule -- ^ Module to configure                     -> IO Int        -- ^ Returned frequency bladeRFGetFrequency dev m = do-  pf <- malloc :: IO (Ptr CUInt)-  c'bladerf_get_frequency (unDeviceHandle dev) ((fromIntegral . fromEnum) m) pf-  f <- peek pf-  free pf+  f <- alloca $ \pf -> do+    c'bladerf_get_frequency (unDeviceHandle dev) ((fromIntegral . fromEnum) m) pf+    peek pf   return $ fromIntegral f  -- | Set module's frequency in Hz.@@ -53,19 +52,16 @@   c'bladerf_set_frequency (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral f)   return () -- ignores ret --- | Obtain the current value of the specified configuration parameter+-- | Obtain the current value of the specified configuration parameter. bladeRFGetCorrection :: DeviceHandle       -- ^ Device handle                      -> BladeRFModule      -- ^ Module to retrieve correction information from                      -> BladeRFCorrection  -- ^ Correction type                      -> IO Word16          -- ^ Current value-bladeRFGetCorrection dev m c = do-  pc <- malloc :: IO (Ptr Word16)+bladeRFGetCorrection dev m c = alloca $ \pc -> do   c'bladerf_get_correction (unDeviceHandle dev) ((fromIntegral . fromEnum) m) ((fromIntegral . fromEnum) c) pc-  c <- peek pc-  free pc-  return c+  peek pc --- | Set the value of the specified configuration parameter+-- | Set the value of the specified configuration parameter. bladeRFSetCorrection :: DeviceHandle      -- ^ Device handle                      -> BladeRFModule     -- ^ Module to apply correction to                      -> BladeRFCorrection -- ^ Correction type
src/LibBladeRF/Gain.hs view
@@ -6,7 +6,7 @@   Stability   : provisional   Portability : portable -  This module deals with Gain control+  This module deals with Gain control. -}  module LibBladeRF.Gain ( -- * set,get TxVGA2@@ -25,8 +25,6 @@                        , bladeRFSetLNAGain                        , bladeRFGetLNAGain                        -- * Optimal gain control--- XXX symb not found!!!---                       , bladeRFSetTXGain                        , bladeRFSetGain                        ) where @@ -39,7 +37,7 @@ import LibBladeRF.Types  --- | Set the PA gain in dB+-- | Set the PA gain in dB. bladeRFSetTXVGA2 :: DeviceHandle -- ^ Device handle                  -> Int          -- ^ Desired gain                  -> IO ()@@ -47,17 +45,16 @@   c'bladerf_set_txvga2 (unDeviceHandle dev) (fromIntegral g)   return () -- ignores ret --- | Get the PA gain in dB+-- | Get the PA gain in dB. bladeRFGetTXVGA2 :: DeviceHandle -- ^ Device handle                  -> IO Int       -- ^ Returned gain bladeRFGetTXVGA2 dev = do-  p <- malloc :: IO (Ptr CInt)-  c'bladerf_get_txvga2 (unDeviceHandle dev) p-  g <-  peek p-  free p+  g <- alloca $ \p -> do+    c'bladerf_get_txvga2 (unDeviceHandle dev) p+    peek p   return $ fromIntegral g --- | Set the post-LPF gain in dB+-- | Set the post-LPF gain in dB. bladeRFSetTXVGA1 :: DeviceHandle         -- ^ Device handle                  -> BladeRFVGAGainBounds -- ^ Desired gain                  -> IO ()@@ -65,17 +62,16 @@   c'bladerf_set_txvga1 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)   return () -- ignores ret --- | Get the post-LPF gain in dB+-- | Get the post-LPF gain in dB. bladeRFGetTXVGA1 :: DeviceHandle -- ^ Device handle                  -> IO Int       -- ^ Returned gain bladeRFGetTXVGA1 dev = do-  p <- malloc :: IO (Ptr CInt)-  c'bladerf_get_txvga1 (unDeviceHandle dev) p-  g <-  peek p-  free p+  g <- alloca $ \p -> do+    c'bladerf_get_txvga1 (unDeviceHandle dev) p+    peek p   return $ fromIntegral g --- | Set the post-LPF VGA gain+-- | Set the post-LPF VGA gain. bladeRFSetRXVGA2 :: DeviceHandle         -- ^ Device handle                  -> BladeRFVGAGainBounds -- ^ Desired gain                  -> IO ()@@ -83,17 +79,16 @@   c'bladerf_set_rxvga2 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)   return () -- ignores ret --- | Get the post-LPF VGA gain+-- | Get the post-LPF VGA gain. bladeRFGetRXVGA2 :: DeviceHandle -- ^ Device handle                  -> IO Int       -- ^ Returned set gain level bladeRFGetRXVGA2 dev = do-  p <- malloc :: IO (Ptr CInt)-  c'bladerf_get_rxvga2 (unDeviceHandle dev) p-  g <-  peek p-  free p+  g <- alloca $ \p -> do+    c'bladerf_get_rxvga2 (unDeviceHandle dev) p+    peek p   return $ fromIntegral g --- | Set the pre-LPF VGA gain+-- | Set the pre-LPF VGA gain. bladeRFSetRXVGA1 :: DeviceHandle         -- ^ Device handle                  -> BladeRFVGAGainBounds -- ^ Desired gain                  -> IO ()@@ -101,17 +96,16 @@   c'bladerf_set_rxvga1 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)   return () -- ignores ret --- | Get the pre-LPF VGA gain+-- | Get the pre-LPF VGA gain. bladeRFGetRXVGA1 :: DeviceHandle -- ^ Device handle                  -> IO Int       -- ^ Returned set gain level bladeRFGetRXVGA1 dev = do-  p <- malloc :: IO (Ptr CInt)-  c'bladerf_get_rxvga1 (unDeviceHandle dev) p-  g <-  peek p-  free p+  g <- alloca $ \p -> do+    c'bladerf_get_rxvga1 (unDeviceHandle dev) p+    peek p   return $ fromIntegral g --- | Set LNA Gain+-- | Set LNA Gain. bladeRFSetLNAGain :: DeviceHandle   -- ^ Device handle                   -> BladeRFLNAGain -- ^ Desired gain level                   -> IO ()@@ -119,30 +113,20 @@   c'bladerf_set_lna_gain (unDeviceHandle dev) ((fromIntegral . fromEnum) g)   return () -- ignores ret --- | Get LNA Gain+-- | Get LNA Gain. bladeRFGetLNAGain :: DeviceHandle      -- ^ Device handle                   -> IO BladeRFLNAGain -- ^ Returned set gain level bladeRFGetLNAGain dev = do-  p <- malloc :: IO (Ptr C'bladerf_lna_gain)-  c'bladerf_get_lna_gain (unDeviceHandle dev) p-  g <-  peek p-  free p+  g <- alloca $ \p -> do+    c'bladerf_get_lna_gain (unDeviceHandle dev) p+    peek p   return $ (toEnum . fromIntegral) g +-- | Set a combined pre and post LPF RX gain. ----- | Set a combined VGA TX gain---   This function computes the optimal TXVGA1 and TXVGA2 gains for a requested---   amount of gain--- XXX symb not found!!!---bladeRFSetTXGain :: DeviceHandle -> Int -> IO ()---bladeRFSetTXGain dev g = do---  c'bladerf_set_tx_gain (unDeviceHandle dev) (fromIntegral g)---  return () -- ignores ret---- | Set a combined pre and post LPF RX gain---   This function computes the optimal LNA, RXVGA1, and RVGA2 gains for a---   requested amount of RX gain, and computes the optimal TXVGA1 and TXVGA2 gains---   for a requested amount of TX gain+-- This action computes the optimal LNA, RXVGA1, and RVGA2 gains for a+-- requested amount of RX gain, and computes the optimal TXVGA1 and TXVGA2+-- gains for a requested amount of TX gain bladeRFSetGain :: DeviceHandle  -- ^ Device handle                -> BladeRFModule -- ^ Module                -> Int           -- ^ Desired gain
src/LibBladeRF/Gpio.hs view
@@ -6,7 +6,7 @@   Stability   : provisional   Portability : portable -  This module GPIO configuration handling+  This module GPIO configuration handling. -}  module LibBladeRF.Gpio ( bladeRFConfigGPIORead@@ -22,20 +22,17 @@ import LibBladeRF.Types  --- | Read a configuration GPIO register+-- | Read a configuration GPIO register. bladeRFConfigGPIORead :: DeviceHandle -- ^ Device handle                       -> IO Word32    -- ^ Read data-bladeRFConfigGPIORead dev = do-  pv <- malloc :: IO (Ptr Word32)+bladeRFConfigGPIORead dev = alloca $ \pv -> do   c'bladerf_config_gpio_read (unDeviceHandle dev) pv-  v <- peek pv-  free pv-  return v+  peek pv --- | Write a configuration GPIO register. Callers should be sure to perform a+-- | Write a configuration GPIO register. -----   read-modify-write sequence to avoid accidentally clearing other---   GPIO bits that may be set by the library internally.+-- Callers should be sure to perform a read-modify-write sequence to avoid+-- accidentally clearing other GPIO bits that may be set by the library internally. bladeRFConfigGPIOWrite :: DeviceHandle -- ^ Device handle                        -> Word32       -- ^ Data to write to GPIO register                        -> IO ()
src/LibBladeRF/Sampling.hs view
@@ -23,52 +23,50 @@ import LibBladeRF.Types  --- | Configure the device's sample rate, in Hz.  Note this requires the sample---   rate is an integer value of Hz.  Use bladeRFSetRationalSampleRate---   for more arbitrary values.+-- | Configure the device's sample rate, in Hz.+--+-- Note this requires the sample rate is an integer value of Hz.+-- Use 'bladeRFSetRationalSampleRate' for more arbitrary values. bladeRFSetSampleRate :: DeviceHandle  -- ^ Device handle                      -> BladeRFModule -- ^ Module to change                      -> Int           -- ^ Sample rate                      -> IO Int        -- ^ Actual sample rate achieved. bladeRFSetSampleRate dev m r = do-  par <- malloc :: IO (Ptr CUInt)-  c'bladerf_set_sample_rate (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral r) par-  actual <- peek par-  free par+  actual <- alloca $ \par -> do+         c'bladerf_set_sample_rate (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral r) par+         peek par   return $ fromIntegral actual  -- | Configure the device's sample rate as a rational fraction of Hz.---   Sample rates are in the form of integer + num/denom.+--+-- Sample rates are in the form of integer + num/denom. bladeRFSetRationalSampleRate :: DeviceHandle           -- ^ Device handle                              -> BladeRFModule          -- ^ Module to change                              -> BladeRFRationalRate    -- ^ Rational sample rate                              -> IO BladeRFRationalRate -- ^ Actual rational sample rate achieved. bladeRFSetRationalSampleRate dev m r = do-  pr <- malloc :: IO (Ptr C'bladerf_rational_rate)-  par <- malloc :: IO (Ptr C'bladerf_rational_rate)   let rate = C'bladerf_rational_rate { c'bladerf_rational_rate'integer = integer r                                      , c'bladerf_rational_rate'num     = num r                                      , c'bladerf_rational_rate'den     = den r                                      }-  poke pr rate-  c'bladerf_set_rational_sample_rate (unDeviceHandle dev) ((fromIntegral . fromEnum) m) pr par-  ar <- peek par+  ar <- alloca $ \pr -> do+     poke pr rate+     alloca $ \par -> do+       c'bladerf_set_rational_sample_rate (unDeviceHandle dev) ((fromIntegral . fromEnum) m) pr par+       peek par   let actual = BladeRFRationalRate { integer = c'bladerf_rational_rate'integer ar                                    , num     = c'bladerf_rational_rate'num ar                                    , den     = c'bladerf_rational_rate'den ar                                    }-  free pr-  free par   return actual --- | Set the bandwidth of the LMS LPF to specified value in Hz+-- | Set the bandwidth of the LMS LPF to specified value in Hz. bladeRFSetBandwidth :: DeviceHandle  -- ^ Device handle                     -> BladeRFModule -- ^ Module for bandwidth request                     -> Int           -- ^ Desired bandwidth                     -> IO Int        -- ^ Actual bandwidth that the device was able to achieve. bladeRFSetBandwidth dev m b = do-  ab <- malloc :: IO (Ptr CUInt)-  c'bladerf_set_bandwidth (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral b) ab-  actual <- peek ab-  free ab+  actual <- alloca $ \ab -> do+         c'bladerf_set_bandwidth (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral b) ab+         peek ab   return $ fromIntegral actual
src/LibBladeRF/Sync.hs view
@@ -54,22 +54,21 @@ -- -- Under the hood, this call starts up an underlying asynchronous stream as -- needed. This stream can be stopped by disabling the TX module. (See--- bladeRFEnableModule for more details.)+-- 'LibBladeRF.Utils.bladeRFEnableModule' for more details.) -- -- Samples will only be sent to the FPGA when a buffer have been filled. The -- number of samples required to fill a buffer corresponds to the `buffer_size`--- parameter passed to bladeRFSyncConfig.+-- parameter passed to 'bladeRFSyncConfig'. bladeRFSyncTx :: DeviceHandle    -- ^ Device handle               -> BS.ByteString   -- ^ Array of samples               -> Int             -- ^ Number of samples to write               -> BladeRFMetadata -- ^ Sample metadata. This must be provided when using-                                 --   the ::BLADERF_FORMAT_SC16_Q11_META format, but may+                                 --   the 'FORMAT_SC16_Q11_META' format, but may                                  --   be NULL when the interface is configured for-                                 --   the ::BLADERF_FORMAT_SC16_Q11 format.+                                 --   the 'FORMAT_SC16_Q11' format.               -> Int             -- ^ Timeout (milliseconds) for this call to complete. Zero implies infinite.               -> IO () bladeRFSyncTx dev s n md t = do-  pmd <- malloc :: IO (Ptr C'bladerf_metadata) -- Use the following instead when switching to ghc7.8 later.. -- bladeRFMetadataToCBladeRFMetadata :: BladeRFMetadata -> C'bladerf_metadata   let meta = C'bladerf_metadata { c'bladerf_metadata'timestamp    = timestamp md@@ -78,25 +77,25 @@                                 , c'bladerf_metadata'actual_count = (fromIntegral . count) md                                 , c'bladerf_metadata'reserved     = [0]                                 }-  poke pmd meta-  BS.useAsCStringLen s $-    \(p, _len) -> c'bladerf_sync_tx (unDeviceHandle dev) p (fromIntegral n) pmd (fromIntegral t)-  free pmd+  alloca $ \pmd -> do+    poke pmd meta+    BS.useAsCStringLen s $+      \(p, _len) -> c'bladerf_sync_tx (unDeviceHandle dev) p (fromIntegral n) pmd (fromIntegral t)+  return () -- XXX ignores ret  -- | Receive IQ samples. -- -- Underthe hood, this call starts up an underlying asynchronous stream as -- needed. This stream can be stopped by disabling the RX module. (See--- bladeRFEnableModule for more details.)+-- 'LibBladeRF.Utils.bladeRFEnableModule' for more details.) bladeRFSyncRx :: DeviceHandle    -- ^ Device handle               -> Int             -- ^ Number of samples to read               -> Int             -- ^ Timeout (milliseconds) for this call to complete. Zero implies infinite.               -> IO (BS.ByteString, BladeRFMetadata)-bladeRFSyncRx dev n t = do-  pmd <- malloc :: IO (Ptr C'bladerf_metadata)-  ptr <- mallocBytes (4 * n)-  c'bladerf_sync_rx (unDeviceHandle dev) ptr (fromIntegral n) pmd (fromIntegral t)-  par <- peekArray (4 * n) ptr+bladeRFSyncRx dev n t = alloca $ \pmd -> do+  par <- allocaBytes (4 * n) $ \ptr -> do+      c'bladerf_sync_rx (unDeviceHandle dev) ptr (fromIntegral n) pmd (fromIntegral t)+      peekArray (4 * n) ptr   let bs = BS.pack par   cmd <- peek pmd  -- Use the following instead when switching to ghc7.8 later..@@ -106,5 +105,4 @@                              , status    = c'bladerf_metadata'status       cmd                              , count     = fromIntegral $ c'bladerf_metadata'actual_count cmd                              }-  free pmd   return (bs, meta)
src/LibBladeRF/Types.hs view
@@ -26,6 +26,7 @@ --                        needs ghc >= 7.8 --                        , bladeRFMetadataToCBladeRFMetadata --                        , bladeRFMetadataFromCBladeRFMetadata+                        , BladeRFLoopback(..)                         ) where  @@ -38,8 +39,7 @@ --import Data.Coerce --import GHC.Generics ------ | Version structure for FPGA, firmware, libbladeRF, and associated utilities+-- | Version structure for FPGA, firmware, libbladeRF, and associated utilities. data BladeRFVersion = BladeRFVersion { major :: Word16 -- ^ Major version                                      , minor :: Word16 -- ^ Minor version                                      , patch :: Word16 -- ^ Patch version@@ -52,8 +52,7 @@            show (patch a) ++ " (" ++                 descr a ++ ")" ------ | Information about a bladeRF attached to the system+-- | Information about a bladeRF attached to the system. data BladeRFDeviceInfo = BladeRFDeviceInfo { backend :: BladeRFBackend -- ^ Backend to use when connecting to device                                            , serial  :: String         -- ^ Device serial number string                                            , usbBus  :: Word8          -- ^ Bus number device is attached to@@ -68,8 +67,7 @@            " USB address: " ++ show (usbAddr a) ++ "\n" ++            " Instance: " ++ show (inst a) ------ | FPGA device variant (size)+-- | FPGA device variant (size). data BladeRFFPGASize = FPGA_UNKNOWN -- ^ Unable to determine FPGA variant                      | FPGA_40KLE   -- ^ 40 kLE FPGA                      | FPGA_115KLE  -- ^ 115 kLE FPGA@@ -89,7 +87,7 @@         , (FPGA_115KLE, c'BLADERF_FPGA_115KLE)         ] --- | Backend by which the host communicates with the device+-- | Backend by which the host communicates with the device. data BladeRFBackend = BACKEND_ANY     -- ^ Don't Care, use any available backend                     | BACKEND_LINUX   -- ^ Linux kernel driver                     | BACKEND_LIBUSB  -- ^ libusb@@ -115,14 +113,14 @@            , (BACKEND_DUMMY, c'BLADERF_BACKEND_DUMMY)            ] --- | Rational sample rate representation+-- | Rational sample rate representation. data BladeRFRationalRate = BladeRFRationalRate { integer :: Word64 -- ^ Integer portion                                                , num     :: Word64 -- ^ Numerator in fractional portion                                                , den     :: Word64 -- ^ Denominator in fractional portion. This must be > 0.                                                } deriving (Eq, Show)  --- | Module selection for those which have both RX and TX constituents+-- | Module selection for those which have both RX and TX constituents. data BladeRFModule = MODULE_RX -- ^ Receive Module                    | MODULE_TX -- ^ Transmit Module                    deriving (Eq)@@ -136,7 +134,7 @@           ]  --- | Sample format+-- | Sample format. data BladeRFFormat   {-| Signed, Complex 16-bit Q11. This is the native format of the DAC data. @@ -168,10 +166,10 @@      0x0c [uint32_t:  BLADERF_META_FLAG_* flags]     @ -    When using the 'bladeRFSyncRx' and 'bladeRFSyncTx' actions,-    this detail is transparent to caller. These functions take care of-    packing/unpacking the metadata into/from the data, via the-    bladerf_metadata structure.+    When using the 'LibBladeRF.Sync.bladeRFSyncRx' and+    'LibBladeRF.Sync.bladeRFSyncTx' actions, this detail is transparent to+    caller. These functions take care of packing/unpacking the metadata+    into/from the data, via the 'LibBladeRF.Types.BladeRFMetadata' structure.      Currently, when using the asynchronous data transfer interface, the user     is responsible for manually packing/unpacking this metadata into/from@@ -190,7 +188,7 @@           ]  --- | LNA gain options+-- | LNA gain options. data BladeRFLNAGain = LNA_GAIN_UNKNOWN -- ^ Invalid LNA gain                     | LNA_GAIN_BYPASS  -- ^ LNA bypassed - 0dB gain                     | LNA_GAIN_MID     -- ^ LNA Mid Gain (MAX-6dB)@@ -207,7 +205,7 @@          , (LNA_GAIN_MAX, c'BLADERF_LNA_GAIN_MAX)          ] --- | Device control and configuration+-- | Device control and configuration. -- -- This section provides functions pertaining to accessing, controlling, and -- configuring various device options and parameters.@@ -235,10 +233,11 @@          , (TXVGA2_GAIN_MAX, c'BLADERF_TXVGA2_GAIN_MAX)          ] --- | Correction parameter selection+-- | Correction parameter selection. -- -- These values specify the correction parameter to modify or query when--- calling bladerf_set_correction() or bladerf_get_correction(). Note that the+-- calling 'LibBladeRF.Frequency.bladeRFSetCorrection' or+-- 'LibBladeRF.Frequency.bladeRFGetCorrection'. Note that the -- meaning of the `value` parameter to these functions depends upon the -- correction parameter. data BladeRFCorrection = CORR_LMS_DCOFF_I -- ^ Adjusts the in-phase DC offset via controls provided by the LMS6002D@@ -288,7 +287,7 @@          ]  --- | Sample metadata+-- | Sample metadata. -- -- This structure is used in conjunction with the 'FORMAT_SC16_Q11_META' -- format to TX scheduled bursts or retrieve timestamp information about@@ -301,8 +300,40 @@                                                              --   transmissions/receptions.                                        , count     :: Int    -- ^ This output parameter is updated to reflect the actual                                                              --   number of contiguous samples that have been populated-                                                             --   in an RX buffer during a 'bladeRFSyncRx' call.+                                                             --   in an RX buffer during a 'LibBladeRF.Sync.bladeRFSyncRx' call.                                        }+++-- | Loopback options.+data BladeRFLoopback = LB_FIRMWARE         -- ^ Firmware loopback inside of the FX3+                     | LB_BB_TXLPF_RXVGA2  -- ^ Baseband loopback. TXLPF output is connected to the RXVGA2 input.+                     | LB_BB_TXVGA1_RXVGA2 -- ^ Baseband loopback. TXVGA1 output is connected to the RXVGA2 input.+                     | LB_BB_TXLPF_RXLPF   -- ^ Baseband loopback. TXLPF output is connected to the RXLPF input.+                     | LB_BB_TXVGA1_RXLPF  -- ^ Baseband loopback. TXVGA1 output is connected to RXLPF input.+                     | LB_RF_LNA1          -- ^ RF loopback. The TXMIX output, through the AUX PA, is connected to the+                                           --   output of LNA1.+                     | LB_RF_LNA2          -- ^ RF loopback. The TXMIX output, through the AUX PA, is connected to the+                                           --   output of LNA2.+                     | LB_RF_LNA3          -- ^ RF loopback. The TXMIX output, through the AUX PA, is connected to the+                                           --   output of LNA3.+                     | LB_NONE             -- ^ Disables loopback and returns to normal operation.+                     deriving (Eq)++instance Enum BladeRFLoopback where+  fromEnum = fromJust . flip lookup loopbacks+  toEnum   = fromJust . flip lookup (map swap loopbacks)++loopbacks = [ (LB_FIRMWARE, c'BLADERF_LB_FIRMWARE)+            , (LB_BB_TXLPF_RXVGA2, c'BLADERF_LB_BB_TXLPF_RXVGA2)+            , (LB_BB_TXVGA1_RXVGA2, c'BLADERF_LB_BB_TXVGA1_RXVGA2)+            , (LB_BB_TXLPF_RXLPF, c'BLADERF_LB_BB_TXLPF_RXLPF)+            , (LB_BB_TXVGA1_RXLPF, c'BLADERF_LB_BB_TXVGA1_RXLPF)+            , (LB_RF_LNA1, c'BLADERF_LB_RF_LNA1)+            , (LB_RF_LNA2, c'BLADERF_LB_RF_LNA2)+            , (LB_RF_LNA3, c'BLADERF_LB_RF_LNA3)+            , (LB_NONE, c'BLADERF_LB_NONE)+            ]+   -- | Isomorpishms
src/LibBladeRF/Utils.hs view
@@ -18,6 +18,8 @@                         , bladeRFGetSerial                         , bladeRFGetFPGASize                         , bladeRFEnableModule+                        , bladeRFSetLoopback+                        , bladeRFGetLoopback                         ) where  import Foreign@@ -29,53 +31,50 @@ import LibBladeRF.Types  --- | Get libbladeRF version information--- bladeRFLibVersion :: IO BladeRFVersion+-- | Get libbladeRF version information.+bladeRFLibVersion :: IO BladeRFVersion bladeRFLibVersion = do-  p <- malloc :: IO (Ptr C'bladerf_version)-  c'bladerf_version p-  brfv <- peek p+  brfv <- alloca $ \p -> do+       c'bladerf_version p+       peek p   desc <- peekCString $ c'bladerf_version'describe brfv   let ver = BladeRFVersion { major = c'bladerf_version'major brfv                            , minor = c'bladerf_version'minor brfv                            , patch = c'bladerf_version'patch brfv                            , descr = desc                            }-  free p   return ver --- | Query firmware version+-- | Query firmware version. bladeRFFwVersion :: DeviceHandle      -- ^ Device handle                  -> IO BladeRFVersion -- ^ Returned firmware version bladeRFFwVersion dev = do-  p <- malloc :: IO (Ptr C'bladerf_version)-  c'bladerf_fw_version (unDeviceHandle dev) p-  brfv <- peek p+  brfv <- alloca $ \p -> do+       c'bladerf_fw_version (unDeviceHandle dev) p+       peek p   desc <- peekCString $ c'bladerf_version'describe brfv   let ver = BladeRFVersion { major = c'bladerf_version'major brfv                            , minor = c'bladerf_version'minor brfv                            , patch = c'bladerf_version'patch brfv                            , descr = desc                            }-  free p   return ver --- | Query FPGA version+-- | Query FPGA version. bladeRFFPGAVersion :: DeviceHandle      -- ^ Device handle                    -> IO BladeRFVersion -- ^ Returned firmware version bladeRFFPGAVersion dev = do   status <- c'bladerf_is_fpga_configured (unDeviceHandle dev)   if status > 0 then do-    p <- malloc :: IO (Ptr C'bladerf_version)-    c'bladerf_fpga_version (unDeviceHandle dev) p-    brfv <- peek p+    brfv <- alloca $ \p -> do+         c'bladerf_fpga_version (unDeviceHandle dev) p+         peek p     desc <- peekCString $ c'bladerf_version'describe brfv     let ver = BladeRFVersion { major = c'bladerf_version'major brfv                              , minor = c'bladerf_version'minor brfv                              , patch = c'bladerf_version'patch brfv                              , descr = desc                              }-    free p     return ver   else     return    BladeRFVersion { major = 0@@ -85,9 +84,10 @@                              }  --- | Load device's FPGA. Note that this FPGA configuration will be reset---   at the next power cycle.--- pass Full path to FPGA bitstream+-- | Load device's FPGA.+--+-- Note that this FPGA configuration will be reset at the next+-- power cycle. Pass Full path to FPGA bitstream. bladeRFLoadFPGA :: DeviceHandle -- ^ Device handle                 -> String       -- ^ Full path to FPGA bitstream                 -> IO ()@@ -96,59 +96,78 @@   _ <- c'bladerf_load_fpga (unDeviceHandle dev) p   return () --- | Obtain the bus speed at which the device is operating+-- | Obtain the bus speed at which the device is operating. bladeRFDeviceSpeed :: DeviceHandle    -- ^ Device handle                    -> IO BladeRFSpeed -- ^ Device speed bladeRFDeviceSpeed dev = do   speed <- c'bladerf_device_speed (unDeviceHandle dev)   return $ (toEnum . fromEnum) speed --- | Fill out a provided bladerf_devinfo structure, given an open device handle.+-- | Fill out a provided 'LibBladeRF.Types.BladeRFDevInfo' structure, given an open device handle. bladeRFGetDevInfo :: DeviceHandle         -- ^ Device handle                   -> IO BladeRFDeviceInfo -- ^ Device information populated by this function bladeRFGetDevInfo dev = do-  p <- malloc :: IO (Ptr C'bladerf_devinfo)-  c'bladerf_get_devinfo (unDeviceHandle dev) p--- XXX ^ handle status return error with Maybe monad???-  brfv <- peek p+  brfv <- alloca $ \p -> do+       c'bladerf_get_devinfo (unDeviceHandle dev) p+       -- XXX ^ handle status return error with Maybe monad???+       peek p   let info = BladeRFDeviceInfo { backend = toEnum . fromEnum . c'bladerf_devinfo'backend $ brfv                                , serial  = map castCCharToChar . c'bladerf_devinfo'serial $ brfv                                , usbBus  = c'bladerf_devinfo'usb_bus brfv                                , usbAddr = c'bladerf_devinfo'usb_addr brfv                                , inst    = c'bladerf_devinfo'instance brfv                                }-  free p   return info --- | Query a device's serial number+-- | Query a device's serial number. bladeRFGetSerial :: DeviceHandle -- ^ Device handle                  -> IO String    -- ^ Returned serial number.-bladeRFGetSerial dev = do-  cstring <- mallocBytes 34 -- device serial is 33 bytes long + null terminating byte.+bladeRFGetSerial dev = allocaBytes 34 $ \cstring -> do   -- API bug bladerf_get_serial() should be allocating the buffer itself, not the call site!+  -- See upstream report: https://github.com/Nuand/bladeRF/issues/382+  -- device serial is 33 bytes long + null terminating byte.   c'bladerf_get_serial (unDeviceHandle dev) cstring-  serial <- peekCString cstring-  free cstring-  return serial+  peekCString cstring --- | Query a device's FPGA size+-- | Query a device's FPGA size. bladeRFGetFPGASize :: DeviceHandle       -- ^ Device handle                    -> IO BladeRFFPGASize -- ^ Returned on-board FPGA's size. bladeRFGetFPGASize dev = do-  p <- malloc :: IO (Ptr C'bladerf_fpga_size)-  c'bladerf_get_fpga_size (unDeviceHandle dev) p-  sz <- peek p-  free p+  sz <- alloca $ \p -> do+     c'bladerf_get_fpga_size (unDeviceHandle dev) p+     peek p   return $ (toEnum . fromEnum) sz - -- | Enable or disable the specified RX/TX module.---   When a synchronous stream is associated with the specified module, this---   will shut down the underlying asynchronous stream when `enable` = false.+--+-- When a synchronous stream is associated with the specified module, this+-- will shut down the underlying asynchronous stream when `enable` = 'False'. bladeRFEnableModule :: DeviceHandle  -- ^ Device handle                     -> BladeRFModule -- ^ Device module-                    -> Bool          -- ^ true to enable, false to disable+                    -> Bool          -- ^ 'True' to enable, 'False' to disable                     -> IO () bladeRFEnableModule dev m t = do   c'bladerf_enable_module (unDeviceHandle dev) ((fromIntegral . fromEnum) m) t   return () -- XXX ignore ret++-- | Apply specified loopback mode.+--+-- Loopback modes should only be enabled or disabled while the RX and TX+-- modules are both disabled (and therefore, when no samples are being+-- actively streamed). Otherwise, unexpected behavior may occur.+bladeRFSetLoopback :: DeviceHandle    -- ^ Device handle+                   -> BladeRFLoopback -- ^ Loopback mode. Note that 'LB_NONE'+                                      --   disables the use of loopback functionality.+                   -> IO ()+bladeRFSetLoopback dev l = do+  c'bladerf_set_loopback (unDeviceHandle dev) ((fromIntegral . fromEnum) l)+  return () -- XXX ignore ret++-- | Get current loopback mode.+bladeRFGetLoopback :: DeviceHandle       -- ^ Device handle+                   -> IO BladeRFLoopback -- ^ Current loopback mode+bladeRFGetLoopback dev = do+  l <- alloca $ \lp -> do+    c'bladerf_get_loopback (unDeviceHandle dev) lp+    peek lp+  return $ (toEnum . fromEnum) l