module System.Hardware.GPIO.Pin
where
import Data.Array
import System.IO
data Pin = Pin { num :: Int
, handle :: Handle
, dir :: PinMode
}
deriving (Show, Eq)
data PinMode = In | Out | Pwm deriving Eq
instance Show PinMode where
show In = "in"
show Out = "out"
show Pwm = "pwm"
pinMapping :: Array Int Int
pinMapping = listArray (0,16) [17, 18, 21, 22, 23, 24, 25, 4, 0, 1, 8, 7, 10, 9, 11, 14, 15]
global_GPIO_PATH = "/sys/class/gpio"
global_EXPORT_PATH = global_GPIO_PATH ++ "/export"
global_UNEXPORT_PATH = global_GPIO_PATH ++ "/unexport"
global_DEVICE_PATH i = global_GPIO_PATH ++ "/gpio"++ (show i)
global_DIRECTION_PATH i = global_DEVICE_PATH i ++ "/direction"
global_VALUE_PATH i = global_DEVICE_PATH i ++ "/value"
openWriteClose :: FilePath -> String -> IO ()
openWriteClose fp str = do
{ hdl <- openFile fp WriteMode
; hPutStr hdl str
; hFlush hdl
; hClose hdl
}
init :: Int -> PinMode -> IO Pin
init i d = do
{ let pn = pinMapping ! i
; openWriteClose global_EXPORT_PATH (show pn)
; openWriteClose (global_DIRECTION_PATH pn) (show d)
; hdl <- case d of
{ In -> openFile (global_VALUE_PATH pn) ReadMode
; _ -> openFile (global_VALUE_PATH pn) ReadWriteMode
}
; let pin = Pin i hdl d
; case d of
{ Out -> set pin Zero
; _ -> return ()
}
; return pin
}
close :: Pin -> IO ()
close pin = do
{ let pn = pinMapping ! (num pin)
; case (dir pin) of
{ Out -> set pin Zero
; _ -> return ()
}
; let hdl = handle pin
; hFlush hdl
; hClose hdl
; openWriteClose global_UNEXPORT_PATH (show pn)
}
data Value = One | Zero deriving (Show, Eq)
read :: Pin -> IO Value
read pin = do
{ let hdl = handle pin
; hSeek hdl AbsoluteSeek 0
; c <- hGetChar hdl
; if (c == '1')
then return One
else return Zero
}
set :: Pin -> Value -> IO ()
set (Pin _ hdl Out) value = do
{ hSeek hdl AbsoluteSeek 0
; case value of
{ One -> hPutChar hdl '1'
; Zero -> hPutChar hdl '0'
}
; hFlush hdl
}
set (Pin _ _ _) value = return ()