ham-0.1.0.0: src/Ham/CAT/SerialCAT.hs
module Ham.CAT.SerialCAT (SerialCAT(..)
,serialGet
,serialSend) where
import Ham.Internal.Data
import System.Hardware.Serialport
import Data.Attoparsec.ByteString.Char8
import qualified Data.ByteString.Char8 as B
import Control.Concurrent (threadDelay)
-- | Interface for radios that are communicating via serial interface.
data SerialCAT = SerialCAT {
serialGetFrequency :: SerialPort -> IO (Maybe Frequency)
, serialGetMode :: SerialPort -> IO (Maybe QsoMode)
, serialSetPowerSSB :: SerialPort -> Int -> IO ()
, serialGetPowerSSB :: SerialPort -> IO (Maybe Int)
, serialIdentify :: SerialPort -> IO Bool
}
-- | Get a value from a radio connected to a serial port.
-- This uses a format that seems to be used by more than one manufacturer, such as Yaesu and Elecraft.
-- The command format is "XY;" for getting something, where XY is a string. XY is given as second argument to this function.
serialGet :: SerialPort
-> String -- ^ Command; e.g. FA for getting frequency of VFO A.
-> (B.ByteString -> Parser a) -- ^ Decoder for the resulting answer from the radio.
-> IO (Maybe a)
serialGet s cmd parser = do
let cmd' = B.pack cmd <> B.pack ";"
send s cmd'
-- Wait for 100ms to give the transceiver some time to answer;
-- I have not found a better way to do this at the moment with the serialport library.
-- It seems to set all operations to non-blocking.
-- Set the radio's CAT TOT to 10msec (minimum).
threadDelay 100000
a <- recv s 100
-- putStrLn $ B.unpack a
return $
let r = parse (parser $ B.pack cmd) a
in maybeResult r
-- | Send a string to the radio.
serialSend :: SerialPort -> String -> IO ()
serialSend s value = do
send s $ B.pack value
threadDelay 100000
_ <- recv s 100
return ()
-- putStrLn $ B.unpack a