{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost        #-}
{-# LANGUAGE PatternGuards              #-}
{-# LANGUAGE ScopedTypeVariables        #-}

module System.FTDI.Internal where

import Control.Applicative
import Control.Exception hiding (handle)
import Control.Monad
import Control.Monad.Fix
import Control.Monad.IO.Class    ( MonadIO, liftIO )
import Control.Monad.Trans.Class ( MonadTrans, lift )
import Control.Monad.Trans.State ( StateT, get, put, runStateT )
import Data.Bits
import Data.ByteString ( ByteString )
import Data.ByteString qualified as BS
import Data.Data
import Data.Function
import Data.List
import Data.Vector qualified as V
import Data.Word
import GHC.Generics
import System.FTDI.Utils
import System.USB qualified as USB


-------------------------------------------------------------------------------
-- Exceptions
-------------------------------------------------------------------------------

data FTDIException = InterfaceNotFound deriving (Int -> FTDIException -> ShowS
[FTDIException] -> ShowS
FTDIException -> String
(Int -> FTDIException -> ShowS)
-> (FTDIException -> String)
-> ([FTDIException] -> ShowS)
-> Show FTDIException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FTDIException -> ShowS
showsPrec :: Int -> FTDIException -> ShowS
$cshow :: FTDIException -> String
show :: FTDIException -> String
$cshowList :: [FTDIException] -> ShowS
showList :: [FTDIException] -> ShowS
Show, Typeable FTDIException
Typeable FTDIException =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> FTDIException -> c FTDIException)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c FTDIException)
-> (FTDIException -> Constr)
-> (FTDIException -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c FTDIException))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c FTDIException))
-> ((forall b. Data b => b -> b) -> FTDIException -> FTDIException)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> FTDIException -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> FTDIException -> r)
-> (forall u. (forall d. Data d => d -> u) -> FTDIException -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> FTDIException -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> FTDIException -> m FTDIException)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> FTDIException -> m FTDIException)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> FTDIException -> m FTDIException)
-> Data FTDIException
FTDIException -> Constr
FTDIException -> DataType
(forall b. Data b => b -> b) -> FTDIException -> FTDIException
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> FTDIException -> u
forall u. (forall d. Data d => d -> u) -> FTDIException -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FTDIException -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FTDIException -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FTDIException
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FTDIException -> c FTDIException
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FTDIException)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c FTDIException)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FTDIException -> c FTDIException
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FTDIException -> c FTDIException
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FTDIException
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FTDIException
$ctoConstr :: FTDIException -> Constr
toConstr :: FTDIException -> Constr
$cdataTypeOf :: FTDIException -> DataType
dataTypeOf :: FTDIException -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FTDIException)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FTDIException)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c FTDIException)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c FTDIException)
$cgmapT :: (forall b. Data b => b -> b) -> FTDIException -> FTDIException
gmapT :: (forall b. Data b => b -> b) -> FTDIException -> FTDIException
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FTDIException -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FTDIException -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FTDIException -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FTDIException -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> FTDIException -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> FTDIException -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FTDIException -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FTDIException -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FTDIException -> m FTDIException
Data, Typeable)

instance Exception FTDIException


-------------------------------------------------------------------------------
-- Request codes and values
-------------------------------------------------------------------------------

type RequestCode  = Word8
type RequestValue = Word16

reqReset           :: RequestCode
reqSetModemCtrl    :: RequestCode
reqSetFlowCtrl     :: RequestCode
reqSetBaudRate     :: RequestCode
reqSetData         :: RequestCode
reqPollModemStatus :: RequestCode
reqSetEventChar    :: RequestCode
reqSetErrorChar    :: RequestCode
reqSetLatencyTimer :: RequestCode
reqGetLatencyTimer :: RequestCode
reqSetBitMode      :: RequestCode
reqReadPins        :: RequestCode
reqReadEEPROM      :: RequestCode
reqWriteEEPROM     :: RequestCode
reqEraseEEPROM     :: RequestCode

reqReset :: Word8
reqReset           = Word8
0x00
reqSetModemCtrl :: Word8
reqSetModemCtrl    = Word8
0x01
reqSetFlowCtrl :: Word8
reqSetFlowCtrl     = Word8
0x02
reqSetBaudRate :: Word8
reqSetBaudRate     = Word8
0x03
reqSetData :: Word8
reqSetData         = Word8
0x04
reqPollModemStatus :: Word8
reqPollModemStatus = Word8
0x05
reqSetEventChar :: Word8
reqSetEventChar    = Word8
0x06
reqSetErrorChar :: Word8
reqSetErrorChar    = Word8
0x07
reqSetLatencyTimer :: Word8
reqSetLatencyTimer = Word8
0x09
reqGetLatencyTimer :: Word8
reqGetLatencyTimer = Word8
0x0A
reqSetBitMode :: Word8
reqSetBitMode      = Word8
0x0B
reqReadPins :: Word8
reqReadPins        = Word8
0x0C
reqReadEEPROM :: Word8
reqReadEEPROM      = Word8
0x90
reqWriteEEPROM :: Word8
reqWriteEEPROM     = Word8
0x91
reqEraseEEPROM :: Word8
reqEraseEEPROM     = Word8
0x92

valResetSIO         :: RequestValue
valPurgeReadBuffer  :: RequestValue
valPurgeWriteBuffer :: RequestValue

valResetSIO :: Word16
valResetSIO         = Word16
0
valPurgeReadBuffer :: Word16
valPurgeReadBuffer  = Word16
1
valPurgeWriteBuffer :: Word16
valPurgeWriteBuffer = Word16
2

valSetDTRHigh :: RequestValue
valSetDTRLow  :: RequestValue
valSetRTSHigh :: RequestValue
valSetRTSLow  :: RequestValue

valSetDTRHigh :: Word16
valSetDTRHigh = Word16
0x0101
valSetDTRLow :: Word16
valSetDTRLow  = Word16
0x0100
valSetRTSHigh :: Word16
valSetRTSHigh = Word16
0x0202
valSetRTSLow :: Word16
valSetRTSLow  = Word16
0x0200


-------------------------------------------------------------------------------
-- Defaults
-------------------------------------------------------------------------------

-- |Default USB timeout. The timeout can be set per device handle with
-- the 'setTimeout' function.
defaultTimeout :: Int
defaultTimeout :: Int
defaultTimeout = Int
5000


-------------------------------------------------------------------------------
-- Devices
-------------------------------------------------------------------------------

-- |A representation of an FTDI device.
data Device = Device
    { Device -> Device
devUSB      :: USB.Device
    , Device -> ConfigDesc
devUSBConf  :: USB.ConfigDesc
    , Device -> ChipType
devChipType :: ChipType
    }

-- |The type of FTDI chip in a 'Device'. The capabilities of a device
-- depend on its chip type.
data ChipType = ChipType_AM
              | ChipType_BM
              | ChipType_2232C
              | ChipType_R
              | ChipType_2232H
              | ChipType_4232H
                deriving (Int -> ChipType
ChipType -> Int
ChipType -> [ChipType]
ChipType -> ChipType
ChipType -> ChipType -> [ChipType]
ChipType -> ChipType -> ChipType -> [ChipType]
(ChipType -> ChipType)
-> (ChipType -> ChipType)
-> (Int -> ChipType)
-> (ChipType -> Int)
-> (ChipType -> [ChipType])
-> (ChipType -> ChipType -> [ChipType])
-> (ChipType -> ChipType -> [ChipType])
-> (ChipType -> ChipType -> ChipType -> [ChipType])
-> Enum ChipType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: ChipType -> ChipType
succ :: ChipType -> ChipType
$cpred :: ChipType -> ChipType
pred :: ChipType -> ChipType
$ctoEnum :: Int -> ChipType
toEnum :: Int -> ChipType
$cfromEnum :: ChipType -> Int
fromEnum :: ChipType -> Int
$cenumFrom :: ChipType -> [ChipType]
enumFrom :: ChipType -> [ChipType]
$cenumFromThen :: ChipType -> ChipType -> [ChipType]
enumFromThen :: ChipType -> ChipType -> [ChipType]
$cenumFromTo :: ChipType -> ChipType -> [ChipType]
enumFromTo :: ChipType -> ChipType -> [ChipType]
$cenumFromThenTo :: ChipType -> ChipType -> ChipType -> [ChipType]
enumFromThenTo :: ChipType -> ChipType -> ChipType -> [ChipType]
Enum, ChipType -> ChipType -> Bool
(ChipType -> ChipType -> Bool)
-> (ChipType -> ChipType -> Bool) -> Eq ChipType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChipType -> ChipType -> Bool
== :: ChipType -> ChipType -> Bool
$c/= :: ChipType -> ChipType -> Bool
/= :: ChipType -> ChipType -> Bool
Eq, Eq ChipType
Eq ChipType =>
(ChipType -> ChipType -> Ordering)
-> (ChipType -> ChipType -> Bool)
-> (ChipType -> ChipType -> Bool)
-> (ChipType -> ChipType -> Bool)
-> (ChipType -> ChipType -> Bool)
-> (ChipType -> ChipType -> ChipType)
-> (ChipType -> ChipType -> ChipType)
-> Ord ChipType
ChipType -> ChipType -> Bool
ChipType -> ChipType -> Ordering
ChipType -> ChipType -> ChipType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ChipType -> ChipType -> Ordering
compare :: ChipType -> ChipType -> Ordering
$c< :: ChipType -> ChipType -> Bool
< :: ChipType -> ChipType -> Bool
$c<= :: ChipType -> ChipType -> Bool
<= :: ChipType -> ChipType -> Bool
$c> :: ChipType -> ChipType -> Bool
> :: ChipType -> ChipType -> Bool
$c>= :: ChipType -> ChipType -> Bool
>= :: ChipType -> ChipType -> Bool
$cmax :: ChipType -> ChipType -> ChipType
max :: ChipType -> ChipType -> ChipType
$cmin :: ChipType -> ChipType -> ChipType
min :: ChipType -> ChipType -> ChipType
Ord, Int -> ChipType -> ShowS
[ChipType] -> ShowS
ChipType -> String
(Int -> ChipType -> ShowS)
-> (ChipType -> String) -> ([ChipType] -> ShowS) -> Show ChipType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChipType -> ShowS
showsPrec :: Int -> ChipType -> ShowS
$cshow :: ChipType -> String
show :: ChipType -> String
$cshowList :: [ChipType] -> ShowS
showList :: [ChipType] -> ShowS
Show, Typeable ChipType
Typeable ChipType =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ChipType -> c ChipType)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ChipType)
-> (ChipType -> Constr)
-> (ChipType -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ChipType))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ChipType))
-> ((forall b. Data b => b -> b) -> ChipType -> ChipType)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ChipType -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ChipType -> r)
-> (forall u. (forall d. Data d => d -> u) -> ChipType -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> ChipType -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ChipType -> m ChipType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ChipType -> m ChipType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ChipType -> m ChipType)
-> Data ChipType
ChipType -> Constr
ChipType -> DataType
(forall b. Data b => b -> b) -> ChipType -> ChipType
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ChipType -> u
forall u. (forall d. Data d => d -> u) -> ChipType -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ChipType -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ChipType -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ChipType
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ChipType -> c ChipType
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ChipType)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ChipType)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ChipType -> c ChipType
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ChipType -> c ChipType
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ChipType
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ChipType
$ctoConstr :: ChipType -> Constr
toConstr :: ChipType -> Constr
$cdataTypeOf :: ChipType -> DataType
dataTypeOf :: ChipType -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ChipType)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ChipType)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ChipType)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ChipType)
$cgmapT :: (forall b. Data b => b -> b) -> ChipType -> ChipType
gmapT :: (forall b. Data b => b -> b) -> ChipType -> ChipType
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ChipType -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ChipType -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ChipType -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ChipType -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ChipType -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ChipType -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ChipType -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ChipType -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ChipType -> m ChipType
Data, Typeable, (forall x. ChipType -> Rep ChipType x)
-> (forall x. Rep ChipType x -> ChipType) -> Generic ChipType
forall x. Rep ChipType x -> ChipType
forall x. ChipType -> Rep ChipType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChipType -> Rep ChipType x
from :: forall x. ChipType -> Rep ChipType x
$cto :: forall x. Rep ChipType x -> ChipType
to :: forall x. Rep ChipType x -> ChipType
Generic)

getChipType :: Device -> ChipType
getChipType :: Device -> ChipType
getChipType = Device -> ChipType
devChipType

setChipType :: Device -> ChipType -> Device
setChipType :: Device -> ChipType -> Device
setChipType Device
dev ChipType
ct = Device
dev {devChipType = ct}

-- |Promote a USB device to an FTDI device. You are responsible for
-- supplying the correct USB device and specifying the correct chip
-- type. There is no failsafe way to automatically determine whether a
-- random USB device is an actual FTDI device.
fromUSBDevice :: USB.Device -- ^ USB device
              -> ChipType
              -> IO Device     -- ^ FTDI device
fromUSBDevice :: Device -> ChipType -> IO Device
fromUSBDevice Device
dev ChipType
chip = do
  ConfigDesc
config <- Device -> Word8 -> IO ConfigDesc
USB.getConfigDesc Device
dev Word8
0
  Device -> IO Device
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Device { devUSB :: Device
devUSB      = Device
dev
                , devUSBConf :: ConfigDesc
devUSBConf  = ConfigDesc
config
                , devChipType :: ChipType
devChipType = ChipType
chip
                }

-- |Tries to guess the type of the FTDI chip by looking at the USB
-- device release number of a device's descriptor. Each FTDI chip uses
-- a specific release number to indicate its type.
guessChipType :: USB.DeviceDesc -> Maybe ChipType
guessChipType :: DeviceDesc -> Maybe ChipType
guessChipType DeviceDesc
desc = case DeviceDesc -> ReleaseNumber
USB.deviceReleaseNumber DeviceDesc
desc of
                       -- Workaround for bug in BM type chips
                       (Int
0,Int
2,Int
0,Int
0) | DeviceDesc -> Maybe Word8
USB.deviceSerialNumberStrIx DeviceDesc
desc Maybe Word8 -> Maybe Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
0
                                             -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_BM
                                 | Bool
otherwise -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_AM
                       (Int
0,Int
4,Int
0,Int
0) -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_BM
                       (Int
0,Int
5,Int
0,Int
0) -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_2232C
                       (Int
0,Int
6,Int
0,Int
0) -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_R
                       (Int
0,Int
7,Int
0,Int
0) -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_2232H
                       (Int
0,Int
8,Int
0,Int
0) -> ChipType -> Maybe ChipType
forall a. a -> Maybe a
Just ChipType
ChipType_4232H
                       ReleaseNumber
_         -> Maybe ChipType
forall a. Maybe a
Nothing

-------------------------------------------------------------------------------
-- Interfaces
-------------------------------------------------------------------------------

-- |A device interface. You can imagine an interface as a port or a
-- communication channel. Some devices support communication over
-- multiple interfaces at the same time.
data Interface = Interface_A
               | Interface_B
               | Interface_C
               | Interface_D
                 deriving (Int -> Interface
Interface -> Int
Interface -> [Interface]
Interface -> Interface
Interface -> Interface -> [Interface]
Interface -> Interface -> Interface -> [Interface]
(Interface -> Interface)
-> (Interface -> Interface)
-> (Int -> Interface)
-> (Interface -> Int)
-> (Interface -> [Interface])
-> (Interface -> Interface -> [Interface])
-> (Interface -> Interface -> [Interface])
-> (Interface -> Interface -> Interface -> [Interface])
-> Enum Interface
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Interface -> Interface
succ :: Interface -> Interface
$cpred :: Interface -> Interface
pred :: Interface -> Interface
$ctoEnum :: Int -> Interface
toEnum :: Int -> Interface
$cfromEnum :: Interface -> Int
fromEnum :: Interface -> Int
$cenumFrom :: Interface -> [Interface]
enumFrom :: Interface -> [Interface]
$cenumFromThen :: Interface -> Interface -> [Interface]
enumFromThen :: Interface -> Interface -> [Interface]
$cenumFromTo :: Interface -> Interface -> [Interface]
enumFromTo :: Interface -> Interface -> [Interface]
$cenumFromThenTo :: Interface -> Interface -> Interface -> [Interface]
enumFromThenTo :: Interface -> Interface -> Interface -> [Interface]
Enum, Interface -> Interface -> Bool
(Interface -> Interface -> Bool)
-> (Interface -> Interface -> Bool) -> Eq Interface
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Interface -> Interface -> Bool
== :: Interface -> Interface -> Bool
$c/= :: Interface -> Interface -> Bool
/= :: Interface -> Interface -> Bool
Eq, Eq Interface
Eq Interface =>
(Interface -> Interface -> Ordering)
-> (Interface -> Interface -> Bool)
-> (Interface -> Interface -> Bool)
-> (Interface -> Interface -> Bool)
-> (Interface -> Interface -> Bool)
-> (Interface -> Interface -> Interface)
-> (Interface -> Interface -> Interface)
-> Ord Interface
Interface -> Interface -> Bool
Interface -> Interface -> Ordering
Interface -> Interface -> Interface
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Interface -> Interface -> Ordering
compare :: Interface -> Interface -> Ordering
$c< :: Interface -> Interface -> Bool
< :: Interface -> Interface -> Bool
$c<= :: Interface -> Interface -> Bool
<= :: Interface -> Interface -> Bool
$c> :: Interface -> Interface -> Bool
> :: Interface -> Interface -> Bool
$c>= :: Interface -> Interface -> Bool
>= :: Interface -> Interface -> Bool
$cmax :: Interface -> Interface -> Interface
max :: Interface -> Interface -> Interface
$cmin :: Interface -> Interface -> Interface
min :: Interface -> Interface -> Interface
Ord, Int -> Interface -> ShowS
[Interface] -> ShowS
Interface -> String
(Int -> Interface -> ShowS)
-> (Interface -> String)
-> ([Interface] -> ShowS)
-> Show Interface
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Interface -> ShowS
showsPrec :: Int -> Interface -> ShowS
$cshow :: Interface -> String
show :: Interface -> String
$cshowList :: [Interface] -> ShowS
showList :: [Interface] -> ShowS
Show, Typeable Interface
Typeable Interface =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Interface -> c Interface)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Interface)
-> (Interface -> Constr)
-> (Interface -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Interface))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Interface))
-> ((forall b. Data b => b -> b) -> Interface -> Interface)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Interface -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Interface -> r)
-> (forall u. (forall d. Data d => d -> u) -> Interface -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Interface -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Interface -> m Interface)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Interface -> m Interface)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Interface -> m Interface)
-> Data Interface
Interface -> Constr
Interface -> DataType
(forall b. Data b => b -> b) -> Interface -> Interface
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Interface -> u
forall u. (forall d. Data d => d -> u) -> Interface -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interface -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interface -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Interface
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interface -> c Interface
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Interface)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Interface)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interface -> c Interface
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interface -> c Interface
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Interface
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Interface
$ctoConstr :: Interface -> Constr
toConstr :: Interface -> Constr
$cdataTypeOf :: Interface -> DataType
dataTypeOf :: Interface -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Interface)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Interface)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Interface)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Interface)
$cgmapT :: (forall b. Data b => b -> b) -> Interface -> Interface
gmapT :: (forall b. Data b => b -> b) -> Interface -> Interface
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interface -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interface -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interface -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interface -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Interface -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Interface -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Interface -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Interface -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interface -> m Interface
Data, Typeable)

interfaceIndex :: Interface -> Word16
interfaceIndex :: Interface -> Word16
interfaceIndex = Word16 -> Word16
forall a. Enum a => a -> a
succ (Word16 -> Word16) -> (Interface -> Word16) -> Interface -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interface -> Word16
forall e n. (Enum e, Num n) => e -> n
genFromEnum

interfaceToUSB :: Interface -> USB.InterfaceNumber
interfaceToUSB :: Interface -> Word8
interfaceToUSB = Interface -> Word8
forall e n. (Enum e, Num n) => e -> n
genFromEnum

interfaceEndPointIn :: Interface -> USB.EndpointAddress
interfaceEndPointIn :: Interface -> EndpointAddress
interfaceEndPointIn Interface
i =
    USB.EndpointAddress { endpointNumber :: Int
USB.endpointNumber    = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Interface -> Int
forall e n. (Enum e, Num n) => e -> n
genFromEnum Interface
i
                        , transferDirection :: TransferDirection
USB.transferDirection = TransferDirection
USB.In
                        }

interfaceEndPointOut :: Interface -> USB.EndpointAddress
interfaceEndPointOut :: Interface -> EndpointAddress
interfaceEndPointOut Interface
i =
    USB.EndpointAddress { endpointNumber :: Int
USB.endpointNumber    = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Interface -> Int
forall e n. (Enum e, Num n) => e -> n
genFromEnum Interface
i
                        , transferDirection :: TransferDirection
USB.transferDirection = TransferDirection
USB.Out
                        }

-------------------------------------------------------------------------------
-- Device Handles
-------------------------------------------------------------------------------

-- |You need a handle in order to communicate with a 'Device'.
data DeviceHandle = DeviceHandle
    { DeviceHandle -> DeviceHandle
devHndUSB     :: USB.DeviceHandle
    , DeviceHandle -> Device
devHndDev     :: Device
    , DeviceHandle -> Int
devHndTimeout :: Int
    }

-- |Perform a USB device reset.
resetUSB :: DeviceHandle -> IO ()
resetUSB :: DeviceHandle -> IO ()
resetUSB = DeviceHandle -> IO ()
USB.resetDevice (DeviceHandle -> IO ())
-> (DeviceHandle -> DeviceHandle) -> DeviceHandle -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DeviceHandle -> DeviceHandle
devHndUSB

-- |Returns the USB timeout associated with a handle.
getTimeout :: DeviceHandle -> Int
getTimeout :: DeviceHandle -> Int
getTimeout = DeviceHandle -> Int
devHndTimeout

-- |Modifies the USB timeout associated with a handle.
setTimeout :: DeviceHandle -> Int -> DeviceHandle
setTimeout :: DeviceHandle -> Int -> DeviceHandle
setTimeout DeviceHandle
devHnd Int
timeout = DeviceHandle
devHnd {devHndTimeout = timeout}

-- |Open a device handle to enable communication. Only use this if you
-- can't use 'withDeviceHandle' for some reason.
openDevice :: Device -> IO DeviceHandle
openDevice :: Device -> IO DeviceHandle
openDevice Device
dev = do
  DeviceHandle
handle <- Device -> IO DeviceHandle
USB.openDevice (Device -> IO DeviceHandle) -> Device -> IO DeviceHandle
forall a b. (a -> b) -> a -> b
$ Device -> Device
devUSB Device
dev
--  USB.setConfig handle $ Just $ USB.configValue $ devUSBConf dev
  DeviceHandle -> IO DeviceHandle
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return DeviceHandle { devHndUSB :: DeviceHandle
devHndUSB     = DeviceHandle
handle
                      , devHndDev :: Device
devHndDev     = Device
dev
                      , devHndTimeout :: Int
devHndTimeout = Int
defaultTimeout
                      }

-- |Release a device handle.
closeDevice :: DeviceHandle -> IO ()
closeDevice :: DeviceHandle -> IO ()
closeDevice = DeviceHandle -> IO ()
USB.closeDevice (DeviceHandle -> IO ())
-> (DeviceHandle -> DeviceHandle) -> DeviceHandle -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DeviceHandle -> DeviceHandle
devHndUSB

-- |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 a) -> IO a
withDeviceHandle :: forall a. Device -> (DeviceHandle -> IO a) -> IO a
withDeviceHandle Device
dev = IO DeviceHandle
-> (DeviceHandle -> IO ()) -> (DeviceHandle -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Device -> IO DeviceHandle
openDevice Device
dev) DeviceHandle -> IO ()
closeDevice

-------------------------------------------------------------------------------
-- Interface Handles
-------------------------------------------------------------------------------

data InterfaceHandle = InterfaceHandle
    { InterfaceHandle -> DeviceHandle
ifHndDevHnd    :: DeviceHandle
    , InterfaceHandle -> Interface
ifHndInterface :: Interface
    , InterfaceHandle -> EndpointDesc
ifHndInEPDesc  :: USB.EndpointDesc
    , InterfaceHandle -> EndpointDesc
ifHndOutEPDesc :: USB.EndpointDesc
    }

getDeviceHandle :: InterfaceHandle -> DeviceHandle
getDeviceHandle :: InterfaceHandle -> DeviceHandle
getDeviceHandle = InterfaceHandle -> DeviceHandle
ifHndDevHnd

getInterface :: InterfaceHandle -> Interface
getInterface :: InterfaceHandle -> Interface
getInterface = InterfaceHandle -> Interface
ifHndInterface

openInterface :: DeviceHandle -> Interface -> IO InterfaceHandle
openInterface :: DeviceHandle -> Interface -> IO InterfaceHandle
openInterface DeviceHandle
devHnd Interface
i =
    let conf :: ConfigDesc
conf    = Device -> ConfigDesc
devUSBConf (Device -> ConfigDesc) -> Device -> ConfigDesc
forall a b. (a -> b) -> a -> b
$ DeviceHandle -> Device
devHndDev DeviceHandle
devHnd
        ifIx :: Int
ifIx    = Interface -> Int
forall a. Enum a => a -> Int
fromEnum Interface
i
        mIfDesc :: Maybe InterfaceDesc
mIfDesc = (ConfigDesc -> Vector Interface
USB.configInterfaces ConfigDesc
conf Vector Interface -> Int -> Maybe Interface
forall a. Vector a -> Int -> Maybe a
V.!? Int
ifIx) Maybe Interface
-> (Interface -> Maybe InterfaceDesc) -> Maybe InterfaceDesc
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Interface -> Maybe InterfaceDesc
forall {a}. Vector a -> Maybe a
headMay
        mInOutEps :: Maybe (Vector EndpointDesc, Vector EndpointDesc)
mInOutEps = (EndpointDesc -> Bool)
-> Vector EndpointDesc
-> (Vector EndpointDesc, Vector EndpointDesc)
forall a. (a -> Bool) -> Vector a -> (Vector a, Vector a)
V.partition ((TransferDirection
USB.In TransferDirection -> TransferDirection -> Bool
forall a. Eq a => a -> a -> Bool
==) (TransferDirection -> Bool)
-> (EndpointDesc -> TransferDirection) -> EndpointDesc -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EndpointAddress -> TransferDirection
USB.transferDirection (EndpointAddress -> TransferDirection)
-> (EndpointDesc -> EndpointAddress)
-> EndpointDesc
-> TransferDirection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EndpointDesc -> EndpointAddress
USB.endpointAddress)
                    (Vector EndpointDesc -> (Vector EndpointDesc, Vector EndpointDesc))
-> (InterfaceDesc -> Vector EndpointDesc)
-> InterfaceDesc
-> (Vector EndpointDesc, Vector EndpointDesc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InterfaceDesc -> Vector EndpointDesc
USB.interfaceEndpoints
                    (InterfaceDesc -> (Vector EndpointDesc, Vector EndpointDesc))
-> Maybe InterfaceDesc
-> Maybe (Vector EndpointDesc, Vector EndpointDesc)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe InterfaceDesc
mIfDesc
        mInEp :: Maybe EndpointDesc
mInEp   = Vector EndpointDesc -> Maybe EndpointDesc
forall {a}. Vector a -> Maybe a
headMay (Vector EndpointDesc -> Maybe EndpointDesc)
-> ((Vector EndpointDesc, Vector EndpointDesc)
    -> Vector EndpointDesc)
-> (Vector EndpointDesc, Vector EndpointDesc)
-> Maybe EndpointDesc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector EndpointDesc, Vector EndpointDesc) -> Vector EndpointDesc
forall a b. (a, b) -> a
fst ((Vector EndpointDesc, Vector EndpointDesc) -> Maybe EndpointDesc)
-> Maybe (Vector EndpointDesc, Vector EndpointDesc)
-> Maybe EndpointDesc
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe (Vector EndpointDesc, Vector EndpointDesc)
mInOutEps
        mOutEp :: Maybe EndpointDesc
mOutEp  = Vector EndpointDesc -> Maybe EndpointDesc
forall {a}. Vector a -> Maybe a
headMay (Vector EndpointDesc -> Maybe EndpointDesc)
-> ((Vector EndpointDesc, Vector EndpointDesc)
    -> Vector EndpointDesc)
-> (Vector EndpointDesc, Vector EndpointDesc)
-> Maybe EndpointDesc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector EndpointDesc, Vector EndpointDesc) -> Vector EndpointDesc
forall a b. (a, b) -> b
snd ((Vector EndpointDesc, Vector EndpointDesc) -> Maybe EndpointDesc)
-> Maybe (Vector EndpointDesc, Vector EndpointDesc)
-> Maybe EndpointDesc
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe (Vector EndpointDesc, Vector EndpointDesc)
mInOutEps
        headMay :: Vector a -> Maybe a
headMay = (Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
V.!? Int
0)
    in IO InterfaceHandle
-> (InterfaceHandle -> IO InterfaceHandle)
-> Maybe InterfaceHandle
-> IO InterfaceHandle
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (FTDIException -> IO InterfaceHandle
forall e a. Exception e => e -> IO a
throwIO FTDIException
InterfaceNotFound)
             ( \InterfaceHandle
ifHnd -> do DeviceHandle -> Word8 -> IO ()
USB.claimInterface (DeviceHandle -> DeviceHandle
devHndUSB DeviceHandle
devHnd) (Interface -> Word8
interfaceToUSB Interface
i)
                            InterfaceHandle -> IO InterfaceHandle
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return InterfaceHandle
ifHnd
             )
             (Maybe InterfaceHandle -> IO InterfaceHandle)
-> Maybe InterfaceHandle -> IO InterfaceHandle
forall a b. (a -> b) -> a -> b
$ do EndpointDesc
inEp  <- Maybe EndpointDesc
mInEp
                  EndpointDesc
outEp <- Maybe EndpointDesc
mOutEp
                  InterfaceHandle -> Maybe InterfaceHandle
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return InterfaceHandle
                     { ifHndDevHnd :: DeviceHandle
ifHndDevHnd    = DeviceHandle
devHnd
                     , ifHndInterface :: Interface
ifHndInterface = Interface
i
                     , ifHndInEPDesc :: EndpointDesc
ifHndInEPDesc  = EndpointDesc
inEp
                     , ifHndOutEPDesc :: EndpointDesc
ifHndOutEPDesc = EndpointDesc
outEp
                     }

closeInterface :: InterfaceHandle -> IO ()
closeInterface :: InterfaceHandle -> IO ()
closeInterface InterfaceHandle
ifHnd = DeviceHandle -> Word8 -> IO ()
USB.releaseInterface (DeviceHandle -> DeviceHandle
devHndUSB (DeviceHandle -> DeviceHandle) -> DeviceHandle -> DeviceHandle
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd)
                                            (Interface -> Word8
interfaceToUSB (Interface -> Word8) -> Interface -> Word8
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> Interface
ifHndInterface InterfaceHandle
ifHnd)

withInterfaceHandle :: DeviceHandle -> Interface -> (InterfaceHandle -> IO a) -> IO a
withInterfaceHandle :: forall a.
DeviceHandle -> Interface -> (InterfaceHandle -> IO a) -> IO a
withInterfaceHandle DeviceHandle
h Interface
i = IO InterfaceHandle
-> (InterfaceHandle -> IO ()) -> (InterfaceHandle -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (DeviceHandle -> Interface -> IO InterfaceHandle
openInterface DeviceHandle
h Interface
i) InterfaceHandle -> IO ()
closeInterface

-------------------------------------------------------------------------------
-- Kernel drivers
-------------------------------------------------------------------------------
withDetachedKernelDriver :: DeviceHandle -> Interface -> IO a -> IO a
withDetachedKernelDriver :: forall a. DeviceHandle -> Interface -> IO a -> IO a
withDetachedKernelDriver DeviceHandle
devHndl Interface
i =
  DeviceHandle -> Word8 -> IO a -> IO a
forall a. DeviceHandle -> Word8 -> IO a -> IO a
USB.withDetachedKernelDriver (DeviceHandle -> DeviceHandle
devHndUSB DeviceHandle
devHndl) (Interface -> Word8
interfaceToUSB Interface
i)

-------------------------------------------------------------------------------
-- Data transfer
-------------------------------------------------------------------------------

newtype ChunkedReaderT m a = ChunkedReaderT {forall (m :: * -> *) a. ChunkedReaderT m a -> StateT ByteString m a
unCR :: StateT ByteString m a}
    deriving ( (forall a b. (a -> b) -> ChunkedReaderT m a -> ChunkedReaderT m b)
-> (forall a b. a -> ChunkedReaderT m b -> ChunkedReaderT m a)
-> Functor (ChunkedReaderT m)
forall a b. a -> ChunkedReaderT m b -> ChunkedReaderT m a
forall a b. (a -> b) -> ChunkedReaderT m a -> ChunkedReaderT m b
forall (m :: * -> *) a b.
Functor m =>
a -> ChunkedReaderT m b -> ChunkedReaderT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ChunkedReaderT m a -> ChunkedReaderT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ChunkedReaderT m a -> ChunkedReaderT m b
fmap :: forall a b. (a -> b) -> ChunkedReaderT m a -> ChunkedReaderT m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> ChunkedReaderT m b -> ChunkedReaderT m a
<$ :: forall a b. a -> ChunkedReaderT m b -> ChunkedReaderT m a
Functor
             , Functor (ChunkedReaderT m)
Functor (ChunkedReaderT m) =>
(forall a. a -> ChunkedReaderT m a)
-> (forall a b.
    ChunkedReaderT m (a -> b)
    -> ChunkedReaderT m a -> ChunkedReaderT m b)
-> (forall a b c.
    (a -> b -> c)
    -> ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m c)
-> (forall a b.
    ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b)
-> (forall a b.
    ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m a)
-> Applicative (ChunkedReaderT m)
forall a. a -> ChunkedReaderT m a
forall a b.
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m a
forall a b.
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
forall a b.
ChunkedReaderT m (a -> b)
-> ChunkedReaderT m a -> ChunkedReaderT m b
forall a b c.
(a -> b -> c)
-> ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m c
forall (m :: * -> *). Monad m => Functor (ChunkedReaderT m)
forall (m :: * -> *) a. Monad m => a -> ChunkedReaderT m a
forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m a
forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m (a -> b)
-> ChunkedReaderT m a -> ChunkedReaderT m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c)
-> ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall (m :: * -> *) a. Monad m => a -> ChunkedReaderT m a
pure :: forall a. a -> ChunkedReaderT m a
$c<*> :: forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m (a -> b)
-> ChunkedReaderT m a -> ChunkedReaderT m b
<*> :: forall a b.
ChunkedReaderT m (a -> b)
-> ChunkedReaderT m a -> ChunkedReaderT m b
$cliftA2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c)
-> ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m c
liftA2 :: forall a b c.
(a -> b -> c)
-> ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m c
$c*> :: forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
*> :: forall a b.
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
$c<* :: forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m a
<* :: forall a b.
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m a
Applicative
             , Applicative (ChunkedReaderT m)
Applicative (ChunkedReaderT m) =>
(forall a. ChunkedReaderT m a)
-> (forall a.
    ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a)
-> (forall a. ChunkedReaderT m a -> ChunkedReaderT m [a])
-> (forall a. ChunkedReaderT m a -> ChunkedReaderT m [a])
-> Alternative (ChunkedReaderT m)
forall a. ChunkedReaderT m a
forall a. ChunkedReaderT m a -> ChunkedReaderT m [a]
forall a.
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
forall (f :: * -> *).
Applicative f =>
(forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall (m :: * -> *). MonadPlus m => Applicative (ChunkedReaderT m)
forall (m :: * -> *) a. MonadPlus m => ChunkedReaderT m a
forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m [a]
forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
$cempty :: forall (m :: * -> *) a. MonadPlus m => ChunkedReaderT m a
empty :: forall a. ChunkedReaderT m a
$c<|> :: forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
<|> :: forall a.
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
$csome :: forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m [a]
some :: forall a. ChunkedReaderT m a -> ChunkedReaderT m [a]
$cmany :: forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m [a]
many :: forall a. ChunkedReaderT m a -> ChunkedReaderT m [a]
Alternative
             , Applicative (ChunkedReaderT m)
Applicative (ChunkedReaderT m) =>
(forall a b.
 ChunkedReaderT m a
 -> (a -> ChunkedReaderT m b) -> ChunkedReaderT m b)
-> (forall a b.
    ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b)
-> (forall a. a -> ChunkedReaderT m a)
-> Monad (ChunkedReaderT m)
forall a. a -> ChunkedReaderT m a
forall a b.
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
forall a b.
ChunkedReaderT m a
-> (a -> ChunkedReaderT m b) -> ChunkedReaderT m b
forall (m :: * -> *). Monad m => Applicative (ChunkedReaderT m)
forall (m :: * -> *) a. Monad m => a -> ChunkedReaderT m a
forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a
-> (a -> ChunkedReaderT m b) -> ChunkedReaderT m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a
-> (a -> ChunkedReaderT m b) -> ChunkedReaderT m b
>>= :: forall a b.
ChunkedReaderT m a
-> (a -> ChunkedReaderT m b) -> ChunkedReaderT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
>> :: forall a b.
ChunkedReaderT m a -> ChunkedReaderT m b -> ChunkedReaderT m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> ChunkedReaderT m a
return :: forall a. a -> ChunkedReaderT m a
Monad
             , Monad (ChunkedReaderT m)
Alternative (ChunkedReaderT m)
(Alternative (ChunkedReaderT m), Monad (ChunkedReaderT m)) =>
(forall a. ChunkedReaderT m a)
-> (forall a.
    ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a)
-> MonadPlus (ChunkedReaderT m)
forall a. ChunkedReaderT m a
forall a.
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
forall (m :: * -> *). MonadPlus m => Monad (ChunkedReaderT m)
forall (m :: * -> *). MonadPlus m => Alternative (ChunkedReaderT m)
forall (m :: * -> *) a. MonadPlus m => ChunkedReaderT m a
forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
forall (m :: * -> *).
(Alternative m, Monad m) =>
(forall a. m a) -> (forall a. m a -> m a -> m a) -> MonadPlus m
$cmzero :: forall (m :: * -> *) a. MonadPlus m => ChunkedReaderT m a
mzero :: forall a. ChunkedReaderT m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
mplus :: forall a.
ChunkedReaderT m a -> ChunkedReaderT m a -> ChunkedReaderT m a
MonadPlus
             , (forall (m :: * -> *). Monad m => Monad (ChunkedReaderT m)) =>
(forall (m :: * -> *) a. Monad m => m a -> ChunkedReaderT m a)
-> MonadTrans ChunkedReaderT
forall (m :: * -> *). Monad m => Monad (ChunkedReaderT m)
forall (m :: * -> *) a. Monad m => m a -> ChunkedReaderT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *). Monad m => Monad (t m)) =>
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
$clift :: forall (m :: * -> *) a. Monad m => m a -> ChunkedReaderT m a
lift :: forall (m :: * -> *) a. Monad m => m a -> ChunkedReaderT m a
MonadTrans
             , Monad (ChunkedReaderT m)
Monad (ChunkedReaderT m) =>
(forall a. IO a -> ChunkedReaderT m a)
-> MonadIO (ChunkedReaderT m)
forall a. IO a -> ChunkedReaderT m a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (ChunkedReaderT m)
forall (m :: * -> *) a. MonadIO m => IO a -> ChunkedReaderT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> ChunkedReaderT m a
liftIO :: forall a. IO a -> ChunkedReaderT m a
MonadIO
             , Monad (ChunkedReaderT m)
Monad (ChunkedReaderT m) =>
(forall a. (a -> ChunkedReaderT m a) -> ChunkedReaderT m a)
-> MonadFix (ChunkedReaderT m)
forall a. (a -> ChunkedReaderT m a) -> ChunkedReaderT m a
forall (m :: * -> *).
Monad m =>
(forall a. (a -> m a) -> m a) -> MonadFix m
forall (m :: * -> *). MonadFix m => Monad (ChunkedReaderT m)
forall (m :: * -> *) a.
MonadFix m =>
(a -> ChunkedReaderT m a) -> ChunkedReaderT m a
$cmfix :: forall (m :: * -> *) a.
MonadFix m =>
(a -> ChunkedReaderT m a) -> ChunkedReaderT m a
mfix :: forall a. (a -> ChunkedReaderT m a) -> ChunkedReaderT m a
MonadFix
             )

{-| Run the 'ChunkedReaderT' given an initial state.

The initial state represents excess bytes carried over from a previous
run. When invoking 'runChunkedReaderT' for the first time you can safely pass the
'BS.empty' bytestring as the initial state.

A contrived example showing how you can manually thread the excess bytes
through subsequent invocations of 'runChunkedReaderT':

@
  example :: 'InterfaceHandle' -> IO ()
  example ifHnd = do
    (packets1, rest1) <- runChunkedReaderT ('readData' ifHnd (return 'False') 400) 'BS.empty'
    print $ 'BS.concat' packets1
    (packets2, rest2) <- runChunkedReaderT ('readData' ifHnd (return 'False') 200) rest1
    print $ 'BS.concat' packets2
@

However, it is much easier to let 'ChunkedReaderT's monad instance handle the
plumbing:

@
  example :: 'InterfaceHandle' -> IO ()
  example ifHnd =
    let reader = do packets1 <- 'readData' ifHnd (return 'False') 400
                    'liftIO' $ print $ 'BS.concat' packets1
                    packets2 <- 'readData' ifHnd (return 'False') 200
                    'liftIO' $ print $ 'BS.concat' packets1
    in runChunkedReaderT reader 'BS.empty'
@

-}
runChunkedReaderT :: ChunkedReaderT m a -> ByteString -> m (a, ByteString)
runChunkedReaderT :: forall (m :: * -> *) a.
ChunkedReaderT m a -> ByteString -> m (a, ByteString)
runChunkedReaderT = StateT ByteString m a -> ByteString -> m (a, ByteString)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (StateT ByteString m a -> ByteString -> m (a, ByteString))
-> (ChunkedReaderT m a -> StateT ByteString m a)
-> ChunkedReaderT m a
-> ByteString
-> m (a, ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChunkedReaderT m a -> StateT ByteString m a
forall (m :: * -> *) a. ChunkedReaderT m a -> StateT ByteString m a
unCR

{-| Reads data from the given FTDI interface by performing bulk reads.

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:

 * 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.

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
packet. This will cause a stream of tiny packets instead of a few large
packets. Performance will suffer horribly, but the request will still be
completed.

If you need to make a lot of small requests then a small latency can actually
improve performance.

Modem status bytes are filtered from the result. Every packet sent by the FTDI
chip contains 2 modem status bytes. They are not part of the data and do not
count for the number of bytes read. They will not appear in the result.

Example:

@
  -- Read 100 data bytes from ifHnd
  (packets, rest) <- 'runChunkedReaderT' ('readData' ifHnd (return 'False') 100) 'BS.empty'
@

-}
readData :: forall m. MonadIO m
         => InterfaceHandle
         -> m Bool -- ^ Check stop action
         -> Int    -- ^ Number of bytes to read
         -> ChunkedReaderT m [ByteString]
readData :: forall (m :: * -> *).
MonadIO m =>
InterfaceHandle -> m Bool -> Int -> ChunkedReaderT m [ByteString]
readData InterfaceHandle
ifHnd m Bool
checkStop Int
numBytes = StateT ByteString m [ByteString] -> ChunkedReaderT m [ByteString]
forall (m :: * -> *) a. StateT ByteString m a -> ChunkedReaderT m a
ChunkedReaderT (StateT ByteString m [ByteString] -> ChunkedReaderT m [ByteString])
-> StateT ByteString m [ByteString]
-> ChunkedReaderT m [ByteString]
forall a b. (a -> b) -> a -> b
$
    do ByteString
prevRest <- StateT ByteString m ByteString
forall (m :: * -> *) s. Monad m => StateT s m s
get
       let readNumBytes :: Int
readNumBytes = Int
numBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
BS.length ByteString
prevRest
       if Int
readNumBytes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
         then do [ByteString]
chunks <- Int -> StateT ByteString m [ByteString]
readLoop Int
readNumBytes
                 [ByteString] -> StateT ByteString m [ByteString]
forall a. a -> StateT ByteString m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> StateT ByteString m [ByteString])
-> [ByteString] -> StateT ByteString m [ByteString]
forall a b. (a -> b) -> a -> b
$ if ByteString -> Bool
BS.null ByteString
prevRest
                          then [ByteString]
chunks
                          else ByteString
prevRest ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
chunks
         else let (ByteString
bs, ByteString
newRest) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt Int
numBytes ByteString
prevRest
              in ByteString -> StateT ByteString m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put ByteString
newRest StateT ByteString m ()
-> StateT ByteString m [ByteString]
-> StateT ByteString m [ByteString]
forall a b.
StateT ByteString m a
-> StateT ByteString m b -> StateT ByteString m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [ByteString] -> StateT ByteString m [ByteString]
forall a. a -> StateT ByteString m a
forall (m :: * -> *) a. Monad m => a -> m a
return [ByteString
bs]
    where
      readLoop :: Int -> StateT ByteString m [ByteString]
      readLoop :: Int -> StateT ByteString m [ByteString]
readLoop Int
readNumBytes = do
        -- Amount of bytes we need to request in order to get atleast
        -- 'readNumBytes' bytes of data.
        let reqSize :: Int
reqSize    = Int
packetSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
reqPackets
            reqPackets :: Int
reqPackets = Int
readNumBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`divRndUp` Int
packetDataSize
        -- Timeout is ignored; the number of bytes that was read contains
        -- enough information.
        (ByteString
bytes, Status
_) <- IO (ByteString, Status) -> StateT ByteString m (ByteString, Status)
forall a. IO a -> StateT ByteString m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ByteString, Status)
 -> StateT ByteString m (ByteString, Status))
-> IO (ByteString, Status)
-> StateT ByteString m (ByteString, Status)
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> Int -> IO (ByteString, Status)
readBulk InterfaceHandle
ifHnd Int
reqSize

        let receivedDataBytes :: Int
receivedDataBytes   = Int
receivedBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
receivedHeaderBytes
            receivedBytes :: Int
receivedBytes       = ByteString -> Int
BS.length ByteString
bytes
            receivedHeaderBytes :: Int
receivedHeaderBytes = Int
packetHeaderSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
receivedPackets
            receivedPackets :: Int
receivedPackets     = Int
receivedBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`divRndUp` Int
packetSize

        -- The reason for not actually getting the requested amount of bytes
        -- could be either a USB timeout or the FTDI latency timer firing.
        --
        -- In case of a USB timeout:
        --   ∃ (n : Nat). receivedBytes ≡ n * packetSize
        --
        -- In case of FTDI latency timer:
        --   receivedBytes < packetSize
        if Int
receivedDataBytes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
readNumBytes
          then let xs :: [ByteString]
xs = ByteString -> [ByteString]
splitPackets ByteString
bytes
               in m Bool -> StateT ByteString m Bool
forall (m :: * -> *) a. Monad m => m a -> StateT ByteString m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Bool
checkStop StateT ByteString m Bool
-> (Bool -> StateT ByteString m [ByteString])
-> StateT ByteString m [ByteString]
forall a b.
StateT ByteString m a
-> (a -> StateT ByteString m b) -> StateT ByteString m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Bool
stop ->
                  if Bool
stop
                  then ByteString -> StateT ByteString m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put ByteString
BS.empty StateT ByteString m ()
-> StateT ByteString m [ByteString]
-> StateT ByteString m [ByteString]
forall a b.
StateT ByteString m a
-> StateT ByteString m b -> StateT ByteString m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [ByteString] -> StateT ByteString m [ByteString]
forall a. a -> StateT ByteString m a
forall (m :: * -> *) a. Monad m => a -> m a
return [ByteString]
xs
                  else ([ByteString] -> [ByteString])
-> StateT ByteString m [ByteString]
-> StateT ByteString m [ByteString]
forall a b.
(a -> b) -> StateT ByteString m a -> StateT ByteString m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([ByteString]
xs [ByteString] -> [ByteString] -> [ByteString]
forall a. Semigroup a => a -> a -> a
<>)
                            (Int -> StateT ByteString m [ByteString]
readLoop (Int -> StateT ByteString m [ByteString])
-> Int -> StateT ByteString m [ByteString]
forall a b. (a -> b) -> a -> b
$ Int
readNumBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
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. The rest is kept for future usage.
               let (ByteString
bs, ByteString
newRest) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt (Int -> Int
splitIndex Int
readNumBytes) ByteString
bytes
               in ByteString -> StateT ByteString m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put ByteString
newRest StateT ByteString m ()
-> StateT ByteString m [ByteString]
-> StateT ByteString m [ByteString]
forall a b.
StateT ByteString m a
-> StateT ByteString m b -> StateT ByteString m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [ByteString] -> StateT ByteString m [ByteString]
forall a. a -> StateT ByteString m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> [ByteString]
splitPackets ByteString
bs)

      splitIndex :: Int -> Int
splitIndex Int
n = Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
packetSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
packetHeaderSize
                     Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
packetDataSize)
          where p :: Int
p = Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
packetDataSize

      packetDataSize :: Int
packetDataSize   = Int
packetSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
packetHeaderSize
      packetHeaderSize :: Int
packetHeaderSize = Int
2
      packetSize :: Int
packetSize       = MaxPacketSize -> Int
USB.maxPacketSize
                         (MaxPacketSize -> Int)
-> (EndpointDesc -> MaxPacketSize) -> EndpointDesc -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EndpointDesc -> MaxPacketSize
USB.endpointMaxPacketSize
                         (EndpointDesc -> Int) -> EndpointDesc -> Int
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> EndpointDesc
ifHndInEPDesc InterfaceHandle
ifHnd

      -- |Split a stream of bytes into packets. The first 2 bytes of each
      -- packet are the modem status bytes and are dropped.
      splitPackets :: ByteString -> [ByteString]
splitPackets ByteString
xs | ByteString -> Bool
BS.null ByteString
xs = []
                      | Bool
otherwise  = case Int -> ByteString -> (ByteString, ByteString)
BS.splitAt Int
packetSize ByteString
xs of
                                       (ByteString
a, ByteString
b) -> Int -> ByteString -> ByteString
BS.drop Int
2 ByteString
a ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: ByteString -> [ByteString]
splitPackets ByteString
b

-- |Perform a bulk read.
--
-- 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
         -> IO (ByteString, USB.Status)
readBulk :: InterfaceHandle -> Int -> IO (ByteString, Status)
readBulk InterfaceHandle
ifHnd =
    DeviceHandle -> EndpointAddress -> ReadAction
USB.readBulk (DeviceHandle -> DeviceHandle
devHndUSB (DeviceHandle -> DeviceHandle) -> DeviceHandle -> DeviceHandle
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd)
                 (Interface -> EndpointAddress
interfaceEndPointIn (Interface -> EndpointAddress) -> Interface -> EndpointAddress
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> Interface
ifHndInterface InterfaceHandle
ifHnd)
                 (DeviceHandle -> Int
devHndTimeout (DeviceHandle -> Int) -> DeviceHandle -> Int
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd)

-- |Perform a bulk write.
--
-- Returns the number of bytes that where written and a flag which indicates
-- whether a timeout occured during the request.
writeBulk :: InterfaceHandle
          -> ByteString -- ^Data to be written
          -> IO (Int, USB.Status)
writeBulk :: InterfaceHandle -> ByteString -> IO (Int, Status)
writeBulk InterfaceHandle
ifHnd ByteString
bs =
    DeviceHandle -> EndpointAddress -> WriteAction
USB.writeBulk (DeviceHandle -> DeviceHandle
devHndUSB (DeviceHandle -> DeviceHandle) -> DeviceHandle -> DeviceHandle
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd)
                  (Interface -> EndpointAddress
interfaceEndPointOut (Interface -> EndpointAddress) -> Interface -> EndpointAddress
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> Interface
ifHndInterface InterfaceHandle
ifHnd)
                  ByteString
bs
                  (DeviceHandle -> Int
devHndTimeout (DeviceHandle -> Int) -> DeviceHandle -> Int
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd)

-------------------------------------------------------------------------------
-- Control Requests
-------------------------------------------------------------------------------

-- |The type of a USB control request.
type USBControl a = USB.DeviceHandle
                  -> USB.ControlSetup
                  -> USB.Timeout
                  -> a

-- |Generic FTDI control request with explicit index
genControl :: USBControl a
           -> USB.Index -- ^Index
           -> InterfaceHandle
           -> RequestCode
           -> RequestValue
           -> a
genControl :: forall a.
USBControl a -> Word16 -> InterfaceHandle -> Word8 -> Word16 -> a
genControl USBControl a
usbCtrl Word16
index InterfaceHandle
ifHnd Word8
request Word16
value =
    USBControl a
usbCtrl DeviceHandle
usbHnd ControlSetup
setup (DeviceHandle -> Int
devHndTimeout DeviceHandle
devHnd)
    where devHnd :: DeviceHandle
devHnd = InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd
          usbHnd :: DeviceHandle
usbHnd = DeviceHandle -> DeviceHandle
devHndUSB DeviceHandle
devHnd
          index' :: Word16
index' = Word16
index Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Interface -> Word16
interfaceIndex (InterfaceHandle -> Interface
ifHndInterface InterfaceHandle
ifHnd)
          setup :: ControlSetup
setup  = USB.ControlSetup { controlSetupRequestType :: RequestType
USB.controlSetupRequestType = RequestType
USB.Vendor
                                    , controlSetupRecipient :: Recipient
USB.controlSetupRecipient   = Recipient
USB.ToDevice
                                    , controlSetupRequest :: Word8
USB.controlSetupRequest     = Word8
request
                                    , controlSetupValue :: Word16
USB.controlSetupValue       = Word16
value
                                    , controlSetupIndex :: Word16
USB.controlSetupIndex       = Word16
index'
                                    }

control :: InterfaceHandle -> RequestCode -> USB.Value -> IO ()
control :: InterfaceHandle -> Word8 -> Word16 -> IO ()
control = USBControl (IO ())
-> Word16 -> InterfaceHandle -> Word8 -> Word16 -> IO ()
forall a.
USBControl a -> Word16 -> InterfaceHandle -> Word8 -> Word16 -> a
genControl USBControl (IO ())
USB.control Word16
0

readControl :: InterfaceHandle -> RequestCode -> USB.Value -> USB.Size -> IO (ByteString, USB.Status)
readControl :: InterfaceHandle
-> Word8 -> Word16 -> Int -> IO (ByteString, Status)
readControl = USBControl (Int -> IO (ByteString, Status))
-> Word16
-> InterfaceHandle
-> Word8
-> Word16
-> Int
-> IO (ByteString, Status)
forall a.
USBControl a -> Word16 -> InterfaceHandle -> Word8 -> Word16 -> a
genControl USBControl (Int -> IO (ByteString, Status))
USB.readControl Word16
0

writeControl :: InterfaceHandle -> RequestCode -> USB.Value -> ByteString -> IO (USB.Size, USB.Status)
writeControl :: InterfaceHandle
-> Word8 -> Word16 -> ByteString -> IO (Int, Status)
writeControl = USBControl (ByteString -> IO (Int, Status))
-> Word16
-> InterfaceHandle
-> Word8
-> Word16
-> ByteString
-> IO (Int, Status)
forall a.
USBControl a -> Word16 -> InterfaceHandle -> Word8 -> Word16 -> a
genControl (\DeviceHandle
hdl ControlSetup
setup Int
timeout ByteString
bs -> DeviceHandle -> ControlSetup -> WriteAction
USB.writeControl DeviceHandle
hdl ControlSetup
setup ByteString
bs Int
timeout) Word16
0

-------------------------------------------------------------------------------

-- |Reset the FTDI device.
reset :: InterfaceHandle -> IO ()
reset :: InterfaceHandle -> IO ()
reset InterfaceHandle
ifHnd = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqReset Word16
valResetSIO

-- |Clear the on-chip read buffer.
purgeReadBuffer :: InterfaceHandle -> IO ()
purgeReadBuffer :: InterfaceHandle -> IO ()
purgeReadBuffer InterfaceHandle
ifHnd = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqReset Word16
valPurgeReadBuffer

-- |Clear the on-chip write buffer.
purgeWriteBuffer :: InterfaceHandle -> IO ()
purgeWriteBuffer :: InterfaceHandle -> IO ()
purgeWriteBuffer InterfaceHandle
ifHnd = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqReset Word16
valPurgeWriteBuffer

-------------------------------------------------------------------------------

-- |Returns the current value of the FTDI latency timer.
getLatencyTimer :: InterfaceHandle -> IO Word8
getLatencyTimer :: InterfaceHandle -> IO Word8
getLatencyTimer InterfaceHandle
ifHnd = do
    (ByteString
bs, Status
_) <- InterfaceHandle
-> Word8 -> Word16 -> Int -> IO (ByteString, Status)
readControl InterfaceHandle
ifHnd Word8
reqGetLatencyTimer Word16
0 Int
1
    case ByteString -> [Word8]
BS.unpack ByteString
bs of
      [Word8
b] -> Word8 -> IO Word8
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Word8
b
      [Word8]
_   -> String -> IO Word8
forall a. HasCallStack => String -> a
error String
"System.FTDI.getLatencyTimer: failed"

-- |Set the FTDI latency timer. The latency is the amount of
-- milliseconds after which the FTDI chip will send a packet
-- regardless of the number of bytes in the packet.
setLatencyTimer :: InterfaceHandle -> Word8 -> IO ()
setLatencyTimer :: InterfaceHandle -> Word8 -> IO ()
setLatencyTimer InterfaceHandle
ifHnd Word8
latency = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqSetLatencyTimer
                                        (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
latency

-- |MPSSE bitbang modes
data BitMode = -- |Switch off bitbang mode, back to regular serial/FIFO.
               BitMode_Reset
               -- |Classical asynchronous bitbang mode, introduced with B-type
               -- chips.
             | BitMode_BitBang
               -- |Multi-Protocol Synchronous Serial Engine, available on 2232x
               -- chips.
             | BitMode_MPSSE
               -- |Synchronous Bit-Bang Mode, available on 2232x and R-type
               -- chips.
             | BitMode_SyncBitBang
               -- |MCU Host Bus Emulation Mode, available on 2232x
               -- chips. CPU-style fifo mode gets set via EEPROM.
             | BitMode_MCU
               -- |Fast Opto-Isolated Serial Interface Mode, available on 2232x
               -- chips.
             | BitMode_Opto
               -- |Bit-Bang on CBus pins of R-type chips, configure in EEPROM
               -- before use.
             | BitMode_CBus
               -- |Single Channel Synchronous FIFO Mode, available on 2232H
               -- chips.
             | BitMode_SyncFIFO
              deriving (BitMode -> BitMode -> Bool
(BitMode -> BitMode -> Bool)
-> (BitMode -> BitMode -> Bool) -> Eq BitMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BitMode -> BitMode -> Bool
== :: BitMode -> BitMode -> Bool
$c/= :: BitMode -> BitMode -> Bool
/= :: BitMode -> BitMode -> Bool
Eq, Eq BitMode
Eq BitMode =>
(BitMode -> BitMode -> Ordering)
-> (BitMode -> BitMode -> Bool)
-> (BitMode -> BitMode -> Bool)
-> (BitMode -> BitMode -> Bool)
-> (BitMode -> BitMode -> Bool)
-> (BitMode -> BitMode -> BitMode)
-> (BitMode -> BitMode -> BitMode)
-> Ord BitMode
BitMode -> BitMode -> Bool
BitMode -> BitMode -> Ordering
BitMode -> BitMode -> BitMode
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BitMode -> BitMode -> Ordering
compare :: BitMode -> BitMode -> Ordering
$c< :: BitMode -> BitMode -> Bool
< :: BitMode -> BitMode -> Bool
$c<= :: BitMode -> BitMode -> Bool
<= :: BitMode -> BitMode -> Bool
$c> :: BitMode -> BitMode -> Bool
> :: BitMode -> BitMode -> Bool
$c>= :: BitMode -> BitMode -> Bool
>= :: BitMode -> BitMode -> Bool
$cmax :: BitMode -> BitMode -> BitMode
max :: BitMode -> BitMode -> BitMode
$cmin :: BitMode -> BitMode -> BitMode
min :: BitMode -> BitMode -> BitMode
Ord, Int -> BitMode -> ShowS
[BitMode] -> ShowS
BitMode -> String
(Int -> BitMode -> ShowS)
-> (BitMode -> String) -> ([BitMode] -> ShowS) -> Show BitMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BitMode -> ShowS
showsPrec :: Int -> BitMode -> ShowS
$cshow :: BitMode -> String
show :: BitMode -> String
$cshowList :: [BitMode] -> ShowS
showList :: [BitMode] -> ShowS
Show, Typeable BitMode
Typeable BitMode =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> BitMode -> c BitMode)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c BitMode)
-> (BitMode -> Constr)
-> (BitMode -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c BitMode))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BitMode))
-> ((forall b. Data b => b -> b) -> BitMode -> BitMode)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> BitMode -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> BitMode -> r)
-> (forall u. (forall d. Data d => d -> u) -> BitMode -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> BitMode -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> BitMode -> m BitMode)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> BitMode -> m BitMode)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> BitMode -> m BitMode)
-> Data BitMode
BitMode -> Constr
BitMode -> DataType
(forall b. Data b => b -> b) -> BitMode -> BitMode
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> BitMode -> u
forall u. (forall d. Data d => d -> u) -> BitMode -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BitMode -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BitMode -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BitMode
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BitMode -> c BitMode
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BitMode)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BitMode)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BitMode -> c BitMode
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BitMode -> c BitMode
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BitMode
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BitMode
$ctoConstr :: BitMode -> Constr
toConstr :: BitMode -> Constr
$cdataTypeOf :: BitMode -> DataType
dataTypeOf :: BitMode -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BitMode)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BitMode)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BitMode)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c BitMode)
$cgmapT :: (forall b. Data b => b -> b) -> BitMode -> BitMode
gmapT :: (forall b. Data b => b -> b) -> BitMode -> BitMode
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BitMode -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BitMode -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BitMode -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BitMode -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> BitMode -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> BitMode -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BitMode -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BitMode -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BitMode -> m BitMode
Data, Typeable)

marshalBitMode :: BitMode -> Word8
marshalBitMode :: BitMode -> Word8
marshalBitMode BitMode
bm = case BitMode
bm of
                      BitMode
BitMode_Reset       -> Word8
0x00
                      BitMode
BitMode_BitBang     -> Word8
0x01
                      BitMode
BitMode_MPSSE       -> Word8
0x02
                      BitMode
BitMode_SyncBitBang -> Word8
0x04
                      BitMode
BitMode_MCU         -> Word8
0x08
                      BitMode
BitMode_Opto        -> Word8
0x10
                      BitMode
BitMode_CBus        -> Word8
0x20
                      BitMode
BitMode_SyncFIFO    -> Word8
0x40

-- |The bitmode controls the method of communication.
setBitMode :: InterfaceHandle -> Word8 -> BitMode -> IO ()
setBitMode :: InterfaceHandle -> Word8 -> BitMode -> IO ()
setBitMode InterfaceHandle
ifHnd Word8
bitMask BitMode
bitMode = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqSetBitMode Word16
value
    where bitMask' :: Word16
bitMask' = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
bitMask
          bitMode' :: Word16
bitMode' = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word16) -> Word8 -> Word16
forall a b. (a -> b) -> a -> b
$ BitMode -> Word8
marshalBitMode BitMode
bitMode
          value :: Word16
value    = Word16
bitMask' Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftL Word16
bitMode' Int
8

-- |Sets the baud rate. Internally the baud rate is represented as a
-- fraction. The maximum baudrate is the numerator and a special
-- /divisor/ is used as the denominator. The maximum baud rate is
-- given by the 'BaudRate' instance for 'Bounded'. The divisor
-- consists of an integral part and a fractional part. Both parts are
-- limited in range. As a result not all baud rates can be accurately
          -- represented. This function returns the nearest representable baud
-- rate relative to the requested baud rate. According to FTDI
-- documentation the maximum allowed error is 3%. The nearest
-- representable baud rate can be calculated with the
-- 'nearestBaudRate' function.
setBaudRate :: RealFrac a => InterfaceHandle -> BaudRate a -> IO (BaudRate a)
setBaudRate :: forall a.
RealFrac a =>
InterfaceHandle -> BaudRate a -> IO (BaudRate a)
setBaudRate InterfaceHandle
ifHnd BaudRate a
baudRate =
  do USBControl (IO ())
-> Word16 -> InterfaceHandle -> Word8 -> Word16 -> IO ()
forall a.
USBControl a -> Word16 -> InterfaceHandle -> Word8 -> Word16 -> a
genControl USBControl (IO ())
USB.control Word16
ix InterfaceHandle
ifHnd Word8
reqSetBaudRate Word16
val
     BaudRate a -> IO (BaudRate a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return BaudRate a
b
  where
    (Word16
val, Word16
ix) = ChipType -> BRDiv Int -> BRSubDiv Int -> (Word16, Word16)
encodeBaudRateDivisors ChipType
chip BRDiv Int
d BRSubDiv Int
s
    (BRDiv Int
d, BRSubDiv Int
s, BaudRate a
b) = ChipType -> BaudRate a -> (BRDiv Int, BRSubDiv Int, BaudRate a)
forall a.
RealFrac a =>
ChipType -> BaudRate a -> (BRDiv Int, BRSubDiv Int, BaudRate a)
calcBaudRateDivisors ChipType
chip BaudRate a
baudRate
    chip :: ChipType
chip = Device -> ChipType
devChipType (Device -> ChipType) -> Device -> ChipType
forall a b. (a -> b) -> a -> b
$ DeviceHandle -> Device
devHndDev (DeviceHandle -> Device) -> DeviceHandle -> Device
forall a b. (a -> b) -> a -> b
$ InterfaceHandle -> DeviceHandle
ifHndDevHnd InterfaceHandle
ifHnd


data Parity = -- |The parity bit is set to one if the number of ones in a given
              -- set of bits is even (making the total number of ones, including
              -- the parity bit, odd).
              Parity_Odd
              -- |The parity bit is set to one if the number of ones in a given
              -- set of bits is odd (making the total number of ones, including
              -- the parity bit, even).
            | Parity_Even
            | Parity_Mark  -- ^The parity bit is always 1.
            | Parity_Space -- ^The parity bit is always 0.
              deriving (Int -> Parity
Parity -> Int
Parity -> [Parity]
Parity -> Parity
Parity -> Parity -> [Parity]
Parity -> Parity -> Parity -> [Parity]
(Parity -> Parity)
-> (Parity -> Parity)
-> (Int -> Parity)
-> (Parity -> Int)
-> (Parity -> [Parity])
-> (Parity -> Parity -> [Parity])
-> (Parity -> Parity -> [Parity])
-> (Parity -> Parity -> Parity -> [Parity])
-> Enum Parity
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Parity -> Parity
succ :: Parity -> Parity
$cpred :: Parity -> Parity
pred :: Parity -> Parity
$ctoEnum :: Int -> Parity
toEnum :: Int -> Parity
$cfromEnum :: Parity -> Int
fromEnum :: Parity -> Int
$cenumFrom :: Parity -> [Parity]
enumFrom :: Parity -> [Parity]
$cenumFromThen :: Parity -> Parity -> [Parity]
enumFromThen :: Parity -> Parity -> [Parity]
$cenumFromTo :: Parity -> Parity -> [Parity]
enumFromTo :: Parity -> Parity -> [Parity]
$cenumFromThenTo :: Parity -> Parity -> Parity -> [Parity]
enumFromThenTo :: Parity -> Parity -> Parity -> [Parity]
Enum, Parity -> Parity -> Bool
(Parity -> Parity -> Bool)
-> (Parity -> Parity -> Bool) -> Eq Parity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Parity -> Parity -> Bool
== :: Parity -> Parity -> Bool
$c/= :: Parity -> Parity -> Bool
/= :: Parity -> Parity -> Bool
Eq, Eq Parity
Eq Parity =>
(Parity -> Parity -> Ordering)
-> (Parity -> Parity -> Bool)
-> (Parity -> Parity -> Bool)
-> (Parity -> Parity -> Bool)
-> (Parity -> Parity -> Bool)
-> (Parity -> Parity -> Parity)
-> (Parity -> Parity -> Parity)
-> Ord Parity
Parity -> Parity -> Bool
Parity -> Parity -> Ordering
Parity -> Parity -> Parity
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Parity -> Parity -> Ordering
compare :: Parity -> Parity -> Ordering
$c< :: Parity -> Parity -> Bool
< :: Parity -> Parity -> Bool
$c<= :: Parity -> Parity -> Bool
<= :: Parity -> Parity -> Bool
$c> :: Parity -> Parity -> Bool
> :: Parity -> Parity -> Bool
$c>= :: Parity -> Parity -> Bool
>= :: Parity -> Parity -> Bool
$cmax :: Parity -> Parity -> Parity
max :: Parity -> Parity -> Parity
$cmin :: Parity -> Parity -> Parity
min :: Parity -> Parity -> Parity
Ord, Int -> Parity -> ShowS
[Parity] -> ShowS
Parity -> String
(Int -> Parity -> ShowS)
-> (Parity -> String) -> ([Parity] -> ShowS) -> Show Parity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Parity -> ShowS
showsPrec :: Int -> Parity -> ShowS
$cshow :: Parity -> String
show :: Parity -> String
$cshowList :: [Parity] -> ShowS
showList :: [Parity] -> ShowS
Show, Typeable Parity
Typeable Parity =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Parity -> c Parity)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Parity)
-> (Parity -> Constr)
-> (Parity -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Parity))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Parity))
-> ((forall b. Data b => b -> b) -> Parity -> Parity)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Parity -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Parity -> r)
-> (forall u. (forall d. Data d => d -> u) -> Parity -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Parity -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Parity -> m Parity)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Parity -> m Parity)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Parity -> m Parity)
-> Data Parity
Parity -> Constr
Parity -> DataType
(forall b. Data b => b -> b) -> Parity -> Parity
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Parity -> u
forall u. (forall d. Data d => d -> u) -> Parity -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Parity -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Parity -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Parity
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Parity -> c Parity
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Parity)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Parity)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Parity -> c Parity
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Parity -> c Parity
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Parity
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Parity
$ctoConstr :: Parity -> Constr
toConstr :: Parity -> Constr
$cdataTypeOf :: Parity -> DataType
dataTypeOf :: Parity -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Parity)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Parity)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Parity)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Parity)
$cgmapT :: (forall b. Data b => b -> b) -> Parity -> Parity
gmapT :: (forall b. Data b => b -> b) -> Parity -> Parity
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Parity -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Parity -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Parity -> r
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Parity -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Parity -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Parity -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Parity -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Parity -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Parity -> m Parity
Data, Typeable)

data BitDataFormat = Bits_7
                   | Bits_8

data StopBits = StopBit_1
              | StopBit_15
              | StopBit_2
                deriving (Int -> StopBits
StopBits -> Int
StopBits -> [StopBits]
StopBits -> StopBits
StopBits -> StopBits -> [StopBits]
StopBits -> StopBits -> StopBits -> [StopBits]
(StopBits -> StopBits)
-> (StopBits -> StopBits)
-> (Int -> StopBits)
-> (StopBits -> Int)
-> (StopBits -> [StopBits])
-> (StopBits -> StopBits -> [StopBits])
-> (StopBits -> StopBits -> [StopBits])
-> (StopBits -> StopBits -> StopBits -> [StopBits])
-> Enum StopBits
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: StopBits -> StopBits
succ :: StopBits -> StopBits
$cpred :: StopBits -> StopBits
pred :: StopBits -> StopBits
$ctoEnum :: Int -> StopBits
toEnum :: Int -> StopBits
$cfromEnum :: StopBits -> Int
fromEnum :: StopBits -> Int
$cenumFrom :: StopBits -> [StopBits]
enumFrom :: StopBits -> [StopBits]
$cenumFromThen :: StopBits -> StopBits -> [StopBits]
enumFromThen :: StopBits -> StopBits -> [StopBits]
$cenumFromTo :: StopBits -> StopBits -> [StopBits]
enumFromTo :: StopBits -> StopBits -> [StopBits]
$cenumFromThenTo :: StopBits -> StopBits -> StopBits -> [StopBits]
enumFromThenTo :: StopBits -> StopBits -> StopBits -> [StopBits]
Enum)

-- |Set RS232 line characteristics
setLineProperty :: InterfaceHandle
                -> BitDataFormat -- ^Number of bits
                -> StopBits      -- ^Number of stop bits
                -> Maybe Parity  -- ^Optional parity mode
                -> Bool          -- ^Break
                -> IO ()
setLineProperty :: InterfaceHandle
-> BitDataFormat -> StopBits -> Maybe Parity -> Bool -> IO ()
setLineProperty InterfaceHandle
ifHnd BitDataFormat
bitDataFormat StopBits
stopBits Maybe Parity
parity Bool
break' =
    InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd
            Word8
reqSetData
            (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ [Word16] -> Word16
forall a. (Num a, Bits a) => [a] -> a
orBits [ case BitDataFormat
bitDataFormat of
                         BitDataFormat
Bits_7 -> Word16
7
                         BitDataFormat
Bits_8 -> Word16
8
                     , Word16 -> (Parity -> Word16) -> Maybe Parity -> Word16
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word16
0 (\Parity
p -> (Word16
1 Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ Parity -> Word16
forall e n. (Enum e, Num n) => e -> n
genFromEnum Parity
p) Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Maybe Parity
parity
                     , StopBits -> Word16
forall e n. (Enum e, Num n) => e -> n
genFromEnum StopBits
stopBits Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
11
                     , Bool -> Word16
forall e n. (Enum e, Num n) => e -> n
genFromEnum Bool
break'   Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
14
                     ]

-------------------------------------------------------------------------------
-- Modem status
-------------------------------------------------------------------------------

-- |Modem status information. The modem status is send as a header for
-- each read access. In the absence of data the FTDI chip will
-- generate the status every 40 ms.
--
-- The modem status can be explicitely requested with the
-- 'pollModemStatus' function.
data ModemStatus = ModemStatus
    { -- |Clear to send (CTS)
      ModemStatus -> Bool
msClearToSend :: Bool
      -- |Data set ready (DTS)
    , ModemStatus -> Bool
msDataSetReady :: Bool
      -- |Ring indicator (RI)
    , ModemStatus -> Bool
msRingIndicator :: Bool
      -- |Receive line signal detect (RLSD)
    , ModemStatus -> Bool
msReceiveLineSignalDetect :: Bool
      -- | Data ready (DR)
    , ModemStatus -> Bool
msDataReady :: Bool
      -- |Overrun error (OE)
    , ModemStatus -> Bool
msOverrunError :: Bool
      -- |Parity error (PE)
    , ModemStatus -> Bool
msParityError :: Bool
      -- |Framing error (FE)
    , ModemStatus -> Bool
msFramingError :: Bool
      -- |Break interrupt (BI)
    , ModemStatus -> Bool
msBreakInterrupt :: Bool
      -- |Transmitter holding register (THRE)
    , ModemStatus -> Bool
msTransmitterHoldingRegister :: Bool
      -- |Transmitter empty (TEMT)
    , ModemStatus -> Bool
msTransmitterEmpty :: Bool
      -- |Error in RCVR FIFO
    , ModemStatus -> Bool
msErrorInReceiverFIFO :: Bool
    } deriving (ModemStatus -> ModemStatus -> Bool
(ModemStatus -> ModemStatus -> Bool)
-> (ModemStatus -> ModemStatus -> Bool) -> Eq ModemStatus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ModemStatus -> ModemStatus -> Bool
== :: ModemStatus -> ModemStatus -> Bool
$c/= :: ModemStatus -> ModemStatus -> Bool
/= :: ModemStatus -> ModemStatus -> Bool
Eq, Eq ModemStatus
Eq ModemStatus =>
(ModemStatus -> ModemStatus -> Ordering)
-> (ModemStatus -> ModemStatus -> Bool)
-> (ModemStatus -> ModemStatus -> Bool)
-> (ModemStatus -> ModemStatus -> Bool)
-> (ModemStatus -> ModemStatus -> Bool)
-> (ModemStatus -> ModemStatus -> ModemStatus)
-> (ModemStatus -> ModemStatus -> ModemStatus)
-> Ord ModemStatus
ModemStatus -> ModemStatus -> Bool
ModemStatus -> ModemStatus -> Ordering
ModemStatus -> ModemStatus -> ModemStatus
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ModemStatus -> ModemStatus -> Ordering
compare :: ModemStatus -> ModemStatus -> Ordering
$c< :: ModemStatus -> ModemStatus -> Bool
< :: ModemStatus -> ModemStatus -> Bool
$c<= :: ModemStatus -> ModemStatus -> Bool
<= :: ModemStatus -> ModemStatus -> Bool
$c> :: ModemStatus -> ModemStatus -> Bool
> :: ModemStatus -> ModemStatus -> Bool
$c>= :: ModemStatus -> ModemStatus -> Bool
>= :: ModemStatus -> ModemStatus -> Bool
$cmax :: ModemStatus -> ModemStatus -> ModemStatus
max :: ModemStatus -> ModemStatus -> ModemStatus
$cmin :: ModemStatus -> ModemStatus -> ModemStatus
min :: ModemStatus -> ModemStatus -> ModemStatus
Ord, Int -> ModemStatus -> ShowS
[ModemStatus] -> ShowS
ModemStatus -> String
(Int -> ModemStatus -> ShowS)
-> (ModemStatus -> String)
-> ([ModemStatus] -> ShowS)
-> Show ModemStatus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ModemStatus -> ShowS
showsPrec :: Int -> ModemStatus -> ShowS
$cshow :: ModemStatus -> String
show :: ModemStatus -> String
$cshowList :: [ModemStatus] -> ShowS
showList :: [ModemStatus] -> ShowS
Show, Typeable ModemStatus
Typeable ModemStatus =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ModemStatus -> c ModemStatus)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ModemStatus)
-> (ModemStatus -> Constr)
-> (ModemStatus -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ModemStatus))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ModemStatus))
-> ((forall b. Data b => b -> b) -> ModemStatus -> ModemStatus)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ModemStatus -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ModemStatus -> r)
-> (forall u. (forall d. Data d => d -> u) -> ModemStatus -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ModemStatus -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus)
-> Data ModemStatus
ModemStatus -> Constr
ModemStatus -> DataType
(forall b. Data b => b -> b) -> ModemStatus -> ModemStatus
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ModemStatus -> u
forall u. (forall d. Data d => d -> u) -> ModemStatus -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ModemStatus -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ModemStatus -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ModemStatus
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ModemStatus -> c ModemStatus
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ModemStatus)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ModemStatus)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ModemStatus -> c ModemStatus
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ModemStatus -> c ModemStatus
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ModemStatus
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ModemStatus
$ctoConstr :: ModemStatus -> Constr
toConstr :: ModemStatus -> Constr
$cdataTypeOf :: ModemStatus -> DataType
dataTypeOf :: ModemStatus -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ModemStatus)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ModemStatus)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ModemStatus)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ModemStatus)
$cgmapT :: (forall b. Data b => b -> b) -> ModemStatus -> ModemStatus
gmapT :: (forall b. Data b => b -> b) -> ModemStatus -> ModemStatus
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ModemStatus -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ModemStatus -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ModemStatus -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ModemStatus -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ModemStatus -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ModemStatus -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ModemStatus -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ModemStatus -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModemStatus -> m ModemStatus
Data, Typeable, (forall x. ModemStatus -> Rep ModemStatus x)
-> (forall x. Rep ModemStatus x -> ModemStatus)
-> Generic ModemStatus
forall x. Rep ModemStatus x -> ModemStatus
forall x. ModemStatus -> Rep ModemStatus x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ModemStatus -> Rep ModemStatus x
from :: forall x. ModemStatus -> Rep ModemStatus x
$cto :: forall x. Rep ModemStatus x -> ModemStatus
to :: forall x. Rep ModemStatus x -> ModemStatus
Generic)

marshalModemStatus :: ModemStatus -> (Word8, Word8)
marshalModemStatus :: ModemStatus -> (Word8, Word8)
marshalModemStatus ModemStatus
ms = (Word8
a, Word8
b)
    where
      a :: Word8
a = [(Int, ModemStatus -> Bool)] -> Word8
mkByte ([(Int, ModemStatus -> Bool)] -> Word8)
-> [(Int, ModemStatus -> Bool)] -> Word8
forall a b. (a -> b) -> a -> b
$ [Int] -> [ModemStatus -> Bool] -> [(Int, ModemStatus -> Bool)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
4..]
                       [ ModemStatus -> Bool
msClearToSend
                       , ModemStatus -> Bool
msDataSetReady
                       , ModemStatus -> Bool
msRingIndicator
                       , ModemStatus -> Bool
msReceiveLineSignalDetect
                       ]
      b :: Word8
b = [(Int, ModemStatus -> Bool)] -> Word8
mkByte ([(Int, ModemStatus -> Bool)] -> Word8)
-> [(Int, ModemStatus -> Bool)] -> Word8
forall a b. (a -> b) -> a -> b
$ [Int] -> [ModemStatus -> Bool] -> [(Int, ModemStatus -> Bool)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..]
                       [ ModemStatus -> Bool
msDataReady
                       , ModemStatus -> Bool
msOverrunError
                       , ModemStatus -> Bool
msParityError
                       , ModemStatus -> Bool
msFramingError
                       , ModemStatus -> Bool
msBreakInterrupt
                       , ModemStatus -> Bool
msTransmitterHoldingRegister
                       , ModemStatus -> Bool
msTransmitterEmpty
                       , ModemStatus -> Bool
msErrorInReceiverFIFO
                       ]

      mkByte :: [(Int, ModemStatus -> Bool)] -> Word8
      mkByte :: [(Int, ModemStatus -> Bool)] -> Word8
mkByte = ((Int, ModemStatus -> Bool) -> Word8 -> Word8)
-> Word8 -> [(Int, ModemStatus -> Bool)] -> Word8
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(Int
n, ModemStatus -> Bool
f) Word8
x -> if ModemStatus -> Bool
f ModemStatus
ms then Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
setBit Word8
x Int
n else Word8
x) Word8
0

unmarshalModemStatus :: Word8 -> Word8 -> ModemStatus
unmarshalModemStatus :: Word8 -> Word8 -> ModemStatus
unmarshalModemStatus Word8
a Word8
b =
    ModemStatus { msClearToSend :: Bool
msClearToSend                = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
a Int
4
                , msDataSetReady :: Bool
msDataSetReady               = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
a Int
5
                , msRingIndicator :: Bool
msRingIndicator              = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
a Int
6
                , msReceiveLineSignalDetect :: Bool
msReceiveLineSignalDetect    = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
a Int
7
                , msDataReady :: Bool
msDataReady                  = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
0
                , msOverrunError :: Bool
msOverrunError               = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
1
                , msParityError :: Bool
msParityError                = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
2
                , msFramingError :: Bool
msFramingError               = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
3
                , msBreakInterrupt :: Bool
msBreakInterrupt             = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
4
                , msTransmitterHoldingRegister :: Bool
msTransmitterHoldingRegister = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
5
                , msTransmitterEmpty :: Bool
msTransmitterEmpty           = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
6
                , msErrorInReceiverFIFO :: Bool
msErrorInReceiverFIFO        = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
b Int
7
                }

-- |Manually request the modem status.
pollModemStatus :: InterfaceHandle -> IO ModemStatus
pollModemStatus :: InterfaceHandle -> IO ModemStatus
pollModemStatus InterfaceHandle
ifHnd = do
    (ByteString
bs, Status
_) <- InterfaceHandle
-> Word8 -> Word16 -> Int -> IO (ByteString, Status)
readControl InterfaceHandle
ifHnd Word8
reqPollModemStatus Word16
0 Int
2
    case ByteString -> [Word8]
BS.unpack ByteString
bs of
      [Word8
x,Word8
y] -> ModemStatus -> IO ModemStatus
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ModemStatus -> IO ModemStatus) -> ModemStatus -> IO ModemStatus
forall a b. (a -> b) -> a -> b
$ Word8 -> Word8 -> ModemStatus
unmarshalModemStatus Word8
x Word8
y
      [Word8]
_     -> String -> IO ModemStatus
forall a. HasCallStack => String -> a
error String
"System.FTDI.pollModemStatus: failed"


-------------------------------------------------------------------------------
-- Flow control
-------------------------------------------------------------------------------

data FlowCtrl = RTS_CTS -- ^Request-To-Send \/ Clear-To-Send
              | DTR_DSR -- ^Data-Terminal-Ready \/ Data-Set-Ready
              | XOnXOff -- ^Transmitter on \/ Transmitter off

marshalFlowControl :: FlowCtrl -> Word16
marshalFlowControl :: FlowCtrl -> Word16
marshalFlowControl FlowCtrl
f = case FlowCtrl
f of
                         FlowCtrl
RTS_CTS -> Word16
0x0100
                         FlowCtrl
DTR_DSR -> Word16
0x0200
                         FlowCtrl
XOnXOff -> Word16
0x0400

-- |Set the flow control for the FTDI chip. Use 'Nothing' to disable flow
-- control.
setFlowControl :: InterfaceHandle -> Maybe FlowCtrl -> IO ()
setFlowControl :: InterfaceHandle -> Maybe FlowCtrl -> IO ()
setFlowControl InterfaceHandle
ifHnd Maybe FlowCtrl
mFC = USBControl (IO ())
-> Word16 -> InterfaceHandle -> Word8 -> Word16 -> IO ()
forall a.
USBControl a -> Word16 -> InterfaceHandle -> Word8 -> Word16 -> a
genControl USBControl (IO ())
USB.control
                                      (Word16 -> (FlowCtrl -> Word16) -> Maybe FlowCtrl -> Word16
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word16
0 FlowCtrl -> Word16
marshalFlowControl Maybe FlowCtrl
mFC)
                                      InterfaceHandle
ifHnd
                                      Word8
reqSetFlowCtrl
                                      Word16
0

-- |Set DTR line.
setDTR :: InterfaceHandle -> Bool -> IO ()
setDTR :: InterfaceHandle -> Bool -> IO ()
setDTR InterfaceHandle
ifHnd Bool
b = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqSetModemCtrl
               (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ if Bool
b then Word16
valSetDTRHigh else Word16
valSetDTRLow

-- |Set RTS line.
setRTS :: InterfaceHandle -> Bool -> IO ()
setRTS :: InterfaceHandle -> Bool -> IO ()
setRTS InterfaceHandle
ifHnd Bool
b = InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
reqSetModemCtrl
               (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ if Bool
b then Word16
valSetRTSHigh else Word16
valSetRTSLow

genSetCharacter :: RequestCode -> InterfaceHandle -> Maybe Word8 -> IO ()
genSetCharacter :: Word8 -> InterfaceHandle -> Maybe Word8 -> IO ()
genSetCharacter Word8
req InterfaceHandle
ifHnd Maybe Word8
mEC =
    InterfaceHandle -> Word8 -> Word16 -> IO ()
control InterfaceHandle
ifHnd Word8
req (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ Word16 -> (Word8 -> Word16) -> Maybe Word8 -> Word16
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word16
0 (\Word8
c -> Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
setBit (Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
c) Int
8) Maybe Word8
mEC

-- |Set the special event character. Use 'Nothing' to disable the event
-- character.
setEventCharacter :: InterfaceHandle -> Maybe Word8 -> IO ()
setEventCharacter :: InterfaceHandle -> Maybe Word8 -> IO ()
setEventCharacter = Word8 -> InterfaceHandle -> Maybe Word8 -> IO ()
genSetCharacter Word8
reqSetEventChar

-- |Set the error character.  Use 'Nothing' to disable the error character.
setErrorCharacter :: InterfaceHandle -> Maybe Word8 -> IO ()
setErrorCharacter :: InterfaceHandle -> Maybe Word8 -> IO ()
setErrorCharacter = Word8 -> InterfaceHandle -> Maybe Word8 -> IO ()
genSetCharacter Word8
reqSetErrorChar


-------------------------------------------------------------------------------
-- Baud rate
-------------------------------------------------------------------------------

newtype BRDiv a = BRDiv {forall a. BRDiv a -> a
unBRDiv :: a}
    deriving ( BRDiv a -> BRDiv a -> Bool
(BRDiv a -> BRDiv a -> Bool)
-> (BRDiv a -> BRDiv a -> Bool) -> Eq (BRDiv a)
forall a. Eq a => BRDiv a -> BRDiv a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => BRDiv a -> BRDiv a -> Bool
== :: BRDiv a -> BRDiv a -> Bool
$c/= :: forall a. Eq a => BRDiv a -> BRDiv a -> Bool
/= :: BRDiv a -> BRDiv a -> Bool
Eq, Eq (BRDiv a)
Eq (BRDiv a) =>
(BRDiv a -> BRDiv a -> Ordering)
-> (BRDiv a -> BRDiv a -> Bool)
-> (BRDiv a -> BRDiv a -> Bool)
-> (BRDiv a -> BRDiv a -> Bool)
-> (BRDiv a -> BRDiv a -> Bool)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> Ord (BRDiv a)
BRDiv a -> BRDiv a -> Bool
BRDiv a -> BRDiv a -> Ordering
BRDiv a -> BRDiv a -> BRDiv a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (BRDiv a)
forall a. Ord a => BRDiv a -> BRDiv a -> Bool
forall a. Ord a => BRDiv a -> BRDiv a -> Ordering
forall a. Ord a => BRDiv a -> BRDiv a -> BRDiv a
$ccompare :: forall a. Ord a => BRDiv a -> BRDiv a -> Ordering
compare :: BRDiv a -> BRDiv a -> Ordering
$c< :: forall a. Ord a => BRDiv a -> BRDiv a -> Bool
< :: BRDiv a -> BRDiv a -> Bool
$c<= :: forall a. Ord a => BRDiv a -> BRDiv a -> Bool
<= :: BRDiv a -> BRDiv a -> Bool
$c> :: forall a. Ord a => BRDiv a -> BRDiv a -> Bool
> :: BRDiv a -> BRDiv a -> Bool
$c>= :: forall a. Ord a => BRDiv a -> BRDiv a -> Bool
>= :: BRDiv a -> BRDiv a -> Bool
$cmax :: forall a. Ord a => BRDiv a -> BRDiv a -> BRDiv a
max :: BRDiv a -> BRDiv a -> BRDiv a
$cmin :: forall a. Ord a => BRDiv a -> BRDiv a -> BRDiv a
min :: BRDiv a -> BRDiv a -> BRDiv a
Ord, Int -> BRDiv a -> ShowS
[BRDiv a] -> ShowS
BRDiv a -> String
(Int -> BRDiv a -> ShowS)
-> (BRDiv a -> String) -> ([BRDiv a] -> ShowS) -> Show (BRDiv a)
forall a. Show a => Int -> BRDiv a -> ShowS
forall a. Show a => [BRDiv a] -> ShowS
forall a. Show a => BRDiv a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> BRDiv a -> ShowS
showsPrec :: Int -> BRDiv a -> ShowS
$cshow :: forall a. Show a => BRDiv a -> String
show :: BRDiv a -> String
$cshowList :: forall a. Show a => [BRDiv a] -> ShowS
showList :: [BRDiv a] -> ShowS
Show, ReadPrec [BRDiv a]
ReadPrec (BRDiv a)
Int -> ReadS (BRDiv a)
ReadS [BRDiv a]
(Int -> ReadS (BRDiv a))
-> ReadS [BRDiv a]
-> ReadPrec (BRDiv a)
-> ReadPrec [BRDiv a]
-> Read (BRDiv a)
forall a. Read a => ReadPrec [BRDiv a]
forall a. Read a => ReadPrec (BRDiv a)
forall a. Read a => Int -> ReadS (BRDiv a)
forall a. Read a => ReadS [BRDiv a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (BRDiv a)
readsPrec :: Int -> ReadS (BRDiv a)
$creadList :: forall a. Read a => ReadS [BRDiv a]
readList :: ReadS [BRDiv a]
$creadPrec :: forall a. Read a => ReadPrec (BRDiv a)
readPrec :: ReadPrec (BRDiv a)
$creadListPrec :: forall a. Read a => ReadPrec [BRDiv a]
readListPrec :: ReadPrec [BRDiv a]
Read, Int -> BRDiv a
BRDiv a -> Int
BRDiv a -> [BRDiv a]
BRDiv a -> BRDiv a
BRDiv a -> BRDiv a -> [BRDiv a]
BRDiv a -> BRDiv a -> BRDiv a -> [BRDiv a]
(BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a)
-> (Int -> BRDiv a)
-> (BRDiv a -> Int)
-> (BRDiv a -> [BRDiv a])
-> (BRDiv a -> BRDiv a -> [BRDiv a])
-> (BRDiv a -> BRDiv a -> [BRDiv a])
-> (BRDiv a -> BRDiv a -> BRDiv a -> [BRDiv a])
-> Enum (BRDiv a)
forall a. Enum a => Int -> BRDiv a
forall a. Enum a => BRDiv a -> Int
forall a. Enum a => BRDiv a -> [BRDiv a]
forall a. Enum a => BRDiv a -> BRDiv a
forall a. Enum a => BRDiv a -> BRDiv a -> [BRDiv a]
forall a. Enum a => BRDiv a -> BRDiv a -> BRDiv a -> [BRDiv a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => BRDiv a -> BRDiv a
succ :: BRDiv a -> BRDiv a
$cpred :: forall a. Enum a => BRDiv a -> BRDiv a
pred :: BRDiv a -> BRDiv a
$ctoEnum :: forall a. Enum a => Int -> BRDiv a
toEnum :: Int -> BRDiv a
$cfromEnum :: forall a. Enum a => BRDiv a -> Int
fromEnum :: BRDiv a -> Int
$cenumFrom :: forall a. Enum a => BRDiv a -> [BRDiv a]
enumFrom :: BRDiv a -> [BRDiv a]
$cenumFromThen :: forall a. Enum a => BRDiv a -> BRDiv a -> [BRDiv a]
enumFromThen :: BRDiv a -> BRDiv a -> [BRDiv a]
$cenumFromTo :: forall a. Enum a => BRDiv a -> BRDiv a -> [BRDiv a]
enumFromTo :: BRDiv a -> BRDiv a -> [BRDiv a]
$cenumFromThenTo :: forall a. Enum a => BRDiv a -> BRDiv a -> BRDiv a -> [BRDiv a]
enumFromThenTo :: BRDiv a -> BRDiv a -> BRDiv a -> [BRDiv a]
Enum, Integer -> BRDiv a
BRDiv a -> BRDiv a
BRDiv a -> BRDiv a -> BRDiv a
(BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a)
-> (Integer -> BRDiv a)
-> Num (BRDiv a)
forall a. Num a => Integer -> BRDiv a
forall a. Num a => BRDiv a -> BRDiv a
forall a. Num a => BRDiv a -> BRDiv a -> BRDiv a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: forall a. Num a => BRDiv a -> BRDiv a -> BRDiv a
+ :: BRDiv a -> BRDiv a -> BRDiv a
$c- :: forall a. Num a => BRDiv a -> BRDiv a -> BRDiv a
- :: BRDiv a -> BRDiv a -> BRDiv a
$c* :: forall a. Num a => BRDiv a -> BRDiv a -> BRDiv a
* :: BRDiv a -> BRDiv a -> BRDiv a
$cnegate :: forall a. Num a => BRDiv a -> BRDiv a
negate :: BRDiv a -> BRDiv a
$cabs :: forall a. Num a => BRDiv a -> BRDiv a
abs :: BRDiv a -> BRDiv a
$csignum :: forall a. Num a => BRDiv a -> BRDiv a
signum :: BRDiv a -> BRDiv a
$cfromInteger :: forall a. Num a => Integer -> BRDiv a
fromInteger :: Integer -> BRDiv a
Num, Enum (BRDiv a)
Real (BRDiv a)
(Real (BRDiv a), Enum (BRDiv a)) =>
(BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a))
-> (BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a))
-> (BRDiv a -> Integer)
-> Integral (BRDiv a)
BRDiv a -> Integer
BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a)
BRDiv a -> BRDiv a -> BRDiv a
forall a. Integral a => Enum (BRDiv a)
forall a. Integral a => Real (BRDiv a)
forall a. Integral a => BRDiv a -> Integer
forall a. Integral a => BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a)
forall a. Integral a => BRDiv a -> BRDiv a -> BRDiv a
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: forall a. Integral a => BRDiv a -> BRDiv a -> BRDiv a
quot :: BRDiv a -> BRDiv a -> BRDiv a
$crem :: forall a. Integral a => BRDiv a -> BRDiv a -> BRDiv a
rem :: BRDiv a -> BRDiv a -> BRDiv a
$cdiv :: forall a. Integral a => BRDiv a -> BRDiv a -> BRDiv a
div :: BRDiv a -> BRDiv a -> BRDiv a
$cmod :: forall a. Integral a => BRDiv a -> BRDiv a -> BRDiv a
mod :: BRDiv a -> BRDiv a -> BRDiv a
$cquotRem :: forall a. Integral a => BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a)
quotRem :: BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a)
$cdivMod :: forall a. Integral a => BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a)
divMod :: BRDiv a -> BRDiv a -> (BRDiv a, BRDiv a)
$ctoInteger :: forall a. Integral a => BRDiv a -> Integer
toInteger :: BRDiv a -> Integer
Integral
             , Num (BRDiv a)
Ord (BRDiv a)
(Num (BRDiv a), Ord (BRDiv a)) =>
(BRDiv a -> Rational) -> Real (BRDiv a)
BRDiv a -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
forall a. Real a => Num (BRDiv a)
forall a. Real a => Ord (BRDiv a)
forall a. Real a => BRDiv a -> Rational
$ctoRational :: forall a. Real a => BRDiv a -> Rational
toRational :: BRDiv a -> Rational
Real, Num (BRDiv a)
Num (BRDiv a) =>
(BRDiv a -> BRDiv a -> BRDiv a)
-> (BRDiv a -> BRDiv a)
-> (Rational -> BRDiv a)
-> Fractional (BRDiv a)
Rational -> BRDiv a
BRDiv a -> BRDiv a
BRDiv a -> BRDiv a -> BRDiv a
forall a. Fractional a => Num (BRDiv a)
forall a. Fractional a => Rational -> BRDiv a
forall a. Fractional a => BRDiv a -> BRDiv a
forall a. Fractional a => BRDiv a -> BRDiv a -> BRDiv a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: forall a. Fractional a => BRDiv a -> BRDiv a -> BRDiv a
/ :: BRDiv a -> BRDiv a -> BRDiv a
$crecip :: forall a. Fractional a => BRDiv a -> BRDiv a
recip :: BRDiv a -> BRDiv a
$cfromRational :: forall a. Fractional a => Rational -> BRDiv a
fromRational :: Rational -> BRDiv a
Fractional, Fractional (BRDiv a)
Real (BRDiv a)
(Real (BRDiv a), Fractional (BRDiv a)) =>
(forall b. Integral b => BRDiv a -> (b, BRDiv a))
-> (forall b. Integral b => BRDiv a -> b)
-> (forall b. Integral b => BRDiv a -> b)
-> (forall b. Integral b => BRDiv a -> b)
-> (forall b. Integral b => BRDiv a -> b)
-> RealFrac (BRDiv a)
forall b. Integral b => BRDiv a -> b
forall b. Integral b => BRDiv a -> (b, BRDiv a)
forall a.
(Real a, Fractional a) =>
(forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
forall a. RealFrac a => Fractional (BRDiv a)
forall a. RealFrac a => Real (BRDiv a)
forall a b. (RealFrac a, Integral b) => BRDiv a -> b
forall a b. (RealFrac a, Integral b) => BRDiv a -> (b, BRDiv a)
$cproperFraction :: forall a b. (RealFrac a, Integral b) => BRDiv a -> (b, BRDiv a)
properFraction :: forall b. Integral b => BRDiv a -> (b, BRDiv a)
$ctruncate :: forall a b. (RealFrac a, Integral b) => BRDiv a -> b
truncate :: forall b. Integral b => BRDiv a -> b
$cround :: forall a b. (RealFrac a, Integral b) => BRDiv a -> b
round :: forall b. Integral b => BRDiv a -> b
$cceiling :: forall a b. (RealFrac a, Integral b) => BRDiv a -> b
ceiling :: forall b. Integral b => BRDiv a -> b
$cfloor :: forall a b. (RealFrac a, Integral b) => BRDiv a -> b
floor :: forall b. Integral b => BRDiv a -> b
RealFrac
             )

instance Num a => Bounded (BRDiv a) where
    minBound :: BRDiv a
minBound = BRDiv a
0
    maxBound :: BRDiv a
maxBound = BRDiv a
2 BRDiv a -> Int -> BRDiv a
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
14 :: Int) BRDiv a -> BRDiv a -> BRDiv a
forall a. Num a => a -> a -> a
- BRDiv a
1

newtype BRSubDiv a = BRSubDiv {forall a. BRSubDiv a -> a
unBRSubDiv :: a}
    deriving ( BRSubDiv a -> BRSubDiv a -> Bool
(BRSubDiv a -> BRSubDiv a -> Bool)
-> (BRSubDiv a -> BRSubDiv a -> Bool) -> Eq (BRSubDiv a)
forall a. Eq a => BRSubDiv a -> BRSubDiv a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => BRSubDiv a -> BRSubDiv a -> Bool
== :: BRSubDiv a -> BRSubDiv a -> Bool
$c/= :: forall a. Eq a => BRSubDiv a -> BRSubDiv a -> Bool
/= :: BRSubDiv a -> BRSubDiv a -> Bool
Eq, Eq (BRSubDiv a)
Eq (BRSubDiv a) =>
(BRSubDiv a -> BRSubDiv a -> Ordering)
-> (BRSubDiv a -> BRSubDiv a -> Bool)
-> (BRSubDiv a -> BRSubDiv a -> Bool)
-> (BRSubDiv a -> BRSubDiv a -> Bool)
-> (BRSubDiv a -> BRSubDiv a -> Bool)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> Ord (BRSubDiv a)
BRSubDiv a -> BRSubDiv a -> Bool
BRSubDiv a -> BRSubDiv a -> Ordering
BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (BRSubDiv a)
forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Bool
forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Ordering
forall a. Ord a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$ccompare :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Ordering
compare :: BRSubDiv a -> BRSubDiv a -> Ordering
$c< :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Bool
< :: BRSubDiv a -> BRSubDiv a -> Bool
$c<= :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Bool
<= :: BRSubDiv a -> BRSubDiv a -> Bool
$c> :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Bool
> :: BRSubDiv a -> BRSubDiv a -> Bool
$c>= :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> Bool
>= :: BRSubDiv a -> BRSubDiv a -> Bool
$cmax :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
max :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$cmin :: forall a. Ord a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
min :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
Ord, Int -> BRSubDiv a -> ShowS
[BRSubDiv a] -> ShowS
BRSubDiv a -> String
(Int -> BRSubDiv a -> ShowS)
-> (BRSubDiv a -> String)
-> ([BRSubDiv a] -> ShowS)
-> Show (BRSubDiv a)
forall a. Show a => Int -> BRSubDiv a -> ShowS
forall a. Show a => [BRSubDiv a] -> ShowS
forall a. Show a => BRSubDiv a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> BRSubDiv a -> ShowS
showsPrec :: Int -> BRSubDiv a -> ShowS
$cshow :: forall a. Show a => BRSubDiv a -> String
show :: BRSubDiv a -> String
$cshowList :: forall a. Show a => [BRSubDiv a] -> ShowS
showList :: [BRSubDiv a] -> ShowS
Show, ReadPrec [BRSubDiv a]
ReadPrec (BRSubDiv a)
Int -> ReadS (BRSubDiv a)
ReadS [BRSubDiv a]
(Int -> ReadS (BRSubDiv a))
-> ReadS [BRSubDiv a]
-> ReadPrec (BRSubDiv a)
-> ReadPrec [BRSubDiv a]
-> Read (BRSubDiv a)
forall a. Read a => ReadPrec [BRSubDiv a]
forall a. Read a => ReadPrec (BRSubDiv a)
forall a. Read a => Int -> ReadS (BRSubDiv a)
forall a. Read a => ReadS [BRSubDiv a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (BRSubDiv a)
readsPrec :: Int -> ReadS (BRSubDiv a)
$creadList :: forall a. Read a => ReadS [BRSubDiv a]
readList :: ReadS [BRSubDiv a]
$creadPrec :: forall a. Read a => ReadPrec (BRSubDiv a)
readPrec :: ReadPrec (BRSubDiv a)
$creadListPrec :: forall a. Read a => ReadPrec [BRSubDiv a]
readListPrec :: ReadPrec [BRSubDiv a]
Read, Int -> BRSubDiv a
BRSubDiv a -> Int
BRSubDiv a -> [BRSubDiv a]
BRSubDiv a -> BRSubDiv a
BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
BRSubDiv a -> BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
(BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a)
-> (Int -> BRSubDiv a)
-> (BRSubDiv a -> Int)
-> (BRSubDiv a -> [BRSubDiv a])
-> (BRSubDiv a -> BRSubDiv a -> [BRSubDiv a])
-> (BRSubDiv a -> BRSubDiv a -> [BRSubDiv a])
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a -> [BRSubDiv a])
-> Enum (BRSubDiv a)
forall a. Enum a => Int -> BRSubDiv a
forall a. Enum a => BRSubDiv a -> Int
forall a. Enum a => BRSubDiv a -> [BRSubDiv a]
forall a. Enum a => BRSubDiv a -> BRSubDiv a
forall a. Enum a => BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
forall a.
Enum a =>
BRSubDiv a -> BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => BRSubDiv a -> BRSubDiv a
succ :: BRSubDiv a -> BRSubDiv a
$cpred :: forall a. Enum a => BRSubDiv a -> BRSubDiv a
pred :: BRSubDiv a -> BRSubDiv a
$ctoEnum :: forall a. Enum a => Int -> BRSubDiv a
toEnum :: Int -> BRSubDiv a
$cfromEnum :: forall a. Enum a => BRSubDiv a -> Int
fromEnum :: BRSubDiv a -> Int
$cenumFrom :: forall a. Enum a => BRSubDiv a -> [BRSubDiv a]
enumFrom :: BRSubDiv a -> [BRSubDiv a]
$cenumFromThen :: forall a. Enum a => BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
enumFromThen :: BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
$cenumFromTo :: forall a. Enum a => BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
enumFromTo :: BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
$cenumFromThenTo :: forall a.
Enum a =>
BRSubDiv a -> BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
enumFromThenTo :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a -> [BRSubDiv a]
Enum, Integer -> BRSubDiv a
BRSubDiv a -> BRSubDiv a
BRSubDiv a -> BRSubDiv a -> BRSubDiv a
(BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a)
-> (Integer -> BRSubDiv a)
-> Num (BRSubDiv a)
forall a. Num a => Integer -> BRSubDiv a
forall a. Num a => BRSubDiv a -> BRSubDiv a
forall a. Num a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: forall a. Num a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
+ :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$c- :: forall a. Num a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
- :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$c* :: forall a. Num a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
* :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$cnegate :: forall a. Num a => BRSubDiv a -> BRSubDiv a
negate :: BRSubDiv a -> BRSubDiv a
$cabs :: forall a. Num a => BRSubDiv a -> BRSubDiv a
abs :: BRSubDiv a -> BRSubDiv a
$csignum :: forall a. Num a => BRSubDiv a -> BRSubDiv a
signum :: BRSubDiv a -> BRSubDiv a
$cfromInteger :: forall a. Num a => Integer -> BRSubDiv a
fromInteger :: Integer -> BRSubDiv a
Num, Enum (BRSubDiv a)
Real (BRSubDiv a)
(Real (BRSubDiv a), Enum (BRSubDiv a)) =>
(BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a))
-> (BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a))
-> (BRSubDiv a -> Integer)
-> Integral (BRSubDiv a)
BRSubDiv a -> Integer
BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a)
BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a. Integral a => Enum (BRSubDiv a)
forall a. Integral a => Real (BRSubDiv a)
forall a. Integral a => BRSubDiv a -> Integer
forall a.
Integral a =>
BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a)
forall a. Integral a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: forall a. Integral a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
quot :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$crem :: forall a. Integral a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
rem :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$cdiv :: forall a. Integral a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
div :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$cmod :: forall a. Integral a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
mod :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$cquotRem :: forall a.
Integral a =>
BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a)
quotRem :: BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a)
$cdivMod :: forall a.
Integral a =>
BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a)
divMod :: BRSubDiv a -> BRSubDiv a -> (BRSubDiv a, BRSubDiv a)
$ctoInteger :: forall a. Integral a => BRSubDiv a -> Integer
toInteger :: BRSubDiv a -> Integer
Integral
             , Num (BRSubDiv a)
Ord (BRSubDiv a)
(Num (BRSubDiv a), Ord (BRSubDiv a)) =>
(BRSubDiv a -> Rational) -> Real (BRSubDiv a)
BRSubDiv a -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
forall a. Real a => Num (BRSubDiv a)
forall a. Real a => Ord (BRSubDiv a)
forall a. Real a => BRSubDiv a -> Rational
$ctoRational :: forall a. Real a => BRSubDiv a -> Rational
toRational :: BRSubDiv a -> Rational
Real, Num (BRSubDiv a)
Num (BRSubDiv a) =>
(BRSubDiv a -> BRSubDiv a -> BRSubDiv a)
-> (BRSubDiv a -> BRSubDiv a)
-> (Rational -> BRSubDiv a)
-> Fractional (BRSubDiv a)
Rational -> BRSubDiv a
BRSubDiv a -> BRSubDiv a
BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a. Fractional a => Num (BRSubDiv a)
forall a. Fractional a => Rational -> BRSubDiv a
forall a. Fractional a => BRSubDiv a -> BRSubDiv a
forall a. Fractional a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: forall a. Fractional a => BRSubDiv a -> BRSubDiv a -> BRSubDiv a
/ :: BRSubDiv a -> BRSubDiv a -> BRSubDiv a
$crecip :: forall a. Fractional a => BRSubDiv a -> BRSubDiv a
recip :: BRSubDiv a -> BRSubDiv a
$cfromRational :: forall a. Fractional a => Rational -> BRSubDiv a
fromRational :: Rational -> BRSubDiv a
Fractional, Fractional (BRSubDiv a)
Real (BRSubDiv a)
(Real (BRSubDiv a), Fractional (BRSubDiv a)) =>
(forall b. Integral b => BRSubDiv a -> (b, BRSubDiv a))
-> (forall b. Integral b => BRSubDiv a -> b)
-> (forall b. Integral b => BRSubDiv a -> b)
-> (forall b. Integral b => BRSubDiv a -> b)
-> (forall b. Integral b => BRSubDiv a -> b)
-> RealFrac (BRSubDiv a)
forall b. Integral b => BRSubDiv a -> b
forall b. Integral b => BRSubDiv a -> (b, BRSubDiv a)
forall a.
(Real a, Fractional a) =>
(forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
forall a. RealFrac a => Fractional (BRSubDiv a)
forall a. RealFrac a => Real (BRSubDiv a)
forall a b. (RealFrac a, Integral b) => BRSubDiv a -> b
forall a b.
(RealFrac a, Integral b) =>
BRSubDiv a -> (b, BRSubDiv a)
$cproperFraction :: forall a b.
(RealFrac a, Integral b) =>
BRSubDiv a -> (b, BRSubDiv a)
properFraction :: forall b. Integral b => BRSubDiv a -> (b, BRSubDiv a)
$ctruncate :: forall a b. (RealFrac a, Integral b) => BRSubDiv a -> b
truncate :: forall b. Integral b => BRSubDiv a -> b
$cround :: forall a b. (RealFrac a, Integral b) => BRSubDiv a -> b
round :: forall b. Integral b => BRSubDiv a -> b
$cceiling :: forall a b. (RealFrac a, Integral b) => BRSubDiv a -> b
ceiling :: forall b. Integral b => BRSubDiv a -> b
$cfloor :: forall a b. (RealFrac a, Integral b) => BRSubDiv a -> b
floor :: forall b. Integral b => BRSubDiv a -> b
RealFrac
             )

instance Num a => Bounded (BRSubDiv a) where
    minBound :: BRSubDiv a
minBound = BRSubDiv a
0
    maxBound :: BRSubDiv a
maxBound = BRSubDiv a
7

-- |Representation of a baud rate. The most interesting part is the
-- instance for 'Bounded'.
newtype BaudRate a = BaudRate {forall a. BaudRate a -> a
unBaudRate :: a}
    deriving ( BaudRate a -> BaudRate a -> Bool
(BaudRate a -> BaudRate a -> Bool)
-> (BaudRate a -> BaudRate a -> Bool) -> Eq (BaudRate a)
forall a. Eq a => BaudRate a -> BaudRate a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => BaudRate a -> BaudRate a -> Bool
== :: BaudRate a -> BaudRate a -> Bool
$c/= :: forall a. Eq a => BaudRate a -> BaudRate a -> Bool
/= :: BaudRate a -> BaudRate a -> Bool
Eq, Eq (BaudRate a)
Eq (BaudRate a) =>
(BaudRate a -> BaudRate a -> Ordering)
-> (BaudRate a -> BaudRate a -> Bool)
-> (BaudRate a -> BaudRate a -> Bool)
-> (BaudRate a -> BaudRate a -> Bool)
-> (BaudRate a -> BaudRate a -> Bool)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> Ord (BaudRate a)
BaudRate a -> BaudRate a -> Bool
BaudRate a -> BaudRate a -> Ordering
BaudRate a -> BaudRate a -> BaudRate a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (BaudRate a)
forall a. Ord a => BaudRate a -> BaudRate a -> Bool
forall a. Ord a => BaudRate a -> BaudRate a -> Ordering
forall a. Ord a => BaudRate a -> BaudRate a -> BaudRate a
$ccompare :: forall a. Ord a => BaudRate a -> BaudRate a -> Ordering
compare :: BaudRate a -> BaudRate a -> Ordering
$c< :: forall a. Ord a => BaudRate a -> BaudRate a -> Bool
< :: BaudRate a -> BaudRate a -> Bool
$c<= :: forall a. Ord a => BaudRate a -> BaudRate a -> Bool
<= :: BaudRate a -> BaudRate a -> Bool
$c> :: forall a. Ord a => BaudRate a -> BaudRate a -> Bool
> :: BaudRate a -> BaudRate a -> Bool
$c>= :: forall a. Ord a => BaudRate a -> BaudRate a -> Bool
>= :: BaudRate a -> BaudRate a -> Bool
$cmax :: forall a. Ord a => BaudRate a -> BaudRate a -> BaudRate a
max :: BaudRate a -> BaudRate a -> BaudRate a
$cmin :: forall a. Ord a => BaudRate a -> BaudRate a -> BaudRate a
min :: BaudRate a -> BaudRate a -> BaudRate a
Ord, Int -> BaudRate a -> ShowS
[BaudRate a] -> ShowS
BaudRate a -> String
(Int -> BaudRate a -> ShowS)
-> (BaudRate a -> String)
-> ([BaudRate a] -> ShowS)
-> Show (BaudRate a)
forall a. Show a => Int -> BaudRate a -> ShowS
forall a. Show a => [BaudRate a] -> ShowS
forall a. Show a => BaudRate a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> BaudRate a -> ShowS
showsPrec :: Int -> BaudRate a -> ShowS
$cshow :: forall a. Show a => BaudRate a -> String
show :: BaudRate a -> String
$cshowList :: forall a. Show a => [BaudRate a] -> ShowS
showList :: [BaudRate a] -> ShowS
Show, ReadPrec [BaudRate a]
ReadPrec (BaudRate a)
Int -> ReadS (BaudRate a)
ReadS [BaudRate a]
(Int -> ReadS (BaudRate a))
-> ReadS [BaudRate a]
-> ReadPrec (BaudRate a)
-> ReadPrec [BaudRate a]
-> Read (BaudRate a)
forall a. Read a => ReadPrec [BaudRate a]
forall a. Read a => ReadPrec (BaudRate a)
forall a. Read a => Int -> ReadS (BaudRate a)
forall a. Read a => ReadS [BaudRate a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (BaudRate a)
readsPrec :: Int -> ReadS (BaudRate a)
$creadList :: forall a. Read a => ReadS [BaudRate a]
readList :: ReadS [BaudRate a]
$creadPrec :: forall a. Read a => ReadPrec (BaudRate a)
readPrec :: ReadPrec (BaudRate a)
$creadListPrec :: forall a. Read a => ReadPrec [BaudRate a]
readListPrec :: ReadPrec [BaudRate a]
Read, Int -> BaudRate a
BaudRate a -> Int
BaudRate a -> [BaudRate a]
BaudRate a -> BaudRate a
BaudRate a -> BaudRate a -> [BaudRate a]
BaudRate a -> BaudRate a -> BaudRate a -> [BaudRate a]
(BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a)
-> (Int -> BaudRate a)
-> (BaudRate a -> Int)
-> (BaudRate a -> [BaudRate a])
-> (BaudRate a -> BaudRate a -> [BaudRate a])
-> (BaudRate a -> BaudRate a -> [BaudRate a])
-> (BaudRate a -> BaudRate a -> BaudRate a -> [BaudRate a])
-> Enum (BaudRate a)
forall a. Enum a => Int -> BaudRate a
forall a. Enum a => BaudRate a -> Int
forall a. Enum a => BaudRate a -> [BaudRate a]
forall a. Enum a => BaudRate a -> BaudRate a
forall a. Enum a => BaudRate a -> BaudRate a -> [BaudRate a]
forall a.
Enum a =>
BaudRate a -> BaudRate a -> BaudRate a -> [BaudRate a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => BaudRate a -> BaudRate a
succ :: BaudRate a -> BaudRate a
$cpred :: forall a. Enum a => BaudRate a -> BaudRate a
pred :: BaudRate a -> BaudRate a
$ctoEnum :: forall a. Enum a => Int -> BaudRate a
toEnum :: Int -> BaudRate a
$cfromEnum :: forall a. Enum a => BaudRate a -> Int
fromEnum :: BaudRate a -> Int
$cenumFrom :: forall a. Enum a => BaudRate a -> [BaudRate a]
enumFrom :: BaudRate a -> [BaudRate a]
$cenumFromThen :: forall a. Enum a => BaudRate a -> BaudRate a -> [BaudRate a]
enumFromThen :: BaudRate a -> BaudRate a -> [BaudRate a]
$cenumFromTo :: forall a. Enum a => BaudRate a -> BaudRate a -> [BaudRate a]
enumFromTo :: BaudRate a -> BaudRate a -> [BaudRate a]
$cenumFromThenTo :: forall a.
Enum a =>
BaudRate a -> BaudRate a -> BaudRate a -> [BaudRate a]
enumFromThenTo :: BaudRate a -> BaudRate a -> BaudRate a -> [BaudRate a]
Enum, Integer -> BaudRate a
BaudRate a -> BaudRate a
BaudRate a -> BaudRate a -> BaudRate a
(BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a)
-> (Integer -> BaudRate a)
-> Num (BaudRate a)
forall a. Num a => Integer -> BaudRate a
forall a. Num a => BaudRate a -> BaudRate a
forall a. Num a => BaudRate a -> BaudRate a -> BaudRate a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: forall a. Num a => BaudRate a -> BaudRate a -> BaudRate a
+ :: BaudRate a -> BaudRate a -> BaudRate a
$c- :: forall a. Num a => BaudRate a -> BaudRate a -> BaudRate a
- :: BaudRate a -> BaudRate a -> BaudRate a
$c* :: forall a. Num a => BaudRate a -> BaudRate a -> BaudRate a
* :: BaudRate a -> BaudRate a -> BaudRate a
$cnegate :: forall a. Num a => BaudRate a -> BaudRate a
negate :: BaudRate a -> BaudRate a
$cabs :: forall a. Num a => BaudRate a -> BaudRate a
abs :: BaudRate a -> BaudRate a
$csignum :: forall a. Num a => BaudRate a -> BaudRate a
signum :: BaudRate a -> BaudRate a
$cfromInteger :: forall a. Num a => Integer -> BaudRate a
fromInteger :: Integer -> BaudRate a
Num, Enum (BaudRate a)
Real (BaudRate a)
(Real (BaudRate a), Enum (BaudRate a)) =>
(BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a))
-> (BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a))
-> (BaudRate a -> Integer)
-> Integral (BaudRate a)
BaudRate a -> Integer
BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a)
BaudRate a -> BaudRate a -> BaudRate a
forall a. Integral a => Enum (BaudRate a)
forall a. Integral a => Real (BaudRate a)
forall a. Integral a => BaudRate a -> Integer
forall a.
Integral a =>
BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a)
forall a. Integral a => BaudRate a -> BaudRate a -> BaudRate a
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: forall a. Integral a => BaudRate a -> BaudRate a -> BaudRate a
quot :: BaudRate a -> BaudRate a -> BaudRate a
$crem :: forall a. Integral a => BaudRate a -> BaudRate a -> BaudRate a
rem :: BaudRate a -> BaudRate a -> BaudRate a
$cdiv :: forall a. Integral a => BaudRate a -> BaudRate a -> BaudRate a
div :: BaudRate a -> BaudRate a -> BaudRate a
$cmod :: forall a. Integral a => BaudRate a -> BaudRate a -> BaudRate a
mod :: BaudRate a -> BaudRate a -> BaudRate a
$cquotRem :: forall a.
Integral a =>
BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a)
quotRem :: BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a)
$cdivMod :: forall a.
Integral a =>
BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a)
divMod :: BaudRate a -> BaudRate a -> (BaudRate a, BaudRate a)
$ctoInteger :: forall a. Integral a => BaudRate a -> Integer
toInteger :: BaudRate a -> Integer
Integral
             , Num (BaudRate a)
Ord (BaudRate a)
(Num (BaudRate a), Ord (BaudRate a)) =>
(BaudRate a -> Rational) -> Real (BaudRate a)
BaudRate a -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
forall a. Real a => Num (BaudRate a)
forall a. Real a => Ord (BaudRate a)
forall a. Real a => BaudRate a -> Rational
$ctoRational :: forall a. Real a => BaudRate a -> Rational
toRational :: BaudRate a -> Rational
Real, Num (BaudRate a)
Num (BaudRate a) =>
(BaudRate a -> BaudRate a -> BaudRate a)
-> (BaudRate a -> BaudRate a)
-> (Rational -> BaudRate a)
-> Fractional (BaudRate a)
Rational -> BaudRate a
BaudRate a -> BaudRate a
BaudRate a -> BaudRate a -> BaudRate a
forall a. Fractional a => Num (BaudRate a)
forall a. Fractional a => Rational -> BaudRate a
forall a. Fractional a => BaudRate a -> BaudRate a
forall a. Fractional a => BaudRate a -> BaudRate a -> BaudRate a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: forall a. Fractional a => BaudRate a -> BaudRate a -> BaudRate a
/ :: BaudRate a -> BaudRate a -> BaudRate a
$crecip :: forall a. Fractional a => BaudRate a -> BaudRate a
recip :: BaudRate a -> BaudRate a
$cfromRational :: forall a. Fractional a => Rational -> BaudRate a
fromRational :: Rational -> BaudRate a
Fractional, Fractional (BaudRate a)
Real (BaudRate a)
(Real (BaudRate a), Fractional (BaudRate a)) =>
(forall b. Integral b => BaudRate a -> (b, BaudRate a))
-> (forall b. Integral b => BaudRate a -> b)
-> (forall b. Integral b => BaudRate a -> b)
-> (forall b. Integral b => BaudRate a -> b)
-> (forall b. Integral b => BaudRate a -> b)
-> RealFrac (BaudRate a)
forall b. Integral b => BaudRate a -> b
forall b. Integral b => BaudRate a -> (b, BaudRate a)
forall a.
(Real a, Fractional a) =>
(forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
forall a. RealFrac a => Fractional (BaudRate a)
forall a. RealFrac a => Real (BaudRate a)
forall a b. (RealFrac a, Integral b) => BaudRate a -> b
forall a b.
(RealFrac a, Integral b) =>
BaudRate a -> (b, BaudRate a)
$cproperFraction :: forall a b.
(RealFrac a, Integral b) =>
BaudRate a -> (b, BaudRate a)
properFraction :: forall b. Integral b => BaudRate a -> (b, BaudRate a)
$ctruncate :: forall a b. (RealFrac a, Integral b) => BaudRate a -> b
truncate :: forall b. Integral b => BaudRate a -> b
$cround :: forall a b. (RealFrac a, Integral b) => BaudRate a -> b
round :: forall b. Integral b => BaudRate a -> b
$cceiling :: forall a b. (RealFrac a, Integral b) => BaudRate a -> b
ceiling :: forall b. Integral b => BaudRate a -> b
$cfloor :: forall a b. (RealFrac a, Integral b) => BaudRate a -> b
floor :: forall b. Integral b => BaudRate a -> b
RealFrac
             )

instance Num a => Bounded (BaudRate a) where
    -- Minimum baud rate is the maximum baudrate divided by the
    -- largest possible divider.
    minBound :: BaudRate a
minBound = BaudRate Integer -> BaudRate a
forall a b. (Integral a, Num b) => a -> b
fromIntegral
               (BaudRate Integer -> BaudRate a) -> BaudRate Integer -> BaudRate a
forall a b. (a -> b) -> a -> b
$ (BaudRate Double -> BaudRate Integer
forall b. Integral b => BaudRate Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling :: BaudRate Double -> BaudRate Integer)
               (BaudRate Double -> BaudRate Integer)
-> BaudRate Double -> BaudRate Integer
forall a b. (a -> b) -> a -> b
$ BRDiv Int -> BRSubDiv Double -> BaudRate Double
forall a.
(Eq a, Fractional a) =>
BRDiv Int -> BRSubDiv a -> BaudRate a
calcBaudRate BRDiv Int
forall a. Bounded a => a
maxBound BRSubDiv Double
forall a. Bounded a => a
maxBound

    maxBound :: BaudRate a
maxBound = a -> BaudRate a
forall a. a -> BaudRate a
BaudRate a
3000000

-- http://www.ftdichip.com/Documents/AppNotes/AN232B-05_BaudRates.pdf
encodeBaudRateDivisors :: ChipType -> BRDiv Int -> BRSubDiv Int -> (Word16, Word16)
encodeBaudRateDivisors :: ChipType -> BRDiv Int -> BRSubDiv Int -> (Word16, Word16)
encodeBaudRateDivisors ChipType
chip BRDiv Int
d BRSubDiv Int
s = (Word16
v, Word16
i)
  where
    v :: Word16
v = BRDiv Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral BRDiv Int
d Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftL Word16
s' Int
14
    i :: Word16
i | ChipType
ChipType_2232C <- ChipType
chip = Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftL (Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
s' Int
2) Int
8
      | Bool
otherwise = Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
s' Int
2
    s' :: Word16
s' = Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ BRSubDiv Int -> Int
encodeSubDiv BRSubDiv Int
s :: Word16

    encodeSubDiv :: BRSubDiv Int -> Int
    encodeSubDiv :: BRSubDiv Int -> Int
encodeSubDiv BRSubDiv Int
n =
        case BRSubDiv Int
n of
          BRSubDiv Int
0 -> Int
0 -- 000 ==> 0/8 = 0
          BRSubDiv Int
4 -> Int
1 -- 001 ==> 4/8 = 0.5
          BRSubDiv Int
2 -> Int
2 -- 010 ==> 2/8 = 0.25
          BRSubDiv Int
1 -> Int
3 -- 011 ==> 1/8 = 0.125
          BRSubDiv Int
3 -> Int
4 -- 100 ==> 3/8 = 0.375
          BRSubDiv Int
5 -> Int
5 -- 101 ==> 5/8 = 0.625
          BRSubDiv Int
6 -> Int
6 -- 110 ==> 6/8 = 0.75
          BRSubDiv Int
7 -> Int
7 -- 111 ==> 7/8 = 0.875
          BRSubDiv Int
_ -> String -> Int
forall a. HasCallStack => String -> a
error String
"Illegal subdivisor"

-- |Calculates the nearest representable baud rate.
nearestBaudRate :: RealFrac a => ChipType -> BaudRate a -> BaudRate a
nearestBaudRate :: forall a. RealFrac a => ChipType -> BaudRate a -> BaudRate a
nearestBaudRate ChipType
chip BaudRate a
baudRate = BaudRate a
b
  where (BRDiv Int
_, BRSubDiv Int
_, BaudRate a
b) = ChipType -> BaudRate a -> (BRDiv Int, BRSubDiv Int, BaudRate a)
forall a.
RealFrac a =>
ChipType -> BaudRate a -> (BRDiv Int, BRSubDiv Int, BaudRate a)
calcBaudRateDivisors ChipType
chip BaudRate a
baudRate


-- |Finds the divisors that most closely represent the requested baud rate.
calcBaudRateDivisors :: forall a. RealFrac a
                     => ChipType
                     -> BaudRate a
                     -> (BRDiv Int, BRSubDiv Int, BaudRate a)
calcBaudRateDivisors :: forall a.
RealFrac a =>
ChipType -> BaudRate a -> (BRDiv Int, BRSubDiv Int, BaudRate a)
calcBaudRateDivisors ChipType
_    BaudRate a
3000000  = (BRDiv Int
0, BRSubDiv Int
0, BaudRate a
0)
calcBaudRateDivisors ChipType
_    BaudRate a
2000000  = (BRDiv Int
1, BRSubDiv Int
0, BaudRate a
0)
calcBaudRateDivisors ChipType
chip BaudRate a
baudRate =
    ((BRDiv Int, BRSubDiv Int, BaudRate a)
 -> (BRDiv Int, BRSubDiv Int, BaudRate a) -> Ordering)
-> [(BRDiv Int, BRSubDiv Int, BaudRate a)]
-> (BRDiv Int, BRSubDiv Int, BaudRate a)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (BaudRate a -> BaudRate a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (BaudRate a -> BaudRate a -> Ordering)
-> ((BRDiv Int, BRSubDiv Int, BaudRate a) -> BaudRate a)
-> (BRDiv Int, BRSubDiv Int, BaudRate a)
-> (BRDiv Int, BRSubDiv Int, BaudRate a)
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (\(BRDiv Int
_,BRSubDiv Int
_,BaudRate a
x) -> BaudRate a
x))
              [ (BRDiv Int
d, BRSubDiv Int
s, BaudRate a
b')
              | BRSubDiv Int
s <- ChipType -> [BRSubDiv Int]
chipSubDivisors ChipType
chip
              , let s' :: BRSubDiv a
s' = BRSubDiv Int -> BRSubDiv a
forall a b. (Integral a, Num b) => a -> b
fromIntegral BRSubDiv Int
s BRSubDiv a -> BRSubDiv a -> BRSubDiv a
forall a. Fractional a => a -> a -> a
/ BRSubDiv a
8
                    d :: BRDiv Int
d  = BaudRate a -> BRSubDiv a -> BRDiv Int
forall b. Integral b => BaudRate a -> BRSubDiv a -> BRDiv b
divisor BaudRate a
baudRate BRSubDiv a
s'
                    -- Baud rate calculated from found divisors.
                    b' :: BaudRate a
b' = BRDiv Int -> BRSubDiv a -> BaudRate a
forall a.
(Eq a, Fractional a) =>
BRDiv Int -> BRSubDiv a -> BaudRate a
calcBaudRate BRDiv Int
d BRSubDiv a
s'
              ]
    where
      -- |Calculates the divisor from a baud rate and a subdivisor.
      divisor :: Integral b => BaudRate a -> BRSubDiv a -> BRDiv b
      divisor :: forall b. Integral b => BaudRate a -> BRSubDiv a -> BRDiv b
divisor BaudRate a
br BRSubDiv a
s = BRDiv b -> BRDiv b
forall a. (Bounded a, Ord a) => a -> a
clamp (BRDiv b -> BRDiv b) -> BRDiv b -> BRDiv b
forall a b. (a -> b) -> a -> b
$ BaudRate a -> BRDiv b
forall b. Integral b => BaudRate a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (BaudRate a -> BRDiv b) -> BaudRate a -> BRDiv b
forall a b. (a -> b) -> a -> b
$ (BaudRate a
forall a. Bounded a => a
maxBound BaudRate a -> BaudRate a -> BaudRate a
forall a. Num a => a -> a -> a
- BaudRate a
br BaudRate a -> BaudRate a -> BaudRate a
forall a. Num a => a -> a -> a
* BaudRate a
s') BaudRate a -> BaudRate a -> BaudRate a
forall a. Fractional a => a -> a -> a
/ BaudRate a
br
          where s' :: BaudRate a
s' = a -> BaudRate a
forall a. a -> BaudRate a
BaudRate (a -> BaudRate a) -> a -> BaudRate a
forall a b. (a -> b) -> a -> b
$ BRSubDiv a -> a
forall a. BRSubDiv a -> a
unBRSubDiv BRSubDiv a
s

      chipSubDivisors :: ChipType -> [BRSubDiv Int]
      chipSubDivisors :: ChipType -> [BRSubDiv Int]
chipSubDivisors ChipType
ChipType_AM = [BRSubDiv Int
0, BRSubDiv Int
1, BRSubDiv Int
2, BRSubDiv Int
4]
      chipSubDivisors ChipType
_           = [BRSubDiv Int
0..BRSubDiv Int
7]

-- |Calculates the baud rate from a divisor and a subdivisor.
calcBaudRate :: (Eq a, Fractional a) => BRDiv Int -> BRSubDiv a -> BaudRate a
calcBaudRate :: forall a.
(Eq a, Fractional a) =>
BRDiv Int -> BRSubDiv a -> BaudRate a
calcBaudRate BRDiv Int
0 BRSubDiv a
0 = BaudRate a
forall a. Bounded a => a
maxBound
calcBaudRate BRDiv Int
1 BRSubDiv a
0 = BaudRate a
2000000
calcBaudRate BRDiv Int
d BRSubDiv a
s = BaudRate a
forall a. Bounded a => a
maxBound BaudRate a -> BaudRate a -> BaudRate a
forall a. Fractional a => a -> a -> a
/ a -> BaudRate a
forall a. a -> BaudRate a
BaudRate (BRDiv Int -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac BRDiv Int
d a -> a -> a
forall a. Num a => a -> a -> a
+ BRSubDiv a -> a
forall a. BRSubDiv a -> a
unBRSubDiv BRSubDiv a
s)