module IchigoJam ( Handle(Handle) ,open ,opend ,close ,send ,recv ,led ,play ,btn ) where import qualified Data.ByteString.Char8 as B import qualified System.Hardware.Serialport as S import Control.Monad(forM_,foldM,forever) import Control.Concurrent(ThreadId,forkIO,killThread,threadDelay) led :: Handle -> Bool -> IO () led h on = do let flag = case on of True -> "1" False -> "0" send h $ "LED " ++ flag ++ "\n" r <- recv h 4 return () play :: Handle -> String -> IO () play h score = do send h $ "PLAY \"" ++ score ++ "\"\n" r <- recv h 4 return () btn :: Handle -> IO Bool btn h = do send h $ "PRINT BTN ()\n" r <- recv h 4 -- [TODO] convert to Bool putStrLn r return True defaultSendDelay = 50 * 1000 defaultRecvDelay = 50 * 1000 data Handle = Handle { port :: S.SerialPort , sendDelay :: Int , recvDelay :: Int } open :: FilePath -> Int -> Int -> IO Handle open path sd rd = do p <- S.openSerial path S.defaultSerialSettings { S.commSpeed = S.CS115200 } return $ Handle p sd rd opend path = open path defaultSendDelay defaultRecvDelay close :: Handle -> IO() close (Handle p sd rd) = do S.closeSerial p send :: Handle -> String -> IO() send (Handle p sd _) s = do forM_ s (\c -> do S.send p $ B.singleton c S.flush p threadDelay sd ) recv :: Handle -> Int -> IO String recv (Handle p _ rd) l = do bs <- foldM( \acc _-> do b <- S.recv p 1 threadDelay rd return $ acc `B.append` b ) B.empty [1..l] return $ B.unpack bs