11 #include "definitions.h"
12 #include "wiiuse_internal.h"
15 static struct wiimote_t
** __wm
= NULL
;
17 void wiiuse_send_next_command(struct wiimote_t
*wm
)
19 struct cmd_blk_t
*cmd
= wm
->cmd_head
;
21 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return;
24 if(cmd
->state
!=CMD_READY
) return;
26 cmd
->state
= CMD_SENT
;
27 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_RUMBLE
)) cmd
->data
[1] |= 0x01;
29 wiiuse_io_write(wm
,cmd
->data
,cmd
->len
);
32 static __inline__
void __wiiuse_push_command(struct wiimote_t
*wm
,struct cmd_blk_t
*cmd
)
36 if(!wm
|| !cmd
) return;
39 cmd
->state
= CMD_READY
;
41 _CPU_ISR_Disable(level
);
42 if(wm
->cmd_head
==NULL
) {
43 wm
->cmd_head
= wm
->cmd_tail
= cmd
;
44 wiiuse_send_next_command(wm
);
46 wm
->cmd_tail
->next
= cmd
;
49 _CPU_ISR_Restore(level
);
53 struct wiimote_t
** wiiuse_init(int wiimotes
) {
55 extern void __wiiuse_sensorbar_enable(int enable
);
56 struct wiimote_t
** wiiuse_init(int wiimotes
, wii_event_cb event_cb
) {
64 __wm
= __lwp_wkspace_allocate(sizeof(struct wiimote_t
*) * wiimotes
);
65 if(!__wm
) return NULL
;
66 memset(__wm
, 0, sizeof(struct wiimote_t
*) * wiimotes
);
69 for (i
= 0; i
< wiimotes
; ++i
) {
71 __wm
[i
] = __lwp_wkspace_allocate(sizeof(struct wiimote_t
));
73 memset(__wm
[i
], 0, sizeof(struct wiimote_t
));
77 __wm
[i
]->dev_handle
= 0;
78 __wm
[i
]->stack
= WIIUSE_STACK_UNKNOWN
;
79 __wm
[i
]->normal_timeout
= WIIMOTE_DEFAULT_TIMEOUT
;
80 __wm
[i
]->exp_timeout
= WIIMOTE_EXP_TIMEOUT
;
81 __wm
[i
]->timeout
= __wm
[i
]->normal_timeout
;
84 __wm
[i
]->bdaddr
= *BD_ADDR_ANY
;
85 __wm
[i
]->event_cb
= event_cb
;
86 wiiuse_init_cmd_queue(__wm
[i
]);
88 __wm
[i
]->bdaddr
= *BDADDR_ANY
;
89 __wm
[i
]->out_sock
= -1;
90 __wm
[i
]->in_sock
= -1;
93 __wm
[i
]->state
= WIIMOTE_INIT_STATES
;
94 __wm
[i
]->flags
= WIIUSE_INIT_FLAGS
;
96 __wm
[i
]->event
= WIIUSE_NONE
;
98 __wm
[i
]->exp
.type
= EXP_NONE
;
100 wiiuse_set_aspect_ratio(__wm
[i
], WIIUSE_ASPECT_4_3
);
101 wiiuse_set_ir_position(__wm
[i
], WIIUSE_IR_ABOVE
);
103 __wm
[i
]->accel_calib
.st_alpha
= WIIUSE_DEFAULT_SMOOTH_ALPHA
;
110 * @brief Set flags for the specified wiimote.
112 * @param wm Pointer to a wiimote_t structure.
113 * @param enable Flags to enable.
114 * @param disable Flags to disable.
116 * @return The flags set after 'enable' and 'disable' have been applied.
118 * The values 'enable' and 'disable' may be any flags OR'ed together.
119 * Flags are defined in wiiuse.h.
121 int wiiuse_set_flags(struct wiimote_t
* wm
, int enable
, int disable
) {
124 /* remove mutually exclusive flags */
129 wm
->flags
&= ~disable
;
135 * @brief Set if the wiimote should report motion sensing.
137 * @param wm Pointer to a wiimote_t structure.
138 * @param status 1 to enable, 0 to disable.
140 * Since reporting motion sensing sends a lot of data,
141 * the wiimote saves power by not transmitting it
144 void wiiuse_motion_sensing(struct wiimote_t
* wm
, int status
)
147 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_ACC
)) return;
148 WIIMOTE_ENABLE_STATE(wm
, WIIMOTE_STATE_ACC
);
150 if(!WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_ACC
)) return;
151 WIIMOTE_DISABLE_STATE(wm
, WIIMOTE_STATE_ACC
);
154 if(!WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) return;
156 wiiuse_status(wm
,NULL
);
160 * @brief Toggle the state of the rumble.
162 * @param wm Pointer to a wiimote_t structure.
164 void wiiuse_toggle_rumble(struct wiimote_t
* wm
)
168 WIIMOTE_TOGGLE_STATE(wm
, WIIMOTE_STATE_RUMBLE
);
169 if(!WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) return;
171 wiiuse_set_leds(wm
,wm
->leds
,NULL
);
175 * @brief Enable or disable the rumble.
177 * @param wm Pointer to a wiimote_t structure.
178 * @param status 1 to enable, 0 to disable.
180 void wiiuse_rumble(struct wiimote_t
* wm
, int status
)
182 if (status
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_RUMBLE
)) return;
183 else if(!status
&& !WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_RUMBLE
)) return;
184 wiiuse_toggle_rumble(wm
);
187 void wiiuse_set_leds(struct wiimote_t
*wm
,int leds
,cmd_blk_cb cb
)
191 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return;
193 wm
->leds
= (leds
&0xf0);
196 wiiuse_sendcmd(wm
,WM_CMD_LED
,&buf
,1,cb
);
199 int wiiuse_set_report_type(struct wiimote_t
*wm
,cmd_blk_cb cb
)
204 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
206 buf
[0] = (WIIMOTE_IS_FLAG_SET(wm
, WIIUSE_CONTINUOUS
) ? 0x04 : 0x00); /* set to 0x04 for continuous reporting */
209 motion
= WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_ACC
) || WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_IR
);
210 exp
= WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_EXP
);
211 ir
= WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_IR
);
213 if (motion
&& ir
&& exp
) buf
[1] = WM_RPT_BTN_ACC_IR_EXP
;
214 else if (motion
&& exp
) buf
[1] = WM_RPT_BTN_ACC_EXP
;
215 else if (motion
&& ir
) buf
[1] = WM_RPT_BTN_ACC_IR
;
216 else if (ir
&& exp
) buf
[1] = WM_RPT_BTN_IR_EXP
;
217 else if (ir
) buf
[1] = WM_RPT_BTN_ACC_IR
;
218 else if (exp
) buf
[1] = WM_RPT_BTN_EXP
;
219 else if (motion
) buf
[1] = WM_RPT_BTN_ACC
;
220 else buf
[1] = WM_RPT_BTN
;
222 WIIUSE_DEBUG("Setting report type: 0x%x", buf
[1]);
224 wiiuse_sendcmd(wm
,WM_CMD_REPORT_TYPE
,buf
,2,cb
);
228 void wiiuse_status(struct wiimote_t
*wm
,cmd_blk_cb cb
)
232 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return;
235 wiiuse_sendcmd(wm
,WM_CMD_CTRL_STATUS
,&buf
,1,cb
);
238 int wiiuse_read_data(struct wiimote_t
*wm
,ubyte
*buffer
,uint addr
,uword len
,cmd_blk_cb cb
)
241 struct cmd_blk_t
*cmd
;
243 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
244 if(!buffer
|| !len
) return 0;
246 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
252 op
= (struct op_t
*)cmd
->data
;
253 op
->cmd
= WM_CMD_READ_DATA
;
256 op
->readdata
.addr
= BIG_ENDIAN_LONG(addr
);
257 op
->readdata
.size
= BIG_ENDIAN_SHORT(len
);
258 __wiiuse_push_command(wm
,cmd
);
263 int wiiuse_write_data(struct wiimote_t
*wm
,uint addr
,ubyte
*data
,ubyte len
,cmd_blk_cb cb
)
266 struct cmd_blk_t
*cmd
;
268 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
269 if(!data
|| !len
) return 0;
271 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
277 op
= (struct op_t
*)cmd
->data
;
278 op
->cmd
= WM_CMD_WRITE_DATA
;
281 op
->writedata
.addr
= BIG_ENDIAN_LONG(addr
);
282 op
->writedata
.size
= (len
&0x0f);
283 memcpy(op
->writedata
.data
,data
,len
);
284 memset(op
->writedata
.data
+len
,0,(16 - len
));
285 __wiiuse_push_command(wm
,cmd
);
290 int wiiuse_write_streamdata(struct wiimote_t
*wm
,ubyte
*data
,ubyte len
,cmd_blk_cb cb
)
292 struct cmd_blk_t
*cmd
;
294 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
295 if(!data
|| !len
|| len
>20) return 0;
297 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
302 cmd
->data
[0] = WM_CMD_STREAM_DATA
;
303 cmd
->data
[1] = (len
<<3);
304 memcpy(cmd
->data
+2,data
,len
);
305 __wiiuse_push_command(wm
,cmd
);
310 int wiiuse_sendcmd(struct wiimote_t
*wm
,ubyte report_type
,ubyte
*msg
,int len
,cmd_blk_cb cb
)
312 struct cmd_blk_t
*cmd
;
314 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
320 cmd
->data
[0] = report_type
;
321 memcpy(cmd
->data
+1,msg
,len
);
322 __wiiuse_push_command(wm
,cmd
);