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 Cabal-Version: >=1.2
library library
build-depends: base >= 4 build-depends: base >= 4, clock
exposed-modules: HWiid exposed-modules: HWiid
hs-source-dirs: src hs-source-dirs: src
extra-libraries: cwiid extra-libraries: cwiid

View file

@ -3,20 +3,17 @@
module HWiid ( BDAddr(..) module HWiid ( BDAddr(..)
, Wiimote , Wiimote
, WiimoteState(..) , WiimoteState(..)
, WiimoteMesg(..)
, nullWiimote , nullWiimote
, bdAddrAny , bdAddrAny
, hwiidFlagMesgInterface
, hwiidFlagNonblock
, hwiidReportStatus
, hwiidReportButtons
, hwiidLed1 , hwiidLed1
, hwiidLed2 , hwiidLed2
, hwiidLed3 , hwiidLed3
, hwiidLed4 , hwiidLed4
, hwiidReportStatus
, hwiidReportButtons
, hwiidOpen
, hwiidOpenTimeout
, hwiidClose
, hwiidGetState
, hwiidSetReportMode
, hwiidSetLed
, hwiidButton2 , hwiidButton2
, hwiidButton1 , hwiidButton1
, hwiidButtonB , hwiidButtonB
@ -30,65 +27,43 @@ module HWiid ( BDAddr(..)
, hwiidButtonPlus , hwiidButtonPlus
, hwiidNunchukButtonZ , hwiidNunchukButtonZ
, hwiidNunchukButtonC , hwiidNunchukButtonC
, hwiidOpen
, hwiidOpenTimeout
, hwiidClose
, hwiidGetState
, hwiidSetReportMode
, hwiidSetLed
, hwiidGetMesg
) where ) where
import Data.Bits
import Data.Typeable
import Data.Word import Data.Word
import Foreign.C.Types 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.Marshal.Utils (with)
import Foreign.Ptr import Foreign.Ptr
import Foreign.Storable import Foreign.Storable
import System.Posix.Clock (TimeSpec)
#include <cwiid.h> #include <cwiid.h>
hwiidFlagMesgInterface :: CInt
hwiidFlagMesgInterface = (#const CWIID_FLAG_MESG_IFC)
data BDAddr = BDAddr (Word8, Word8, Word8, Word8, Word8, Word8) hwiidFlagNonblock :: CInt
deriving (Eq, Ord, Show) hwiidFlagNonblock = (#const CWIID_FLAG_NONBLOCK)
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 hwiidReportStatus :: Word8
{ stateButtons :: Word16 hwiidReportStatus = (#const CWIID_RPT_STATUS)
} deriving (Eq, Show)
instance Storable WiimoteState where hwiidReportButtons :: Word8
sizeOf _ = (#size struct cwiid_state) hwiidReportButtons = (#const CWIID_RPT_BTN)
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
newtype Wiimote = Wiimote (Ptr Wiimote) deriving (Eq, Ord, Show, Storable)
hwiidLed1 :: Word8 hwiidLed1 :: Word8
hwiidLed1 = (#const CWIID_LED1_ON) hwiidLed1 = (#const CWIID_LED1_ON)
@ -102,12 +77,6 @@ hwiidLed3 = (#const CWIID_LED3_ON)
hwiidLed4 :: Word8 hwiidLed4 :: Word8
hwiidLed4 = (#const CWIID_LED4_ON) hwiidLed4 = (#const CWIID_LED4_ON)
hwiidReportStatus :: Word8
hwiidReportStatus = (#const CWIID_RPT_STATUS)
hwiidReportButtons :: Word8
hwiidReportButtons = (#const CWIID_RPT_BTN)
hwiidButton2 :: Word16 hwiidButton2 :: Word16
hwiidButton2 = (#const CWIID_BTN_2) hwiidButton2 = (#const CWIID_BTN_2)
@ -150,6 +119,94 @@ hwiidNunchukButtonC :: Word16
hwiidNunchukButtonC = (#const CWIID_NUNCHUK_BTN_C) 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
nullWiimote = Wiimote nullPtr 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" foreign import ccall unsafe "cwiid.h cwiid_set_led"
hwiidSetLed :: Wiimote -> Word8 -> IO CInt 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