module System.Hardware.Arduino.Utils where
import Control.Concurrent (threadDelay)
import Control.Monad (void)
import Data.Bits ((.|.), shiftL)
import Data.Char (isAlphaNum, isAscii, isSpace, chr)
import Data.IORef (newIORef, readIORef, writeIORef)
import Data.List (intercalate)
import Data.Word (Word8)
import System.Process (system)
import System.Info (os)
import Numeric (showHex, showIntAtBase, showFFloat)
delay :: Int -> IO ()
delay n
| os == "darwin"
= void $ system $ "sleep " ++ showFFloat (Just 2) (fromIntegral n / (1000 :: Double)) ""
| True
= threadDelay (n*1000)
mkDebugPrinter :: Bool -> IO (String -> IO ())
mkDebugPrinter False = return (const (return ()))
mkDebugPrinter True = do
cnt <- newIORef (1::Int)
let f s = do i <- readIORef cnt
writeIORef cnt (i+1)
putStrLn $ "[" ++ show i ++ "] hArduino: " ++ s
return f
showByte :: Word8 -> String
showByte i | isVisible = [c]
| i <= 0xf = '0' : showHex i ""
| True = showHex i ""
where c = chr $ fromIntegral i
isVisible = isAscii c && isAlphaNum c && isSpace c
showByteList :: [Word8] -> String
showByteList bs = "[" ++ intercalate ", " (map showByte bs) ++ "]"
showBin :: (Integral a, Show a) => a -> String
showBin n = showIntAtBase 2 (head . show) n ""
getString :: [Word8] -> String
getString [] = ""
getString [a] = [chr (fromIntegral a)]
getString (l:h:rest) = c : getString rest
where c = chr $ fromIntegral $ h `shiftL` 8 .|. l
die :: String -> [String] -> a
die m ms = error $ "\n*** hArduino:ERROR: " ++ intercalate "\n*** " (m:ms)