From 1b4d7204a8f0842dd0cde5c79e124dd21508526a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 7 Apr 2010 10:31:27 +0200 Subject: Added message interface --- src/HWiid.hsc | 183 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 127 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/HWiid.hsc b/src/HWiid.hsc index 3699a05..994aca1 100644 --- a/src/HWiid.hsc +++ b/src/HWiid.hsc @@ -3,20 +3,17 @@ module HWiid ( BDAddr(..) , Wiimote , WiimoteState(..) + , WiimoteMesg(..) , nullWiimote , bdAddrAny + , hwiidFlagMesgInterface + , hwiidFlagNonblock + , hwiidReportStatus + , hwiidReportButtons , hwiidLed1 , hwiidLed2 , hwiidLed3 , hwiidLed4 - , hwiidReportStatus - , hwiidReportButtons - , hwiidOpen - , hwiidOpenTimeout - , hwiidClose - , hwiidGetState - , hwiidSetReportMode - , hwiidSetLed , hwiidButton2 , hwiidButton1 , hwiidButtonB @@ -30,65 +27,43 @@ module HWiid ( BDAddr(..) , hwiidButtonPlus , hwiidNunchukButtonZ , hwiidNunchukButtonC + , hwiidOpen + , hwiidOpenTimeout + , hwiidClose + , hwiidGetState + , hwiidSetReportMode + , hwiidSetLed + , hwiidGetMesg ) where +import Data.Bits +import Data.Typeable import Data.Word import Foreign.C.Types -import Foreign.Marshal.Alloc (alloca) +import Foreign.Marshal.Alloc (alloca, free) +import Foreign.Marshal.Array (peekArray) import Foreign.Marshal.Utils (with) import Foreign.Ptr import Foreign.Storable +import System.Posix.Clock (TimeSpec) #include +hwiidFlagMesgInterface :: CInt +hwiidFlagMesgInterface = (#const CWIID_FLAG_MESG_IFC) -data BDAddr = BDAddr (Word8, Word8, Word8, Word8, Word8, Word8) - deriving (Eq, Ord, Show) - -instance Storable BDAddr where - sizeOf _ = (#size bdaddr_t) - alignment _ = alignment (undefined :: CInt) - - peek addr = do - b0 <- peekByteOff addr 0 - b1 <- peekByteOff addr 1 - b2 <- peekByteOff addr 2 - b3 <- peekByteOff addr 3 - b4 <- peekByteOff addr 4 - b5 <- peekByteOff addr 5 - return $ BDAddr (b0, b1, b2, b3, b4, b5) - - poke addr (BDAddr (b0, b1, b2, b3, b4, b5)) = do - pokeByteOff addr 0 b0 - pokeByteOff addr 1 b1 - pokeByteOff addr 2 b2 - pokeByteOff addr 3 b3 - pokeByteOff addr 4 b4 - pokeByteOff addr 5 b5 - -bdAddrAny :: BDAddr -bdAddrAny = BDAddr (0, 0, 0, 0, 0, 0) - +hwiidFlagNonblock :: CInt +hwiidFlagNonblock = (#const CWIID_FLAG_NONBLOCK) -data WiimoteState = WiimoteState - { stateButtons :: Word16 - } deriving (Eq, Show) -instance Storable WiimoteState where - sizeOf _ = (#size struct cwiid_state) - alignment _ = alignment (undefined :: CInt) - - peek state = do - buttons <- (#peek struct cwiid_state, buttons) state - return $ WiimoteState (buttons) - - poke state (WiimoteState (buttons)) = do - (#poke struct cwiid_state, buttons) state buttons +hwiidReportStatus :: Word8 +hwiidReportStatus = (#const CWIID_RPT_STATUS) +hwiidReportButtons :: Word8 +hwiidReportButtons = (#const CWIID_RPT_BTN) -newtype Wiimote = Wiimote (Ptr Wiimote) deriving (Eq, Ord, Show, Storable) hwiidLed1 :: Word8 hwiidLed1 = (#const CWIID_LED1_ON) @@ -102,12 +77,6 @@ hwiidLed3 = (#const CWIID_LED3_ON) hwiidLed4 :: Word8 hwiidLed4 = (#const CWIID_LED4_ON) -hwiidReportStatus :: Word8 -hwiidReportStatus = (#const CWIID_RPT_STATUS) - -hwiidReportButtons :: Word8 -hwiidReportButtons = (#const CWIID_RPT_BTN) - hwiidButton2 :: Word16 hwiidButton2 = (#const CWIID_BTN_2) @@ -150,6 +119,94 @@ hwiidNunchukButtonC :: Word16 hwiidNunchukButtonC = (#const CWIID_NUNCHUK_BTN_C) +hwiidMesgTypeStatus :: (#type enum cwiid_mesg_type) +hwiidMesgTypeStatus = (#const CWIID_MESG_STATUS) + +hwiidMesgTypeButton :: (#type enum cwiid_mesg_type) +hwiidMesgTypeButton = (#const CWIID_MESG_BTN) + + + +data BDAddr = BDAddr (Word8, Word8, Word8, Word8, Word8, Word8) + deriving (Eq, Ord, Show) + +instance Storable BDAddr where + sizeOf _ = (#size bdaddr_t) + alignment _ = alignment (undefined :: CInt) + + peek addr = do + b0 <- peekByteOff addr 0 + b1 <- peekByteOff addr 1 + b2 <- peekByteOff addr 2 + b3 <- peekByteOff addr 3 + b4 <- peekByteOff addr 4 + b5 <- peekByteOff addr 5 + return $ BDAddr (b0, b1, b2, b3, b4, b5) + + poke addr (BDAddr (b0, b1, b2, b3, b4, b5)) = do + pokeByteOff addr 0 b0 + pokeByteOff addr 1 b1 + pokeByteOff addr 2 b2 + pokeByteOff addr 3 b3 + pokeByteOff addr 4 b4 + pokeByteOff addr 5 b5 + +bdAddrAny :: BDAddr +bdAddrAny = BDAddr (0, 0, 0, 0, 0, 0) + + +data WiimoteState = WiimoteState + { stateButtons :: Word16 + } deriving (Eq, Show) + +instance Storable WiimoteState where + sizeOf _ = (#size struct cwiid_state) + alignment _ = alignment (undefined :: CInt) + + peek state = do + buttons <- (#peek struct cwiid_state, buttons) state + return $ WiimoteState (buttons) + + poke state (WiimoteState (buttons)) = do + (#poke struct cwiid_state, buttons) state buttons + + +data WiimoteMesg = WiimoteStatusMesg + { mesgType :: (#type enum cwiid_mesg_type) + , mesgBattery :: Word8 + , mesgExtensionType :: (#type enum cwiid_ext_type) + } + | WiimoteButtonMesg + { mesgType :: (#type enum cwiid_mesg_type) + , mesgButtons :: Word16 + } + | WiimoteMesgUnknown + deriving (Eq, Show) + +instance Storable WiimoteMesg where + sizeOf _ = (#size union cwiid_mesg) + alignment _ = alignment (undefined :: CInt) + + peek mesg = do + mesgtype <- (#peek union cwiid_mesg, type) mesg + + case () of + _ | mesgtype == hwiidMesgTypeStatus -> do + battery <- (#peek struct cwiid_status_mesg, battery) mesg + exttype <- (#peek struct cwiid_status_mesg, ext_type) mesg + return $ WiimoteStatusMesg mesgtype battery exttype + | mesgtype == hwiidMesgTypeButton -> do + buttons <- (#peek struct cwiid_btn_mesg, buttons) mesg + return $ WiimoteButtonMesg mesgtype buttons + | otherwise -> return WiimoteMesgUnknown + + + poke _ _ = error "Can't write WiimoteMesg" + + +newtype Wiimote = Wiimote (Ptr Wiimote) deriving (Eq, Ord, Show, Storable) + + nullWiimote :: Wiimote nullWiimote = Wiimote nullPtr @@ -181,3 +238,17 @@ foreign import ccall unsafe "cwiid.h cwiid_set_rpt_mode" foreign import ccall unsafe "cwiid.h cwiid_set_led" hwiidSetLed :: Wiimote -> Word8 -> IO CInt + +foreign import ccall unsafe "cwiid.h cwiid_get_mesg" + cwiid_get_mesg :: Wiimote -> Ptr CInt -> Ptr (Ptr WiimoteMesg) -> Ptr TimeSpec -> IO CInt + +hwiidGetMesg :: Wiimote -> IO [WiimoteMesg] +hwiidGetMesg wiimote = alloca $ \countptr -> alloca $ \arrayptr -> alloca $ \timestamp -> do + cwiid_get_mesg wiimote countptr arrayptr timestamp + count <- peek countptr + array <- peek arrayptr + + ret <- peekArray (fromIntegral count) array + free array + + return ret \ No newline at end of file -- cgit v1.2.3