packages feed

ftdi 0.1 → 0.2

raw patch · 2 files changed

+63/−44 lines, 2 filesdep +monads-fddep ~basedep ~base-unicode-symbolsdep ~transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: monads-fd

Dependency ranges changed: base, base-unicode-symbols, transformers

API changes (from Hackage documentation)

- System.FTDI: readData :: (MonadIO m) => InterfaceHandle -> Int -> ChunkedReaderT m [ByteString]
+ System.FTDI: readData :: (MonadIO m) => InterfaceHandle -> m Bool -> Int -> ChunkedReaderT m [ByteString]

Files

System/FTDI/Internal.hs view
@@ -14,7 +14,7 @@ -- Imports ------------------------------------------------------------------------------- --- base+-- from base: import Control.Applicative       ( Applicative, (<$>), Alternative ) import Control.Exception         ( Exception, bracket, throwIO ) import Control.Monad             ( Functor@@ -24,6 +24,9 @@                                  ) import Control.Monad.Fix         ( MonadFix ) import Data.Bool                 ( Bool, otherwise )+#ifdef __HADDOCK__+import Data.Bool                 ( Bool(False, True) )+#endif import Data.Bits                 ( Bits, (.|.)                                  , setBit, shiftL, shiftR, testBit                                  )@@ -50,30 +53,31 @@ import Text.Read                 ( Read ) import Text.Show                 ( Show ) --- base-unicode-symbols+-- from base-unicode-symbols: import Data.Eq.Unicode           ( (≡) ) import Data.Function.Unicode     ( (∘) ) import Data.Monoid.Unicode       ( (⊕) ) import Prelude.Unicode           ( (⋅), (÷) ) --- bytestring-import qualified Data.ByteString as BS ( drop, length, null, splitAt, unpack )-#ifdef __HADDOCK__-import qualified Data.ByteString as BS ( empty )-#endif+-- from bytestring:+import qualified Data.ByteString as BS ( empty, drop, length+                                       , null, splitAt, unpack+                                       ) import Data.ByteString           ( ByteString ) --- ftdi+-- from ftdi: import System.FTDI.Utils         ( divRndUp, clamp, genFromEnum, orBits ) --- safe+-- from monads-fd:+import Control.Monad.Trans       ( MonadTrans, MonadIO, lift, liftIO )++-- from safe: import Safe                      ( atMay, headMay ) --- transformers-import Control.Monad.Trans       ( MonadTrans, MonadIO, liftIO )+-- from transformers: import Control.Monad.Trans.State ( StateT, get, put, runStateT ) --- usb+-- from usb: import qualified System.USB as USB  @@ -158,7 +162,7 @@ -- Devices ------------------------------------------------------------------------------- --- |A representation of an FTDI device. +-- |A representation of an FTDI device. data Device = Device     { devUSB      ∷ USB.Device     , devUSBConf  ∷ USB.ConfigDesc@@ -279,7 +283,7 @@ closeDevice ∷ DeviceHandle → IO () closeDevice = USB.closeDevice ∘ devHndUSB --- |The recommended way to acquire a handle. Ensures that the handles+-- |The recommended way to acquire a handle. Ensures that the handle -- is released when the monadic computation is completed. Even, or -- especially, when an exception is thrown. withDeviceHandle ∷ Device → (DeviceHandle → IO α) → IO α@@ -360,9 +364,9 @@ @   example &#x2237; 'InterfaceHandle' &#x2192; IO ()   example ifHnd = do-    (packets1, rest1) &#x2190; runChunkedReaderT ('readData' ifHnd 400) 'BS.empty'+    (packets1, rest1) &#x2190; runChunkedReaderT ('readData' ifHnd (return 'False') 400) 'BS.empty'     print $ 'BS.concat' packets1-    (packets2, rest2) &#x2190; runChunkedReaderT ('readData' ifHnd 200) rest1+    (packets2, rest2) &#x2190; runChunkedReaderT ('readData' ifHnd (return 'False') 200) rest1     print $ 'BS.concat' packets2 @ @@ -372,9 +376,9 @@ @   example &#x2237; 'InterfaceHandle' &#x2192; IO ()   example ifHnd =-    let reader = do packets1 &#x2190; 'readData' ifHnd 400+    let reader = do packets1 &#x2190; 'readData' ifHnd (return 'False') 400                     liftIO $ print $ 'BS.concat' packets1-                    packets2 &#x2190; 'readData' ifHnd 200+                    packets2 &#x2190; 'readData' ifHnd (return 'False') 200                     liftIO $ print $ 'BS.concat' packets1     in runChunkedReaderT reader 'BS.empty' @@@ -385,23 +389,31 @@  {-| Reads data from the given FTDI interface by performing bulk reads. -This function produces an action in the ChunkedReaderT monad that, when-executed, will read exactly the requested number of bytes. Executing the-readData action will block until all data is read. The result value is a list-of chunks, represented as ByteStrings. This representation was choosen for-efficiency reasons.+This function produces an action in the @ChunkedReaderT@ monad that+will read exactly the requested number of bytes unless it is+explicitly asked to stop early. Executing the @readData@ action will+block until either: -Data is read in packets. The function may choose to request more than needed in-order to get the highest possible bandwidth. The excess of bytes is kept as the-state of the ChunkedReaderT monad. A subsequent invocation of readData will-first return bytes from the stored state before requesting more from the device-itself. A consequence of this behaviour is that even when you request 100 bytes-the function will actually request 512 bytes (depending on the packet size) and-/block/ until all 512 bytes are read! There is no workaround since requesting+ * All data are read++ * The given checkStop action returns 'True'++The result value is a list of chunks, represented as+@ByteString@s. This representation was choosen for efficiency reasons.++Data are read in packets. The function may choose to request more than+needed in order to get the highest possible bandwidth. The excess of+bytes is kept as the state of the @ChunkedReaderT@ monad. A subsequent+invocation of @readData@ will first return bytes from the stored state+before requesting more from the device itself. A consequence of this+behaviour is that even when you request 100 bytes the function will+actually request 512 bytes (depending on the packet size) and /block/+until all 512 bytes are read! There is no workaround since requesting less bytes than the packet size is an error. -USB timeouts will not interrupt readData. In case of a timeout readData will-simply resume reading data. A small USB timeout can degrade performance.+USB timeouts will not interrupt @readData@. In case of a timeout+@readData@ will simply resume reading data. A small USB timeout can+degrade performance.  The FTDI latency timer can cause poor performance. If the FTDI chip can't fill a packet before the latency timer fires it is forced to send an incomplete@@ -420,13 +432,16 @@  @   -- Read 100 data bytes from ifHnd-  (packets, rest) &#x2190; 'runChunkedReaderT' ('readData' ifHnd 100) 'BS.empty'+  (packets, rest) &#x2190; 'runChunkedReaderT' ('readData' ifHnd (return 'False') 100) 'BS.empty' @  -}--- TODO: timeout-readData ∷ ∀ m. MonadIO m ⇒ InterfaceHandle → Int → ChunkedReaderT m [ByteString]-readData ifHnd numBytes = ChunkedReaderT $+readData ∷ ∀ m. MonadIO m+         ⇒ InterfaceHandle+         → m Bool -- ^ Check stop action+         → Int -- ^ Number of bytes to read+         → ChunkedReaderT m [ByteString]+readData ifHnd checkStop numBytes = ChunkedReaderT $     do prevRest ← get        let readNumBytes = numBytes - BS.length prevRest        if readNumBytes > 0@@ -462,12 +477,15 @@         --   receivedBytes < packetSize         if receivedDataBytes < readNumBytes           then let xs = splitPackets bytes-               in liftM (xs ⊕) (readLoop $ readNumBytes - receivedDataBytes)+               in lift checkStop >>= \stop →+                  if stop+                  then put BS.empty >> return xs+                  else liftM (xs ⊕)+                             (readLoop $ readNumBytes - receivedDataBytes)           else -- We might have received too much data, since we can only                -- request multiples of 'packetSize' bytes. Split the byte                -- string at such an index that the first part contains-               -- readNumBytes of data bytes. The rest is kept for future-               -- usage.+               -- readNumBytes of data. The rest is kept for future usage.                let (bs, newRest) = BS.splitAt (splitIndex readNumBytes) bytes                in put newRest >> return (splitPackets bs) @@ -489,7 +507,7 @@  -- |Perform a bulk read. ----- Returns the data that was read (in the form of a 'ByteString') and a flag+-- Returns the bytes that where read (in the form of a 'ByteString') and a flag -- which indicates whether a timeout occured during the request. readBulk ∷ InterfaceHandle          → Int -- ^Number of bytes to read
ftdi.cabal view
@@ -1,5 +1,5 @@ name:          ftdi-version:       0.1+version:       0.2 cabal-version: >=1.6 build-type:    Custom stability:     experimental@@ -39,11 +39,12 @@   exposed-modules: System.FTDI   other-modules: System.FTDI.Internal                , System.FTDI.Utils-  build-depends: base                 >= 4     && < 4.3-               , base-unicode-symbols >= 0.1.1 && < 0.2+  build-depends: base                 >= 3.0.3 && < 4.3+               , base-unicode-symbols >= 0.1.1 && < 0.3                , bytestring           >= 0.9.1 && < 0.10+               , monads-fd            >= 0.1   && < 0.2                , safe                 >= 0.2   && < 0.3-               , transformers         >= 0.1.4 && < 0.2+               , transformers         >= 0.2   && < 0.3                , usb                  >= 0.3   && < 0.4   ghc-options: -Wall