Added message interface

This commit is contained in:
Matthias Schiffer 2010-04-07 10:31:27 +02:00
parent 050f1283eb
commit 1b4d7204a8
2 changed files with 128 additions and 57 deletions

View file

@ -11,7 +11,7 @@ build-type: Simple
Cabal-Version: >=1.2
library
build-depends: base >= 4
build-depends: base >= 4, clock
exposed-modules: HWiid
hs-source-dirs: src
extra-libraries: cwiid

View file

@ -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 <cwiid.h>
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)
hwiidReportStatus :: Word8
hwiidReportStatus = (#const CWIID_RPT_STATUS)
instance Storable WiimoteState where
sizeOf _ = (#size struct cwiid_state)
alignment _ = alignment (undefined :: CInt)
hwiidReportButtons :: Word8
hwiidReportButtons = (#const CWIID_RPT_BTN)
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
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