packages feed

huckleberry 0.9.1.1 → 0.10.0.0

raw patch · 13 files changed

+430/−104 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- System.PIO.Linux: oRdOnly :: Int
- System.PIO.Linux: oRdWr :: Int
- System.PIO.Linux: oWrOnly :: Int
- System.PIO.Linux.I2C: setSlave :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: mode0 :: Word8
- System.PIO.Linux.SPI: mode1 :: Word8
- System.PIO.Linux.SPI: mode2 :: Word8
- System.PIO.Linux.SPI: mode3 :: Word8
- System.PIO.Linux.SPI: setRdBitsPerWord :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: setRdLbsFirst :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: setRdMaxSpeedHz :: Int -> Word32 -> IO Int
- System.PIO.Linux.SPI: setRdMode :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: setWrBitsPerWord :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: setWrLbsFirst :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: setWrMaxSpeedHz :: Int -> Word32 -> IO Int
- System.PIO.Linux.SPI: setWrMode :: Int -> Word8 -> IO Int
- System.PIO.Linux.SPI: transferMessage1 :: Int -> Ptr a -> Int -> Word32 -> Word8 -> IO Int
+ System.PIO.Linux: ReadMode :: IOMode
+ System.PIO.Linux: ReadWriteMode :: IOMode
+ System.PIO.Linux: WriteMode :: IOMode
+ System.PIO.Linux: data IOMode
+ System.PIO.Linux: instance GHC.Enum.Enum System.PIO.Linux.IOMode
+ System.PIO.Linux: type FileDescriptor = Int
+ System.PIO.Linux: type FilePath = String
+ System.PIO.Linux.GPIO: type PinNumber = Int
+ System.PIO.Linux.I2C.Raw: setSlave :: FileDescriptor -> SlaveAddress -> IO ()
+ System.PIO.Linux.I2C.Raw: type SlaveAddress = Word8
+ System.PIO.Linux.PWM: type Channel = Int
+ System.PIO.Linux.PWM: type DutyCycle = Int
+ System.PIO.Linux.PWM: type Period = Int
+ System.PIO.Linux.SPI.Raw: Mode0 :: SPIMode
+ System.PIO.Linux.SPI.Raw: Mode1 :: SPIMode
+ System.PIO.Linux.SPI.Raw: Mode2 :: SPIMode
+ System.PIO.Linux.SPI.Raw: Mode3 :: SPIMode
+ System.PIO.Linux.SPI.Raw: data SPIMode
+ System.PIO.Linux.SPI.Raw: getBitsPerWord :: FileDescriptor -> IO Bits
+ System.PIO.Linux.SPI.Raw: getLsbFirst :: FileDescriptor -> IO Bool
+ System.PIO.Linux.SPI.Raw: getMaxSpeedHz :: FileDescriptor -> IO Speed
+ System.PIO.Linux.SPI.Raw: getMode :: FileDescriptor -> IO SPIMode
+ System.PIO.Linux.SPI.Raw: instance GHC.Enum.Enum System.PIO.Linux.SPI.Raw.SPIMode
+ System.PIO.Linux.SPI.Raw: setBitsPerWord :: FileDescriptor -> Bits -> IO ()
+ System.PIO.Linux.SPI.Raw: setLsbFirst :: FileDescriptor -> Bool -> IO ()
+ System.PIO.Linux.SPI.Raw: setMaxSpeedHz :: FileDescriptor -> Speed -> IO ()
+ System.PIO.Linux.SPI.Raw: setMode :: FileDescriptor -> SPIMode -> IO ()
+ System.PIO.Linux.SPI.Raw: transferRx :: FileDescriptor -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()
+ System.PIO.Linux.SPI.Raw: transferTx :: FileDescriptor -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()
+ System.PIO.Linux.SPI.Raw: transferTxRx1 :: FileDescriptor -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()
+ System.PIO.Linux.SPI.Raw: transferTxRx2 :: FileDescriptor -> Ptr a -> Int -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()
+ System.PIO.Linux.SPI.Raw: type Bits = Word8
+ System.PIO.Linux.SPI.Raw: type Speed = Word32
- System.PIO.Linux: fdClose :: Int -> IO Int
+ System.PIO.Linux: fdClose :: FileDescriptor -> IO ()
- System.PIO.Linux: fdGetBuf :: Int -> Ptr a -> Int -> IO Int
+ System.PIO.Linux: fdGetBuf :: FileDescriptor -> Ptr a -> Int -> IO ()
- System.PIO.Linux: fdOpen :: String -> Int -> IO Int
+ System.PIO.Linux: fdOpen :: FilePath -> IOMode -> IO FileDescriptor
- System.PIO.Linux: fdPutBuf :: Int -> Ptr a -> Int -> IO Int
+ System.PIO.Linux: fdPutBuf :: FileDescriptor -> Ptr a -> Int -> IO ()
- System.PIO.Linux.GPIO: getValue :: Int -> IO Bool
+ System.PIO.Linux.GPIO: getValue :: PinNumber -> IO Bool
- System.PIO.Linux.GPIO: setValue :: Int -> Bool -> IO ()
+ System.PIO.Linux.GPIO: setValue :: PinNumber -> Bool -> IO ()
- System.PIO.Linux.PWM: getEnable :: Int -> IO Bool
+ System.PIO.Linux.PWM: getEnable :: Channel -> IO Bool
- System.PIO.Linux.PWM: getValue :: Int -> IO (Int, Int)
+ System.PIO.Linux.PWM: getValue :: Channel -> IO (Period, DutyCycle)
- System.PIO.Linux.PWM: setEnable :: Int -> Bool -> IO ()
+ System.PIO.Linux.PWM: setEnable :: Channel -> Bool -> IO ()
- System.PIO.Linux.PWM: setValue :: Int -> Int -> Int -> IO ()
+ System.PIO.Linux.PWM: setValue :: Channel -> Period -> DutyCycle -> IO ()

Files

cbits/hs_i2c.c view
@@ -1,7 +1,6 @@ #include "hs_i2c.h"  #include <sys/ioctl.h>-#include <linux/types.h> #include <linux/i2c-dev.h>  
cbits/hs_spi.c view
@@ -1,8 +1,8 @@ #include "hs_spi.h"  #include <sys/ioctl.h>-#include <linux/types.h> #include <linux/spi/spidev.h>+#include <string.h>   unsigned char spi_mode_0() {@@ -19,45 +19,105 @@ }  -int spi_transfer_message_1(int fd, void* buff, __u32 buff_len, __u32 speed, __u8 bits) { -  struct spi_ioc_transfer spi;-  spi.tx_buf        = (__u64) buff;-  spi.rx_buf        = (__u64) buff;-  spi.len           = buff_len;-  spi.speed_hz      = speed;-  spi.bits_per_word = bits;-  spi.delay_usecs   = 0;-  spi.cs_change     = 0;+int spi_transfer_tx_rx_1(int fd, void *buff, __u32 buff_len, __u8 bits, __u32 speed, __u16 delay, __u8 cs_change) { -  return ioctl(fd,SPI_IOC_MESSAGE(1),&spi);+  struct spi_ioc_transfer tran;+  memset(&tran,0,sizeof(struct spi_ioc_transfer));+  +  tran.tx_buf        = (__u64) buff;+  tran.rx_buf        = (__u64) buff;+  tran.len           = buff_len;+  tran.bits_per_word = bits;+  tran.speed_hz      = speed;+  tran.delay_usecs   = delay;+  tran.cs_change     = cs_change;++  return ioctl(fd,SPI_IOC_MESSAGE(1),&tran);+   }+int spi_transfer_tx_rx_2(int fd,+			 void *tx_buff, __u32 tx_buff_len,+			 void *rx_buff, __u32 rx_buff_len,+			 __u8 bits, __u32 speed, __u16 delay, __u8 cs_change) { -int spi_set_rd_mode(int fd, __u8 mode) {-  return ioctl(fd,SPI_IOC_RD_MODE,&mode);+  struct spi_ioc_transfer tran[2];+  memset(tran,0,sizeof(tran));+  +  tran[0].tx_buf        = (__u64) tx_buff;+  tran[0].len           = tx_buff_len;+  tran[0].bits_per_word = bits;+  tran[0].speed_hz      = speed;+  tran[0].delay_usecs   = delay;+  tran[0].cs_change     = cs_change;++  tran[1].rx_buf        = (__u64) rx_buff;+  tran[1].len           = rx_buff_len;+  tran[1].bits_per_word = bits;+  tran[1].speed_hz      = speed;+  tran[1].delay_usecs   = delay;+  tran[1].cs_change     = cs_change;++  return ioctl(fd,SPI_IOC_MESSAGE(2),tran);+   }-int spi_set_wr_mode(int fd, __u8 mode) {+int spi_transfer_tx_1(int fd, void *buff, __u32 buff_len, __u8 bits, __u32 speed, __u16 delay, __u8 cs_change) {+  +  struct spi_ioc_transfer tran;+  memset(&tran,0,sizeof(struct spi_ioc_transfer));+  +  tran.tx_buf        = (__u64) buff;+  tran.len           = buff_len;+  tran.bits_per_word = bits;+  tran.speed_hz      = speed;+  tran.delay_usecs   = delay;+  tran.cs_change     = cs_change;++  return ioctl(fd,SPI_IOC_MESSAGE(1),&tran);++}+int spi_transfer_rx_1(int fd, void *buff, __u32 buff_len, __u8 bits, __u32 speed, __u16 delay, __u8 cs_change) {+  +  struct spi_ioc_transfer tran;+  memset(&tran,0,sizeof(struct spi_ioc_transfer));+  +  tran.rx_buf        = (__u64) buff;+  tran.len           = buff_len;+  tran.bits_per_word = bits;+  tran.speed_hz      = speed;+  tran.delay_usecs   = delay;+  tran.cs_change     = cs_change;++  return ioctl(fd,SPI_IOC_MESSAGE(1),&tran);++}+++int spi_get_mode(int fd, __u8 *pmode) {+  return ioctl(fd,SPI_IOC_RD_MODE,pmode);+}+int spi_set_mode(int fd, __u8 mode) {   return ioctl(fd,SPI_IOC_WR_MODE,&mode); } -int spi_set_rd_lbs_first(int fd, __u8 lbs) {-  return ioctl(fd,SPI_IOC_RD_LSB_FIRST,&lbs);+int spi_get_lsb_first(int fd, __u8 *plsb) {+  return ioctl(fd,SPI_IOC_RD_LSB_FIRST,plsb); }-int spi_set_wr_lbs_first(int fd, __u8 lbs) {-  return ioctl(fd,SPI_IOC_WR_LSB_FIRST,&lbs);+int spi_set_lsb_first(int fd, __u8 lsb) {+  return ioctl(fd,SPI_IOC_WR_LSB_FIRST,&lsb); } -int spi_set_rd_bits_per_word(int fd, __u8 bits) {-  return ioctl(fd,SPI_IOC_RD_BITS_PER_WORD,&bits);+int spi_get_bits_per_word(int fd, __u8 *pbits) {+  return ioctl(fd,SPI_IOC_RD_BITS_PER_WORD,pbits); }-int spi_set_wr_bits_per_word(int fd, __u8 bits) {+int spi_set_bits_per_word(int fd, __u8 bits) {   return ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&bits); } -int spi_set_rd_max_speed_hz(int fd, __u32 speed) {-  return ioctl(fd,SPI_IOC_RD_MAX_SPEED_HZ,&speed);+int spi_get_max_speed_hz(int fd, __u32 *pspeed) {+  return ioctl(fd,SPI_IOC_RD_MAX_SPEED_HZ,pspeed); }-int spi_set_wr_max_speed_hz(int fd, __u32 speed) {+int spi_set_max_speed_hz(int fd, __u32 speed) {   return ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&speed); } 
huckleberry.cabal view
@@ -1,5 +1,5 @@ name:                huckleberry-version:             0.9.1.1+version:             0.10.0.0 synopsis:            Haskell IOT on Intel Edison and other Linux computers. description:         Please see README.md homepage:            https://github.com/mitsuji/huckleberry#readme@@ -24,6 +24,8 @@                      , System.PIO.Linux.PWM                      , System.PIO.Linux.I2C                      , System.PIO.Linux.SPI+                     , System.PIO.Linux.I2C.Raw+                     , System.PIO.Linux.SPI.Raw   build-depends:       base >= 4.7 && < 5   default-language:    Haskell2010   c-sources:           cbits/hs_fcntl.c
include/hs_fcntl.h view
@@ -1,8 +1,6 @@ #ifndef HS_FCNTL_H #define HS_FCNTL_H -#include <linux/types.h>- int o_rdonly(); int o_wronly(); int o_rdwr();
include/hs_spi.h view
@@ -2,27 +2,31 @@ #define HS_SPI_H  #include <linux/types.h>-#include <stddef.h>-#include <stdio.h>  unsigned char spi_mode_0(); unsigned char spi_mode_1(); unsigned char spi_mode_2(); unsigned char spi_mode_3(); -int spi_transfer_message_1(int fd, void* buff, __u32 buff_len, __u32 speed, __u8 bits);+int spi_transfer_tx_rx_1(int fd, void *buff, __u32 buff_len, __u8 bits, __u32 speed, __u16 delay, __u8 cs_change);+int spi_transfer_tx_rx_2(int fd,+			 void *tx_buff, __u32 tx_buff_len,+			 void *rx_buff, __u32 rx_buff_len,+			 __u8 bits, __u32 speed, __u16 delay, __u8 cs_change);+int spi_transfer_tx_1(int fd, void *buff, __u32 buff_len, __u8 bits, __u32 speed, __u16 delay, __u8 cs_change);+int spi_transfer_rx_1(int fd, void *buff, __u32 buff_len, __u8 bits, __u32 speed, __u16 delay, __u8 cs_change); -int spi_set_rd_mode(int fd, __u8 mode);-int spi_set_wr_mode(int fd, __u8 mode);+int spi_get_mode(int fd, __u8 *pmode);+int spi_set_mode(int fd, __u8 mode); -int spi_set_rd_lbs_first(int fd, __u8 lbs);-int spi_set_wr_lbs_first(int fd, __u8 lbs);+int spi_get_lsb_first(int fd, __u8 *plsb);+int spi_set_lsb_first(int fd, __u8 lsb); -int spi_set_rd_bits_per_word(int fd, __u8 bits);-int spi_set_wr_bits_per_word(int fd, __u8 bits);+int spi_get_bits_per_word(int fd, __u8 *pbits);+int spi_set_bits_per_word(int fd, __u8 bits); -int spi_set_rd_max_speed_hz(int fd, __u32 speed);-int spi_set_wr_max_speed_hz(int fd, __u32 speed);+int spi_get_max_speed_hz(int fd, __u32 *pspeed);+int spi_set_max_speed_hz(int fd, __u32 speed);   #endif
src/System/PIO.hs view
@@ -14,18 +14,22 @@     f2 '1' = 1  +-- | an unsigned number in binary notation. binToNum :: (Eq a, Num a) => String -> a binToNum s = case readBin s of   (x,""):_  -> x   _         -> error "binToNum: parse error"   +-- | an unsigned number in octal notation. octToNum :: (Eq a, Num a) => String -> a octToNum s = case readOct s of   (x,""):_  -> x   _         -> error "octToNum: parse error"   +-- | an unsigned number in hexadecimal notation.+-- Both upper or lower case letters are allowed. hexToNum :: (Eq a, Num a) => String -> a hexToNum s = case readHex s of   (x,""):_  -> x
src/System/PIO/Linux.hs view
@@ -1,29 +1,82 @@ {-# LANGUAGE ForeignFunctionInterface #-}  module System.PIO.Linux (+  FilePath,+  FileDescriptor,+  IOMode(..),   fdOpen,   fdClose,   fdPutBuf,   fdGetBuf,-  oRdOnly,-  oWrOnly,-  oRdWr   ) where  import Foreign.Ptr(Ptr) import Foreign.C.String(CString,withCString)-  -foreign import ccall "open" open :: CString -> Int -> IO Int-foreign import ccall "close" fdClose :: Int -> IO Int-                                        -foreign import ccall "write" fdPutBuf :: Int -> Ptr a -> Int -> IO Int-foreign import ccall "read" fdGetBuf :: Int -> Ptr a -> Int -> IO Int-                                        -foreign import ccall "o_rdonly" oRdOnly :: Int-foreign import ccall "o_wronly" oWrOnly :: Int-foreign import ccall "o_rdwr" oRdWr :: Int+import Prelude hiding (FilePath)+import Foreign.C.Error(throwErrno)++-- | File and directory names are values of type String+type FilePath = String++-- | File descriptor numbers are values of type Int+type FileDescriptor = Int+                ++foreign import ccall "o_rdonly" o_rdonly :: Int+foreign import ccall "o_wronly" o_wronly :: Int+foreign import ccall "o_rdwr" o_rdwr :: Int                                         -fdOpen :: String -> Int -> IO Int-fdOpen path flags = withCString path $ \cs -> open cs flags-                                              +foreign import ccall "open" linux_open :: CString -> Int -> IO Int+foreign import ccall "close" linux_close :: Int -> IO Int+foreign import ccall "write" linux_write :: Int -> Ptr a -> Int -> IO Int+foreign import ccall "read" linux_read :: Int -> Ptr a -> Int -> IO Int++                +data IOMode = ReadMode+            | WriteMode+            | ReadWriteMode+              +instance Enum IOMode where+  +  toEnum n | n == o_rdonly = ReadMode+           | n == o_wronly = WriteMode+           | n == o_rdwr = ReadWriteMode+           | otherwise = error "toEnum: convert error"++  fromEnum ReadMode = o_rdonly+  fromEnum WriteMode = o_wronly+  fromEnum ReadWriteMode = o_rdwr++++-- | Computation 'fdOpen' @file@ @mode@ allocates and returns a new, open+-- descriptor to manage the file @file@. It manages input if @mode@+-- is 'ReadMode', output if @mode@ is 'WriteMode',+-- and both input and output if mode is 'ReadWriteMode'.+fdOpen :: FilePath -> IOMode -> IO FileDescriptor+fdOpen path mode = withCString path $+  \cpath -> linux_open cpath (fromEnum mode) >>= \fd -> case fd of+    -1 -> throwErrno "fdOpen"+    otherwise -> return fd++-- | Computation 'fdClose' @fd@ makes descriptor @fd@ closed.+fdClose :: FileDescriptor -> IO ()+fdClose fd = linux_close fd >>= \rc -> case rc of+  -1 -> throwErrno "fdClose"+  otherwise -> return ()++-- | 'fdPutBuf' @fd@ @buf@ @count@ writes @count@ 8-bit bytes from the+-- buffer @buf@ to the descriptor @fd@.+fdPutBuf :: FileDescriptor -> Ptr a -> Int -> IO ()+fdPutBuf fd buf bufLen = linux_write fd buf bufLen >>= \rc -> case rc of+  -1 -> throwErrno "fdPutBuf"+  otherwise -> return ()++-- | 'fdGetBuf' @fd@ @buf@ @count@ reads data from the descriptor @fd@+-- into the buffer @buf@ until either EOF is reached or+-- @count@ 8-bit bytes have been read.+fdGetBuf :: FileDescriptor -> Ptr a -> Int -> IO ()+fdGetBuf fd buf bufLen = linux_read fd buf bufLen >>= \rc -> case rc of+  -1 -> throwErrno "fdGetBuf"+  otherwise -> return () 
src/System/PIO/Linux/GPIO.hs view
@@ -1,21 +1,27 @@ module System.PIO.Linux.GPIO (+  PinNumber,   setValue,   getValue   ) where  import System.IO (writeFile, readFile) -  +-- | GPIO pin numbers are values of type Int+type PinNumber = Int+ valueFilePath :: Int -> String valueFilePath n = "/sys/class/gpio/gpio" ++ (show n) ++ "/value"  -setValue :: Int -> Bool -> IO ()+-- | Computation 'setValue' @pinnum@ @True@ makes corresponding pin high.+-- Computation 'setValue' @pinnum@ @False@ makes corresponding pin low.+setValue :: PinNumber -> Bool -> IO () setValue n flag =   writeFile (valueFilePath n) $ show $ fromEnum flag  -getValue :: Int -> IO Bool+-- | Computation 'getValue' @pinnum@ obtain status of corresponding pin.+getValue :: PinNumber -> IO Bool getValue n =   (\flag -> toEnum $ read flag) <$> readFile (valueFilePath n) 
src/System/PIO/Linux/I2C.hs view
@@ -1,10 +1,5 @@-{-# LANGUAGE ForeignFunctionInterface #-} + module System.PIO.Linux.I2C (-  setSlave   ) where--import Data.Word(Word8)--foreign import ccall "i2c_set_slave" setSlave :: Int -> Word8 -> IO Int 
+ src/System/PIO/Linux/I2C/Raw.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE ForeignFunctionInterface #-}++module System.PIO.Linux.I2C.Raw (+  SlaveAddress,+  setSlave+  ) where++import Data.Word(Word8)+import System.PIO.Linux(FileDescriptor)+import Foreign.C.Error(throwErrno)++type SlaveAddress = Word8++foreign import ccall "i2c_set_slave" i2c_set_slave :: Int -> Word8 -> IO Int+++-- | Computation 'setSlave' @fd@ @address@ sets the slave address for+-- descriptor @fd@ on I2C.+setSlave :: FileDescriptor -> SlaveAddress -> IO ()+setSlave fd addr = i2c_set_slave fd addr >>= \rc -> case rc of+  -1 -> throwErrno "setSlave"+  otherwize -> return ()+
src/System/PIO/Linux/PWM.hs view
@@ -1,4 +1,7 @@ module System.PIO.Linux.PWM (+  Channel,+  Period,+  DutyCycle,   setEnable,   getEnable,   setValue,@@ -7,7 +10,16 @@  import System.IO (writeFile, readFile) +-- | PWM channel numbers are values of type Int+type Channel = Int +-- | PWM period is a value of type Int+type Period = Int++-- | PWM duty cycle is a value of type Int+type DutyCycle = Int++ interfaceFilePath :: Int -> String -> String interfaceFilePath n file = "/sys/class/pwm/pwmchip0/pwm" ++ (show n) ++ file @@ -21,17 +33,21 @@ dutyCycleFilePath n = interfaceFilePath n "/duty_cycle"  -setEnable :: Int -> Bool -> IO ()+-- | Computation 'setEnable' @channel@ @True@ makes corresponding PWM channel enabled.+-- Computation 'setEnable' @channel@ @False@ makes corresponding PWM channel disabled.+setEnable :: Channel -> Bool -> IO () setEnable n flag =   writeFile (enableFilePath n) $ show $ fromEnum flag  -getEnable :: Int -> IO Bool+-- | Computation 'getEnable' @channel@ obtain status of corresponding PWM channel.+getEnable :: Channel -> IO Bool getEnable n =   (\flag -> toEnum $ read flag) <$> readFile (enableFilePath n)  -setValue :: Int -> Int -> Int -> IO ()+-- | 'setValue' @channel@ @period@ @dutyCycle@ generates PWM signal on corresponding PWM channel. @period@ and @dutyCycle@ are value of nanoseconds.+setValue :: Channel -> Period -> DutyCycle -> IO () setValue n period dutyCycle = do   let dutyCycleFilePath' = dutyCycleFilePath n   writeFile dutyCycleFilePath' $ show 0@@ -39,7 +55,8 @@   writeFile dutyCycleFilePath' $ show dutyCycle  -getValue :: Int -> IO (Int, Int)+-- | 'getValue' @channel@ obtain status of current PWM signal on corresponding PWM channel.+getValue :: Channel -> IO (Period, DutyCycle) getValue n =   (\p dc -> (read p, read dc)) <$> readFile (periodFilePath n) <*> readFile (dutyCycleFilePath n) 
src/System/PIO/Linux/SPI.hs view
@@ -1,40 +1,5 @@-{-# LANGUAGE ForeignFunctionInterface #-} + module System.PIO.Linux.SPI (-  mode0,-  mode1,-  mode2,-  mode3,-  transferMessage1,-  setRdMode,-  setWrMode,-  setRdLbsFirst,-  setWrLbsFirst,-  setRdBitsPerWord,-  setWrBitsPerWord,-  setRdMaxSpeedHz,-  setWrMaxSpeedHz,   ) where--import Foreign.Ptr(Ptr)-import Data.Word(Word8,Word32)--foreign import ccall "spi_mode_0" mode0 :: Word8-foreign import ccall "spi_mode_1" mode1 :: Word8-foreign import ccall "spi_mode_2" mode2 :: Word8-foreign import ccall "spi_mode_3" mode3 :: Word8--foreign import ccall "spi_transfer_message_1" transferMessage1 :: Int -> Ptr a -> Int -> Word32 -> Word8 -> IO Int--foreign import ccall "spi_set_rd_mode" setRdMode :: Int -> Word8 -> IO Int-foreign import ccall "spi_set_wr_mode" setWrMode :: Int -> Word8 -> IO Int--foreign import ccall "spi_set_rd_lbs_first" setRdLbsFirst :: Int -> Word8 -> IO Int-foreign import ccall "spi_set_wr_lbs_first" setWrLbsFirst :: Int -> Word8 -> IO Int--foreign import ccall "spi_set_rd_bits_per_word" setRdBitsPerWord :: Int -> Word8 -> IO Int-foreign import ccall "spi_set_wr_bits_per_word" setWrBitsPerWord :: Int -> Word8 -> IO Int--foreign import ccall "spi_set_rd_max_speed_hz" setRdMaxSpeedHz :: Int -> Word32 -> IO Int-foreign import ccall "spi_set_wr_max_speed_hz" setWrMaxSpeedHz :: Int -> Word32 -> IO Int 
+ src/System/PIO/Linux/SPI/Raw.hs view
@@ -0,0 +1,200 @@+{-# LANGUAGE ForeignFunctionInterface #-}++module System.PIO.Linux.SPI.Raw (+  SPIMode(..),+  Bits,+  Speed,+  transferTxRx1,+  transferTxRx2,+  transferTx,+  transferRx,+  getMode,+  setMode,+  getLsbFirst,+  setLsbFirst,+  getBitsPerWord,+  setBitsPerWord,+  getMaxSpeedHz,+  setMaxSpeedHz,+  ) where++import Foreign.Ptr(Ptr)+import Data.Word(Word8,Word16,Word32)+import System.PIO.Linux(FileDescriptor)+import Foreign.Marshal.Alloc(alloca)+import Foreign.Storable(peek)+import Foreign.C.Error(throwErrno)+++type Bits  = Word8+type Speed = Word32+type Delay = Word16+type CSChange = Bool+++foreign import ccall "spi_mode_0" spi_mode0 :: Word8+foreign import ccall "spi_mode_1" spi_mode1 :: Word8+foreign import ccall "spi_mode_2" spi_mode2 :: Word8+foreign import ccall "spi_mode_3" spi_mode3 :: Word8++foreign import ccall "spi_transfer_tx_rx_1" spi_transfer_tx_rx_1+  :: Int -> Ptr a -> Int -> Word8 -> Word32 -> Word16 -> Word8 -> IO Int+foreign import ccall "spi_transfer_tx_rx_2" spi_transfer_tx_rx_2+  :: Int -> Ptr a -> Int -> Ptr a -> Int -> Word8 -> Word32 -> Word16 -> Word8 -> IO Int+foreign import ccall "spi_transfer_tx_1" spi_transfer_tx_1+  :: Int -> Ptr a -> Int -> Word8 -> Word32 -> Word16 -> Word8 -> IO Int+foreign import ccall "spi_transfer_rx_1" spi_transfer_rx_1+  :: Int -> Ptr a -> Int -> Word8 -> Word32 -> Word16 -> Word8 -> IO Int++foreign import ccall "spi_get_mode" spi_get_mode :: Int -> Ptr Word8 -> IO Int+foreign import ccall "spi_set_mode" spi_set_mode :: Int -> Word8 -> IO Int++foreign import ccall "spi_get_lsb_first" spi_get_lsb_first :: Int -> Ptr Word8 -> IO Int+foreign import ccall "spi_set_lsb_first" spi_set_lsb_first :: Int -> Word8 -> IO Int++foreign import ccall "spi_get_bits_per_word" spi_get_bits_per_word :: Int -> Ptr Word8 -> IO Int+foreign import ccall "spi_set_bits_per_word" spi_set_bits_per_word :: Int -> Word8 -> IO Int++foreign import ccall "spi_get_max_speed_hz" spi_get_max_speed_hz :: Int -> Ptr Word32 -> IO Int+foreign import ccall "spi_set_max_speed_hz" spi_set_max_speed_hz :: Int -> Word32 -> IO Int++++data SPIMode = Mode0+             | Mode1+             | Mode2+             | Mode3+              +                                        +instance Enum SPIMode where+  +  toEnum n | (fromIntegral n) == spi_mode0 = Mode0+           | (fromIntegral n) == spi_mode1 = Mode1+           | (fromIntegral n) == spi_mode2 = Mode2+           | (fromIntegral n) == spi_mode3 = Mode3+           | otherwise  = error "toEnum: convert error"++  fromEnum Mode0 = (fromIntegral spi_mode0)+  fromEnum Mode1 = (fromIntegral spi_mode1)+  fromEnum Mode2 = (fromIntegral spi_mode2)+  fromEnum Mode3 = (fromIntegral spi_mode3)++++-- | 'transferTxRx1' @fd@ @buf@ @count@ @bits@ @speed@ @delay@ @csChange@ transfer @count@ 8-bit bytes from the+-- buffer @buf@ to the descriptor @fd@.+transferTxRx1 :: FileDescriptor -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()+transferTxRx1 fd buf bufLen bits speed delay csChange =+  spi_transfer_tx_rx_1 fd buf bufLen bits speed delay (fromIntegral $ fromEnum csChange)+  >>= \rc -> case rc of+    -1 -> throwErrno "transferTxRx1"+    otherwize -> return ()+    ++transferTxRx2 :: FileDescriptor -> Ptr a -> Int -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()+transferTxRx2 fd txBuf txBufLen rxBuf rxBufLen bits speed delay csChange =+  spi_transfer_tx_rx_2 fd txBuf txBufLen rxBuf rxBufLen bits speed delay (fromIntegral $ fromEnum csChange)+  >>= \rc -> case rc of+    -1 -> throwErrno "transferTxRx2"+    otherwize -> return ()+  ++transferTx :: FileDescriptor -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()+transferTx fd buf bufLen bits speed delay csChange =+  spi_transfer_tx_1 fd buf bufLen bits speed delay (fromIntegral $ fromEnum csChange)+  >>= \rc -> case rc of+    -1 -> throwErrno "transferTx"+    otherwize -> return ()+    ++transferRx :: FileDescriptor -> Ptr a -> Int -> Bits -> Speed -> Delay -> CSChange -> IO ()+transferRx fd buf bufLen bits speed delay csChange =+  spi_transfer_rx_1 fd buf bufLen bits speed delay (fromIntegral $ fromEnum csChange)+  >>= \rc -> case rc of+    -1 -> throwErrno "transferRx"+    otherwize -> return ()++++-- | Computation 'getMode' @fd@ gets the spi mode for+-- descriptor @fd@.+getMode :: FileDescriptor -> IO SPIMode+getMode fd = alloca $+             \p -> spi_get_mode fd p >>= \rc -> case rc of+               -1 -> throwErrno "getMode"+               otherwize -> do+                 mode <- peek p+                 return $ toEnum $ fromIntegral mode+++-- | Computation 'setMode' @fd@ @mode@ sets the spi mode for+-- descriptor @fd@.+setMode :: FileDescriptor -> SPIMode -> IO ()+setMode fd mode =+  spi_set_mode fd (fromIntegral $ fromEnum mode)+  >>= \rc -> case rc of+    -1 -> throwErrno "setMode"+    otherwize -> return ()+++-- | Computation 'getLsbFirst' @fd@ gets the LBS-first flag for+-- descriptor @fd@.+getLsbFirst :: FileDescriptor -> IO Bool+getLsbFirst fd = alloca $+                 \p -> spi_get_lsb_first fd p >>= \rc -> case rc of+                   -1 -> throwErrno "getLsbFirst"+                   otherwize -> do+                     flag <- peek p+                     return $ toEnum $ fromIntegral flag+++-- | Computation 'setLsbFirst' @fd@ @flag@ sets the LBS-first flag for+-- descriptor @fd@.+setLsbFirst :: FileDescriptor -> Bool -> IO ()+setLsbFirst fd flag =+  spi_set_lsb_first fd (fromIntegral $ fromEnum flag)+  >>= \rc -> case rc of+    -1 -> throwErrno "setLsbFirst"+    otherwize -> return ()+++-- | Computation 'getBitsPerWord' @fd@ gets the number+-- of bits in each SPI transfer word for+-- descriptor @fd@.+getBitsPerWord :: FileDescriptor -> IO Bits+getBitsPerWord fd = alloca $+  \p -> spi_get_bits_per_word fd p >>= \rc -> case rc of+    -1 -> throwErrno "getBitsPerWord"+    otherwize -> peek p+++-- | Computation 'setBitsPerWord' @fd@ @bits@ sets the number+-- of bits in each SPI transfer word for+-- descriptor @fd@.+setBitsPerWord :: FileDescriptor -> Bits -> IO ()+setBitsPerWord fd bits = spi_set_bits_per_word fd bits+  >>= \rc -> case rc of+    -1 -> throwErrno "setBitsPerWord"+    otherwize -> return ()+++-- | Computation 'getMaxSpeedHz' @fd@ gets the maximum+-- SPI transfer speed, in Hz for+-- descriptor @fd@.+getMaxSpeedHz :: FileDescriptor -> IO Speed+getMaxSpeedHz fd = alloca $+  \p -> spi_get_max_speed_hz fd p >>= \rc -> case rc of+    -1 -> throwErrno "getMaxSpeedHz"+    otherwize -> peek p+++-- | Computation 'setMaxSpeedHz' @fd@ @speed@ sets the maximum+-- SPI transfer speed, in Hz for+-- descriptor @fd@.+setMaxSpeedHz :: FileDescriptor -> Speed -> IO ()+setMaxSpeedHz fd speed = spi_set_max_speed_hz fd speed+  >>= \rc -> case rc of+    -1 -> throwErrno "setMaxSpeedHz"+    otherwize -> return ()++