hlibBladeRF 0.1.0.1 → 0.1.0.2
raw patch · 12 files changed
+213/−181 lines, 12 files
Files
- ChangeLog +13/−0
- hlibBladeRF.cabal +3/−2
- src/Bindings/LibBladeRF/Gain.hsc +0/−3
- src/Bindings/LibBladeRF/LibBladeRF.hsc +2/−2
- src/LibBladeRF/Flash.hs +6/−8
- src/LibBladeRF/Frequency.hs +9/−13
- src/LibBladeRF/Gain.hs +30/−46
- src/LibBladeRF/Gpio.hs +7/−10
- src/LibBladeRF/Sampling.hs +18/−20
- src/LibBladeRF/Sync.hs +14/−16
- src/LibBladeRF/Types.hs +51/−20
- src/LibBladeRF/Utils.hs +60/−41
+ 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