{-| Module : $Header$ Copyright : (c) 2014 Edward O'Callaghan License : LGPL-2.1 Maintainer : eocallaghan@alterapraxis.com Stability : provisional Portability : portable This module encapsulates misc libbladeRF library functions. -} module LibBladeRF.Utils ( bladeRFLibVersion , bladeRFFwVersion , bladeRFFPGAVersion , bladeRFDeviceSpeed , bladeRFLoadFPGA , bladeRFGetDevInfo , bladeRFGetSerial , bladeRFGetFPGASize , bladeRFEnableModule ) where import Foreign import Foreign.C.Types import Foreign.C.String import Bindings.LibBladeRF import LibBladeRF.LibBladeRF import LibBladeRF.Types -- | Get libbladeRF version information -- bladeRFLibVersion :: IO BladeRFVersion bladeRFLibVersion = do p <- malloc :: IO (Ptr C'bladerf_version) c'bladerf_version p brfv <- 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 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 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 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 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 , minor = 0 , patch = 0 , descr = "Unknown (FPGA not loaded)" } -- | 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 () bladeRFLoadFPGA dev s = do p <- newCString s _ <- c'bladerf_load_fpga (unDeviceHandle dev) p return () -- | 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. 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 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 bladeRFGetSerial :: DeviceHandle -- ^ Device handle -> IO String -- ^ Returned serial number. bladeRFGetSerial dev = do cstring <- mallocBytes 34 -- device serial is 33 bytes long + null terminating byte. -- API bug bladerf_get_serial() should be allocating the buffer itself, not the call site! c'bladerf_get_serial (unDeviceHandle dev) cstring serial <- peekCString cstring free cstring return serial -- | 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 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. bladeRFEnableModule :: DeviceHandle -- ^ Device handle -> BladeRFModule -- ^ Device module -> 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