packages feed

bus-pirate 0.5 → 0.6

raw patch · 5 files changed

+143/−32 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- System.Hardware.BusPirate.I2C: I2cConfig :: Bool -> Bool -> Bool -> Bool -> I2cConfig
- System.Hardware.BusPirate.I2C: data I2cConfig
- System.Hardware.BusPirate.I2C: i2cAux :: I2cConfig -> Bool
- System.Hardware.BusPirate.I2C: i2cChipSelect :: I2cConfig -> Bool
- System.Hardware.BusPirate.I2C: i2cPower :: I2cConfig -> Bool
- System.Hardware.BusPirate.I2C: i2cPullups :: I2cConfig -> Bool
- System.Hardware.BusPirate.I2C: instance Show I2cConfig
- System.Hardware.BusPirate.I2C: writeRead :: ByteString -> Int -> I2cM ByteString
+ System.Hardware.BusPirate: runI2c :: FilePath -> I2cM a -> IO (Either String a)
+ System.Hardware.BusPirate: runSpi :: FilePath -> SpiM a -> IO (Either String a)
+ System.Hardware.BusPirate.I2C: PConfig :: Bool -> Bool -> Bool -> Bool -> PeripheralConfig
+ System.Hardware.BusPirate.I2C: data PeripheralConfig
+ System.Hardware.BusPirate.I2C: perAux :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.I2C: perChipSelect :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.I2C: perPower :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.I2C: perPullups :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.SPI: PConfig :: Bool -> Bool -> Bool -> Bool -> PeripheralConfig
+ System.Hardware.BusPirate.SPI: Spi125KHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi1MHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi250KHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi2MHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi2_6MHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi30KHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi4MHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: Spi8MHz :: SpiSpeed
+ System.Hardware.BusPirate.SPI: bulkTransfer :: ByteString -> SpiM ByteString
+ System.Hardware.BusPirate.SPI: data PeripheralConfig
+ System.Hardware.BusPirate.SPI: data SpiM a
+ System.Hardware.BusPirate.SPI: data SpiSpeed
+ System.Hardware.BusPirate.SPI: instance Applicative SpiM
+ System.Hardware.BusPirate.SPI: instance Bounded SpiSpeed
+ System.Hardware.BusPirate.SPI: instance Enum SpiSpeed
+ System.Hardware.BusPirate.SPI: instance Eq SpiSpeed
+ System.Hardware.BusPirate.SPI: instance Functor SpiM
+ System.Hardware.BusPirate.SPI: instance Monad SpiM
+ System.Hardware.BusPirate.SPI: instance MonadIO SpiM
+ System.Hardware.BusPirate.SPI: instance Ord SpiSpeed
+ System.Hardware.BusPirate.SPI: instance Show SpiSpeed
+ System.Hardware.BusPirate.SPI: perAux :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.SPI: perChipSelect :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.SPI: perPower :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.SPI: perPullups :: PeripheralConfig -> Bool
+ System.Hardware.BusPirate.SPI: setCS :: Bool -> SpiM ()
+ System.Hardware.BusPirate.SPI: setConfig :: PeripheralConfig -> SpiM ()
+ System.Hardware.BusPirate.SPI: setSpeed :: SpiSpeed -> SpiM ()
+ System.Hardware.BusPirate.SPI: spiMode :: SpiM a -> BusPirateM a
- System.Hardware.BusPirate.I2C: setConfig :: I2cConfig -> I2cM ()
+ System.Hardware.BusPirate.I2C: setConfig :: PeripheralConfig -> I2cM ()

Files

System/Hardware/BusPirate.hs view
@@ -1,11 +1,13 @@ {-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}-                + module System.Hardware.BusPirate   ( -- * General     BusPirateM   , runBusPirate     -- * I2C mode-  , module System.Hardware.BusPirate.I2C+  , runI2c+    -- * SPI mode+  , runSpi   ) where  import Control.Monad (replicateM)@@ -17,3 +19,12 @@  import System.Hardware.BusPirate.Core import System.Hardware.BusPirate.I2C+import System.Hardware.BusPirate.SPI++-- | Convenient way to run an I2C action+runI2c :: FilePath -> I2cM a -> IO (Either String a)+runI2c path action = runBusPirate path $ i2cMode action++-- | Convenient way to run an I2C action+runSpi :: FilePath -> SpiM a -> IO (Either String a)+runSpi path action = runBusPirate path $ spiMode action
System/Hardware/BusPirate/Core.hs view
@@ -94,3 +94,22 @@      command :: Word8 -> BusPirateM () command cmd = commandExpect cmd "\x01"++data PeripheralConfig+    = PConfig { perPower      :: Bool+              , perPullups    :: Bool+              , perAux        :: Bool+              , perChipSelect :: Bool+              }+    deriving (Show)++setPeripherals :: PeripheralConfig -> BusPirateM ()+setPeripherals config = do+    command $ 0x40+            + bit 3 (perPower config)+            + bit 2 (perPullups config)+            + bit 1 (perAux config)+            + bit 0 (perChipSelect config)+  where+    bit n True = 2^n+    bit _ _    = 0
System/Hardware/BusPirate/I2C.hs view
@@ -11,9 +11,8 @@   , ackBit   , nackBit   , bulkWrite-  , writeRead     -- * Configuration-  , I2cConfig(..)+  , PeripheralConfig(..)   , setConfig   , I2cSpeed(..)   , setSpeed@@ -44,10 +43,13 @@  newtype I2cM a = I2cM (BusPirateM a)                deriving (Functor, Applicative, Monad, MonadIO)-        ++err :: String -> I2cM a+err = I2cM . BPM . left+ -- | Enter I2C mode and run given action i2cMode :: I2cM a -> BusPirateM a-i2cMode (I2cM m) = commandExpect 0x2 "I2C1" >>  m+i2cMode (I2cM m) = commandExpect 0x2 "I2C1" >> m  -- | Send a start bit startBit :: I2cM ()@@ -61,11 +63,11 @@ readByte :: I2cM Word8 readByte = I2cM $ putByte 0x4 >> getByte --- | Send an ACK +-- | Send an ACK ackBit :: I2cM () ackBit = I2cM $ command 0x6 --- | Send a NACK +-- | Send a NACK nackBit :: I2cM () nackBit = I2cM $ command 0x7 @@ -74,10 +76,10 @@  -- | Write some bytes bulkWrite :: ByteString -> I2cM ()-bulkWrite d +bulkWrite d   | BS.null d = return ()   | BS.length d > 16 = I2cM $ BPM $ left "Too many bytes"-  | otherwise = I2cM $ do +  | otherwise = I2cM $ do     command $ fromIntegral $ 0x10 + BS.length d - 1     put d     acks <- replicateM (BS.length d) $ toEnum . fromIntegral <$> getByte@@ -87,41 +89,31 @@                    bytes = if length nacks > 1 then "bytes" else "byte"                in fail $ "Nack after "++bytes++" "++nacks'++" during bulkWrite of "++show d -data I2cConfig = I2cConfig { i2cPower      :: Bool-                           , i2cPullups    :: Bool-                           , i2cAux        :: Bool-                           , i2cChipSelect :: Bool-                           }-               deriving (Show) --- | Set Bus Pirate I2C configuration bits-setConfig :: I2cConfig -> I2cM ()-setConfig config = I2cM $ -    command $ 0x40-            + bit 3 (i2cPower config)-            + bit 2 (i2cPullups config)-            + bit 1 (i2cAux config)-            + bit 0 (i2cChipSelect config)-  where-    bit n True = 2^n-    bit _ _    = 0+-- | Set Bus Pirate peripheral configuration bits+setConfig :: PeripheralConfig -> I2cM ()+setConfig config = I2cM $ setPeripherals config +-- | I2C bus speed data I2cSpeed = I2c_5kHz               | I2c_50kHz               | I2c_100kHz               | I2c_400kHz               deriving (Show, Eq, Ord, Enum, Bounded)-              + -- | Set I2C bus speed setSpeed :: I2cSpeed -> I2cM () setSpeed speed = I2cM $ command $ fromIntegral $ 0x60 + fromEnum speed  -- | Send Start bit, write some bytes, then read some bytes (ACKing -- each until the last), then send a stop bit+--+-- This is very likely broken as the command structure itself appears+-- to be horribly broken, requiring a conditional read of a status byte. writeRead :: ByteString -> Int -> I2cM ByteString-writeRead send recv -  | BS.length send > 0xffff = error "Too large send request"-  | recv > 0xffff           = error "Too large recieve request"+writeRead send recv+  | BS.length send > 0xffff = err "Too large send request"+  | recv > 0xffff           = err "Too large recieve request"   | otherwise               = I2cM $ do     putByte 0x8     putWord16 $ fromIntegral $ BS.length send
+ System/Hardware/BusPirate/SPI.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}++module System.Hardware.BusPirate.SPI+  ( -- * Types+    SpiM+  , spiMode+    -- * Bus operations+  , bulkTransfer+  , setCS+    -- * Configuration+  , PeripheralConfig(..)+  , setConfig+  , SpiSpeed(..)+  , setSpeed+  ) where++import Control.Applicative+import Control.Monad (replicateM)+import Control.Monad.IO.Class+import Control.Monad.Trans.Either+import Data.Word++import qualified Data.ByteString as BS+import Data.ByteString (ByteString)++import System.Hardware.BusPirate.Core++newtype SpiM a = SpiM (BusPirateM a)+               deriving (Functor, Applicative, Monad, MonadIO)++err :: String -> SpiM a+err = SpiM . BPM . left++-- | Enter I2C mode and run given action+spiMode :: SpiM a -> BusPirateM a+spiMode (SpiM m) = commandExpect 0x1 "SPI1" >> m++-- | Set chip select+setCS :: Bool -> SpiM ()+setCS True = SpiM $ command 0x21+setCS False = SpiM $ command 0x20++bulkTransfer :: ByteString -> SpiM ByteString+bulkTransfer d+  | BS.null d = return BS.empty+  | BS.length d > 16 = SpiM $ BPM $ left "Too many bytes"+  | otherwise = SpiM $ do+    command $ fromIntegral $ 0x10 + BS.length d - 1+    put d+    reply <- replicateM (BS.length d) $ getByte+    return $ BS.pack reply++-- | Set Bus Pirate peripheral configuration bits+setConfig :: PeripheralConfig -> SpiM ()+setConfig config = SpiM $ setPeripherals config++data SpiSpeed+    = Spi30KHz+    | Spi125KHz+    | Spi250KHz+    | Spi1MHz+    | Spi2MHz+    | Spi2_6MHz+    | Spi4MHz+    | Spi8MHz+    deriving (Show, Ord, Eq, Enum, Bounded)++-- | Set bus speed+setSpeed :: SpiSpeed -> SpiM ()+setSpeed speed = SpiM $ command $ 0x6 + fromIntegral (fromEnum speed)++-- | Write-then-read+--+-- This is very likely broken as the command structure itself appears+-- to be horribly broken, requiring a conditional read of a status byte.+writeRead :: Bool -> ByteString -> Word16 -> SpiM ByteString+writeRead toggleCS write readLen+  | readLen >= 4096 = err "Read length too long"+  | BS.length write >= 4096 = err "Write length too long"+  | otherwise = SpiM $ do+    putByte $ if toggleCS then 0x4 else 0x5+    putWord16 $ fromIntegral $ BS.length write+    putWord16 readLen+    status <- getByte+    case status of+      0 -> BPM $ left "Data too long"+      1 -> do put write+              get (fromIntegral readLen)
bus-pirate.cabal view
@@ -1,5 +1,5 @@ name:                bus-pirate-version:             0.5+version:             0.6 synopsis:            Haskell interface to the Bus Pirate binary interface homepage:            http://www.github.com/bgamari/bus-pirate license:             BSD3@@ -20,6 +20,7 @@ library   exposed-modules:     System.Hardware.BusPirate                        System.Hardware.BusPirate.I2C+                       System.Hardware.BusPirate.SPI   other-modules:       System.Hardware.BusPirate.Core   build-depends:       base >=4.6 && <4.8,                        serialport >=0.4 && <0.5,