packages feed

rtlsdr (empty) → 0.1.0.0

raw patch · 4 files changed

+434/−0 lines, 4 filesdep +arraydep +basesetup-changed

Dependencies added: array, base

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Adam Walker++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Adam Walker nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ RTLSDR.chs view
@@ -0,0 +1,368 @@+{-# LANGUAGE EmptyDataDecls #-}+module RTLSDR (+    getDeviceCount,+    getDeviceName,+    getDeviceUSBString,+    GIBSError(..),+    getIndexBySerial,+    RTLSDR,+    open,+    close,+    setXtalFreq,+    getXtalFreq,+    getUSBStrings,+    EEPROMError(..),+    writeEEPROM,+    readEEPROM,+    setCenterFreq,+    getCenterFreq,+    setFreqCorrection,+    getFreqCorrection,+    Tuner(..),+    getTunerType,+    getTunerGains,+    setTunerGain,+    getTunerGain,+    setTunerIFGain,+    setTunerGainMode,+    setSampleRate,+    getSampleRate,+    setTestMode,+    setAGCMode,+    DirectSamplingMode(..),+    setDirectSampling,+    getDirectSampling,+    setOffsetTuning,+    getOffsetTuning,+    resetBuffer,+    readSync,+    ReadCallback,+    readAsync,+    cancelAsync+    ) where++#include <rtl-sdr.h>++import Foreign.C.Types+import Foreign.C.String+import Foreign.Marshal.Alloc+import Foreign.Marshal.Array+import Foreign.Ptr+import Foreign.Storable++import Data.Word+import Data.Int+import Control.Monad+import Data.Array.MArray+import Data.Array.Storable++justWhenM :: Monad m => Bool -> m a -> m (Maybe a)+justWhenM cond act = if cond then liftM Just act else return Nothing++b2int :: Num i => Bool -> i+b2int False = 0+b2int True  = 1++foreign import ccall unsafe "rtlsdr_get_device_count"+    c_getDeviceCount :: IO CUInt++getDeviceCount :: IO Word32+getDeviceCount = liftM fromIntegral c_getDeviceCount++foreign import ccall unsafe "rtlsdr_get_device_name"+    c_rtlsdrGetDeviceName :: CUInt -> IO CString++getDeviceName :: Word32 -> IO String+getDeviceName index = c_rtlsdrGetDeviceName (fromIntegral index) >>= peekCString ++foreign import ccall unsafe "rtlsdr_get_device_usb_strings"+    c_getDeviceUSBStrings :: CUInt -> Ptr CChar -> Ptr CChar -> Ptr CChar -> IO CInt++getDeviceUSBString :: Word32 -> IO (Maybe (String, String, String))+getDeviceUSBString index = +    allocaArray 256 $ \mp -> +    allocaArray 256 $ \pp -> +    allocaArray 256 $ \sp -> do+        res <- c_getDeviceUSBStrings (fromIntegral index) mp pp sp +        justWhenM (res==0) $ do+            m <- peekCString mp+            p <- peekCString pp+            s <- peekCString sp+            return (m, p, s)+        +foreign import ccall unsafe "rtlsdr_get_index_by_serial"+    c_getIndexBySerial :: CString -> IO CInt++-- Get Index By Serial Error+data GIBSError = NameNull+               | NoDevices+               | NoMatching+               deriving (Show)++toGIBSError :: Int -> GIBSError+toGIBSError (-1) = NameNull+toGIBSError (-2) = NoDevices+toGIBSError (-3) = NoMatching+toGIBSError _    = error "rtlsdr_get_index_by_serial returned invalid error code"++getIndexBySerial :: String -> IO (Either GIBSError Int)+getIndexBySerial serial = liftM (func . fromIntegral) $ withCString serial c_getIndexBySerial +    where func res +            | res < 0   = Left (toGIBSError res)+            | otherwise = Right res++data CRTLSDR+data RTLSDR = RTLSDR (Ptr CRTLSDR)++foreign import ccall unsafe "rtlsdr_open"+    c_open :: Ptr (Ptr CRTLSDR) -> CInt -> IO CInt++open :: Word32 -> IO (Maybe RTLSDR)+open index = alloca $ \ptr -> do+    res <- c_open ptr (fromIntegral index)+    justWhenM (res >= 0) $ do+        res <- peek ptr+        return $ RTLSDR res++foreign import ccall unsafe "rtlsdr_close"+    c_close :: Ptr CRTLSDR -> IO CInt++close :: RTLSDR -> IO ()+close (RTLSDR ptr) = void $ c_close ptr++foreign import ccall unsafe "rtlsdr_set_xtal_freq"+    c_setXtalFreq :: Ptr CRTLSDR -> CUInt -> CUInt -> IO CInt++setXtalFreq :: RTLSDR -> Word32 -> Word32 -> IO Bool+setXtalFreq (RTLSDR ptr) rtlFreq tunerFreq = liftM (==0) $ c_setXtalFreq ptr (fromIntegral rtlFreq) (fromIntegral tunerFreq)++foreign import ccall unsafe "rtlsdr_get_xtal_freq"+    c_getXtalFreq :: Ptr CRTLSDR -> Ptr CUInt -> Ptr CUInt -> IO CInt++getXtalFreq :: RTLSDR -> IO (Maybe (Word32, Word32))+getXtalFreq (RTLSDR ptr) = +    alloca $ \rp -> +    alloca $ \tp -> do+        res <- c_getXtalFreq ptr rp tp+        justWhenM (res /= 0) $ do+            r <- peek rp+            t <- peek tp+            return (fromIntegral r, fromIntegral t)++foreign import ccall unsafe "rtlsdr_get_usb_strings"+    c_getUSBStrings :: Ptr CRTLSDR -> Ptr CChar -> Ptr CChar -> Ptr CChar -> IO CInt++getUSBStrings :: RTLSDR -> IO (Maybe (String, String, String))+getUSBStrings (RTLSDR ptr) = +    allocaArray 256 $ \mp -> +    allocaArray 256 $ \pp -> +    allocaArray 256 $ \sp -> do+        res <- c_getUSBStrings ptr mp pp sp +        justWhenM (res == 0) $ do+            m <- peekCString mp+            p <- peekCString pp+            s <- peekCString sp+            return (m, p, s)++data EEPROMError = InvalidHandle+                 | SizeExceeded+                 | NoEEPROM+                 deriving(Show)++toEEPROMError :: Int -> EEPROMError+toEEPROMError (-1) = InvalidHandle+toEEPROMError (-2) = SizeExceeded+toEEPROMError (-3) = NoEEPROM+toEEPROMError _    = error "librtlsdr returned invalid EEPROM error code"++foreign import ccall unsafe "rtlsdr_write_eeprom"+    c_writeEEPROM :: Ptr CRTLSDR -> Ptr CUChar -> CUChar -> CUShort -> IO CInt++writeEEPROM :: RTLSDR -> [Word8] -> Int -> IO (Maybe EEPROMError)+writeEEPROM (RTLSDR ptr) dataa offset = +    liftM (func . fromIntegral) $ withArrayLen (map fromIntegral dataa) $ \size ptrd -> c_writeEEPROM ptr ptrd (fromIntegral offset) (fromIntegral size)+    where func x+            | x < 0     = Just $ toEEPROMError x+            | otherwise = Nothing++foreign import ccall unsafe "rtlsdr_read_eeprom"+    c_readEEPROM :: Ptr CRTLSDR -> Ptr CUChar -> CUChar -> CUShort -> IO CInt++readEEPROM :: RTLSDR -> Int -> Int -> IO (Either EEPROMError [Word8])+readEEPROM (RTLSDR ptr) offset len = allocaArray len $ \ptrd -> do+    res <- c_readEEPROM ptr ptrd (fromIntegral offset) (fromIntegral len)+    case res < 0 of+        True  -> return $ Left $ toEEPROMError $ fromIntegral res+        False -> do+            res <- peekArray len ptrd+            return $ Right $ map fromIntegral res++foreign import ccall unsafe "rtlsdr_set_center_freq"+    c_setCenterFreq :: Ptr CRTLSDR -> CUInt -> IO CInt++setCenterFreq :: RTLSDR -> Word32 -> IO Bool+setCenterFreq (RTLSDR ptr) freq = liftM (==0) $ c_setCenterFreq ptr (fromIntegral freq)++foreign import ccall unsafe "rtlsdr_get_center_freq"+    c_getCenterFreq :: Ptr CRTLSDR -> IO CUInt++getCenterFreq :: RTLSDR -> IO (Maybe Word32)+getCenterFreq (RTLSDR ptr) = liftM func $ c_getCenterFreq ptr+    where func 0 = Nothing+          func x = Just $ fromIntegral x++foreign import ccall unsafe "rtlsdr_set_freq_correction"+    c_setFreqCorrection :: Ptr CRTLSDR -> CInt -> IO CInt++setFreqCorrection :: RTLSDR -> Int32 -> IO Bool+setFreqCorrection (RTLSDR ptr) ppm = liftM (==0) $ c_setFreqCorrection ptr (fromIntegral ppm)++foreign import ccall unsafe "rtlsdr_get_freq_correction"+    c_getFreqCorrection :: Ptr CRTLSDR -> IO CInt++getFreqCorrection :: RTLSDR -> IO Int32 +getFreqCorrection (RTLSDR ptr) = liftM fromIntegral $ c_getFreqCorrection ptr++{#enum rtlsdr_tuner as Tuner {underscoreToCase} deriving (Show, Eq) #}++foreign import ccall unsafe "rtlsdr_get_tuner_type"+    c_getTunerType :: Ptr CRTLSDR -> IO CInt++getTunerType :: RTLSDR -> IO Tuner+getTunerType (RTLSDR ptr) = liftM (toEnum . fromIntegral) $ c_getTunerType ptr++foreign import ccall unsafe "rtlsdr_get_tuner_gains"+    c_getTunerGains :: Ptr CRTLSDR -> Ptr CInt -> IO CInt++getTunerGains :: RTLSDR -> IO (Maybe [Int])+getTunerGains (RTLSDR ptr) = do+    num <- c_getTunerGains ptr nullPtr +    justWhenM (num >= 0) $ +        allocaArray (fromIntegral num) $ \ptrg -> do+            c_getTunerGains ptr ptrg+            res <- peekArray (fromIntegral num) ptrg+            return $ map fromIntegral res++foreign import ccall unsafe "rtlsdr_set_tuner_gain"+    c_setTunerGain :: Ptr CRTLSDR -> CInt -> IO CInt++setTunerGain :: RTLSDR -> Int32 -> IO Bool+setTunerGain (RTLSDR ptr) gain = liftM (==0) $ c_setTunerGain ptr (fromIntegral gain)++foreign import ccall unsafe "rtlsdr_get_tuner_gain"+    c_getTunerGain :: Ptr CRTLSDR -> IO CInt++getTunerGain :: RTLSDR -> IO (Maybe Int32)+getTunerGain (RTLSDR ptr) = liftM func $ c_getTunerGain ptr+    where func 0 = Nothing+          func x = Just $ fromIntegral x++foreign import ccall unsafe "rtlsdr_set_tuner_if_gain"+    c_setTunerIFGain :: Ptr CRTLSDR -> CInt -> CInt -> IO CInt++setTunerIFGain :: RTLSDR -> Int -> Int -> IO Bool+setTunerIFGain (RTLSDR ptr) stage gain = liftM (==0) $ c_setTunerIFGain ptr (fromIntegral stage) (fromIntegral gain)++foreign import ccall unsafe "rtlsdr_set_tuner_gain_mode"+    c_setTunerGainMode :: Ptr CRTLSDR -> CInt -> IO CInt++setTunerGainMode :: RTLSDR -> Bool -> IO Bool+setTunerGainMode (RTLSDR ptr) mode = liftM (==0) $ c_setTunerGainMode ptr (b2int mode)++foreign import ccall unsafe "rtlsdr_set_sample_rate"+    c_setSampleRate :: Ptr CRTLSDR -> CUInt -> IO CInt++setSampleRate :: RTLSDR -> Word32 -> IO Bool+setSampleRate (RTLSDR ptr) rate = liftM (==0) $ c_setSampleRate ptr (fromIntegral rate)++foreign import ccall unsafe "rtlsdr_get_sample_rate"+    c_getSampleRate :: Ptr CRTLSDR -> IO CUInt++getSampleRate :: RTLSDR -> IO (Maybe Word32)+getSampleRate (RTLSDR ptr) = liftM func $ c_getSampleRate ptr+    where func 0 = Nothing+          func x = Just $ fromIntegral x++foreign import ccall unsafe "rtlsdr_set_testmode"+    c_setTestmode :: Ptr CRTLSDR -> CInt -> IO CInt++setTestMode :: RTLSDR -> Bool -> IO Bool+setTestMode (RTLSDR ptr) on = liftM (==0) $ c_setTestmode ptr (b2int on)++foreign import ccall unsafe "rtlsdr_set_agc_mode"+    c_setAGCMode :: Ptr CRTLSDR -> CInt -> IO CInt++setAGCMode :: RTLSDR -> Bool -> IO Bool+setAGCMode (RTLSDR ptr) on = liftM (==0) $ c_setAGCMode ptr (b2int on)++data DirectSamplingMode = DSDisabled+                        | DSI+                        | DSQ+                        deriving (Enum, Show, Eq)++foreign import ccall unsafe "rtlsdr_set_direct_sampling"+    c_setDirectSampling :: Ptr CRTLSDR -> CInt -> IO CInt++setDirectSampling :: RTLSDR -> DirectSamplingMode -> IO Bool+setDirectSampling (RTLSDR ptr) mode = liftM (==0) $ c_setDirectSampling ptr (fromIntegral $ fromEnum mode)++foreign import ccall unsafe "rtlsdr_get_direct_sampling"+    c_getDirectSampling :: Ptr CRTLSDR -> IO CInt++getDirectSampling :: RTLSDR -> IO (Maybe DirectSamplingMode)+getDirectSampling (RTLSDR ptr) = do+    res <- c_getDirectSampling ptr+    justWhenM (res >= 0) $ +        return $ toEnum $ fromIntegral res++foreign import ccall unsafe "rtlsdr_set_offset_tuning"+    c_setOffsetTuning :: Ptr CRTLSDR -> CInt -> IO CInt++setOffsetTuning :: RTLSDR -> Bool -> IO Bool+setOffsetTuning (RTLSDR ptr) on = liftM (==0) $ c_setOffsetTuning ptr (b2int on)++foreign import ccall unsafe "rtlsdr_get_offset_tuning"+    c_getOffsetTuning :: Ptr CRTLSDR -> IO CInt++getOffsetTuning :: RTLSDR -> IO (Maybe Bool)+getOffsetTuning (RTLSDR ptr) = do+    res <- c_getOffsetTuning ptr+    justWhenM (res >= 0) $ +        return $ res == 1++foreign import ccall unsafe "rtlsdr_reset_buffer"+    c_resetBuffer :: Ptr CRTLSDR -> IO CInt++resetBuffer :: RTLSDR -> IO Int+resetBuffer (RTLSDR ptr) = liftM fromIntegral $ c_resetBuffer ptr++foreign import ccall unsafe "rtlsdr_read_sync"+    c_readSync :: Ptr CRTLSDR -> Ptr CUChar -> CInt -> Ptr CInt -> IO CInt++readSync :: RTLSDR -> Ptr CUChar -> Int -> IO Bool+readSync (RTLSDR ptr) aptr len = do+    res <- alloca $ c_readSync ptr aptr (fromIntegral len) +    return $ res >= 0 ++type ReadCallback = Ptr CUChar -> Word32 -> Ptr CInt -> IO ()++foreign import ccall "wrapper"+    wrap :: ReadCallback -> IO (FunPtr ReadCallback)++foreign import ccall safe "rtlsdr_read_async"+    c_readAsync :: Ptr CRTLSDR -> FunPtr ReadCallback -> Ptr () -> CUInt -> CUInt -> IO CInt++readAsync :: RTLSDR -> Word32 -> Word32 -> (Ptr CUChar -> Int -> IO ()) -> IO Bool+readAsync (RTLSDR ptr) bufNum bufLen callback = do+    cb <- wrap f+    res <- c_readAsync ptr cb nullPtr (fromIntegral bufNum) (fromIntegral bufLen)+    return $ res == 0+    where+    f buf len ctx = callback buf (fromIntegral len)++foreign import ccall unsafe "rtlsdr_cancel_async"+    c_cancelAsync :: Ptr CRTLSDR -> IO CInt++cancelAsync :: RTLSDR -> IO Bool+cancelAsync (RTLSDR ptr) = liftM (==0) $ c_cancelAsync ptr+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ rtlsdr.cabal view
@@ -0,0 +1,34 @@+-- Initial rtlsdr.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++name:                rtlsdr+version:             0.1.0.0+synopsis:            Bindings to librtlsdr+description:         +    Bindings to librtlsdr. Turns your Realtek RTL2832 based DVB dongle into a SDR receiver. +    .+    For more information see: http://sdr.osmocom.org/trac/wiki/rtl-sdr+license:             BSD3+license-file:        LICENSE+author:              Adam Walker+maintainer:          adamwalker10@gmail.com+copyright:           2014 Adam Walker+category:            Software defined radio+build-type:          Simple+-- extra-source-files:  +cabal-version:       >=1.10++source-repository head+    type: git+    location: https://github.com/adamwalker/hrtlsdr++library+    exposed-modules:     RTLSDR+    -- other-modules:       +    other-extensions:    EmptyDataDecls+    build-depends:       base >=4.6 && <4.8, array >=0.4 && <0.6+    -- hs-source-dirs:      +    build-tools:         c2hs+    default-language:    Haskell2010+    extra-libraries:     rtlsdr+    -- ghc-options:         -Wall