11 #include "definitions.h"
12 #include "wiiuse_internal.h"
15 void wiiuse_send_next_command(struct wiimote_t
*wm
)
17 struct cmd_blk_t
*cmd
= wm
->cmd_head
;
19 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return;
22 if(cmd
->state
!=CMD_READY
) return;
24 cmd
->state
= CMD_SENT
;
25 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_RUMBLE
)) cmd
->data
[1] |= 0x01;
27 wiiuse_io_write(wm
,cmd
->data
,cmd
->len
);
30 static __inline__
void __wiiuse_push_command(struct wiimote_t
*wm
,struct cmd_blk_t
*cmd
)
34 if(!wm
|| !cmd
) return;
37 cmd
->state
= CMD_READY
;
39 _CPU_ISR_Disable(level
);
40 if(wm
->cmd_head
==NULL
) {
41 wm
->cmd_head
= wm
->cmd_tail
= cmd
;
42 wiiuse_send_next_command(wm
);
44 wm
->cmd_tail
->next
= cmd
;
47 _CPU_ISR_Restore(level
);
51 struct wiimote_t
** wiiuse_init(int wiimotes
) {
53 extern void __wiiuse_sensorbar_enable(int enable
);
54 struct wiimote_t
** wiiuse_init(int wiimotes
, wii_event_cb event_cb
) {
57 struct wiimote_t
** wm
= NULL
;
62 wm
= __lwp_wkspace_allocate(sizeof(struct wiimote_t
*) * wiimotes
);
65 for (i
= 0; i
< wiimotes
; ++i
) {
66 wm
[i
] = __lwp_wkspace_allocate(sizeof(struct wiimote_t
));
67 memset(wm
[i
], 0, sizeof(struct wiimote_t
));
72 wm
[i
]->dev_handle
= 0;
73 wm
[i
]->stack
= WIIUSE_STACK_UNKNOWN
;
74 wm
[i
]->normal_timeout
= WIIMOTE_DEFAULT_TIMEOUT
;
75 wm
[i
]->exp_timeout
= WIIMOTE_EXP_TIMEOUT
;
76 wm
[i
]->timeout
= wm
[i
]->normal_timeout
;
79 wm
[i
]->bdaddr
= *BD_ADDR_ANY
;
80 wm
[i
]->event_cb
= event_cb
;
81 wiiuse_init_cmd_queue(wm
[i
]);
83 wm
[i
]->bdaddr
= *BDADDR_ANY
;
88 wm
[i
]->state
= WIIMOTE_INIT_STATES
;
89 wm
[i
]->flags
= WIIUSE_INIT_FLAGS
;
91 wm
[i
]->event
= WIIUSE_NONE
;
93 wm
[i
]->exp
.type
= EXP_NONE
;
95 wiiuse_set_aspect_ratio(wm
[i
], WIIUSE_ASPECT_4_3
);
96 wiiuse_set_ir_position(wm
[i
], WIIUSE_IR_ABOVE
);
98 wm
[i
]->accel_calib
.st_alpha
= WIIUSE_DEFAULT_SMOOTH_ALPHA
;
105 * @brief Set flags for the specified wiimote.
107 * @param wm Pointer to a wiimote_t structure.
108 * @param enable Flags to enable.
109 * @param disable Flags to disable.
111 * @return The flags set after 'enable' and 'disable' have been applied.
113 * The values 'enable' and 'disable' may be any flags OR'ed together.
114 * Flags are defined in wiiuse.h.
116 int wiiuse_set_flags(struct wiimote_t
* wm
, int enable
, int disable
) {
119 /* remove mutually exclusive flags */
124 wm
->flags
&= ~disable
;
130 * @brief Set if the wiimote should report motion sensing.
132 * @param wm Pointer to a wiimote_t structure.
133 * @param status 1 to enable, 0 to disable.
135 * Since reporting motion sensing sends a lot of data,
136 * the wiimote saves power by not transmitting it
139 void wiiuse_motion_sensing(struct wiimote_t
* wm
, int status
)
142 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_ACC
)) return;
143 WIIMOTE_ENABLE_STATE(wm
, WIIMOTE_STATE_ACC
);
145 if(!WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_ACC
)) return;
146 WIIMOTE_DISABLE_STATE(wm
, WIIMOTE_STATE_ACC
);
149 if(!WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) return;
151 wiiuse_status(wm
,NULL
);
155 * @brief Toggle the state of the rumble.
157 * @param wm Pointer to a wiimote_t structure.
159 void wiiuse_toggle_rumble(struct wiimote_t
* wm
)
163 WIIMOTE_TOGGLE_STATE(wm
, WIIMOTE_STATE_RUMBLE
);
164 if(!WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) return;
166 wiiuse_set_leds(wm
,wm
->leds
,NULL
);
170 * @brief Enable or disable the rumble.
172 * @param wm Pointer to a wiimote_t structure.
173 * @param status 1 to enable, 0 to disable.
175 void wiiuse_rumble(struct wiimote_t
* wm
, int status
)
177 if (status
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_RUMBLE
)) return;
178 else if(!status
&& !WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_RUMBLE
)) return;
179 wiiuse_toggle_rumble(wm
);
182 void wiiuse_set_leds(struct wiimote_t
*wm
,int leds
,cmd_blk_cb cb
)
186 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return;
188 wm
->leds
= (leds
&0xf0);
191 wiiuse_sendcmd(wm
,WM_CMD_LED
,&buf
,1,cb
);
194 int wiiuse_set_report_type(struct wiimote_t
*wm
,cmd_blk_cb cb
)
199 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
201 buf
[0] = (WIIMOTE_IS_FLAG_SET(wm
, WIIUSE_CONTINUOUS
) ? 0x04 : 0x00); /* set to 0x04 for continuous reporting */
204 motion
= WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_ACC
) || WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_IR
);
205 exp
= WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_EXP
);
206 ir
= WIIMOTE_IS_SET(wm
, WIIMOTE_STATE_IR
);
208 if (motion
&& ir
&& exp
) buf
[1] = WM_RPT_BTN_ACC_IR_EXP
;
209 else if (motion
&& exp
) buf
[1] = WM_RPT_BTN_ACC_EXP
;
210 else if (motion
&& ir
) buf
[1] = WM_RPT_BTN_ACC_IR
;
211 else if (ir
&& exp
) buf
[1] = WM_RPT_BTN_IR_EXP
;
212 else if (ir
) buf
[1] = WM_RPT_BTN_ACC_IR
;
213 else if (exp
) buf
[1] = WM_RPT_BTN_EXP
;
214 else if (motion
) buf
[1] = WM_RPT_BTN_ACC
;
215 else buf
[1] = WM_RPT_BTN
;
217 WIIUSE_DEBUG("Setting report type: 0x%x", buf
[1]);
219 wiiuse_sendcmd(wm
,WM_CMD_REPORT_TYPE
,buf
,2,cb
);
223 void wiiuse_status(struct wiimote_t
*wm
,cmd_blk_cb cb
)
227 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return;
230 wiiuse_sendcmd(wm
,WM_CMD_CTRL_STATUS
,&buf
,1,cb
);
233 int wiiuse_read_data(struct wiimote_t
*wm
,ubyte
*buffer
,uint addr
,uword len
,cmd_blk_cb cb
)
236 struct cmd_blk_t
*cmd
;
238 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
239 if(!buffer
|| !len
) return 0;
241 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
247 op
= (struct op_t
*)cmd
->data
;
248 op
->cmd
= WM_CMD_READ_DATA
;
251 op
->readdata
.addr
= BIG_ENDIAN_LONG(addr
);
252 op
->readdata
.size
= BIG_ENDIAN_SHORT(len
);
253 __wiiuse_push_command(wm
,cmd
);
258 int wiiuse_write_data(struct wiimote_t
*wm
,uint addr
,ubyte
*data
,ubyte len
,cmd_blk_cb cb
)
261 struct cmd_blk_t
*cmd
;
263 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
264 if(!data
|| !len
) return 0;
266 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
272 op
= (struct op_t
*)cmd
->data
;
273 op
->cmd
= WM_CMD_WRITE_DATA
;
276 op
->writedata
.addr
= BIG_ENDIAN_LONG(addr
);
277 op
->writedata
.size
= (len
&0x0f);
278 memcpy(op
->writedata
.data
,data
,len
);
279 memset(op
->writedata
.data
+len
,0,(16 - len
));
280 __wiiuse_push_command(wm
,cmd
);
285 int wiiuse_write_streamdata(struct wiimote_t
*wm
,ubyte
*data
,ubyte len
,cmd_blk_cb cb
)
287 struct cmd_blk_t
*cmd
;
289 if(!wm
|| !WIIMOTE_IS_CONNECTED(wm
)) return 0;
290 if(!data
|| !len
|| len
>20) return 0;
292 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
297 cmd
->data
[0] = WM_CMD_STREAM_DATA
;
298 cmd
->data
[1] = (len
<<3);
299 memcpy(cmd
->data
+2,data
,len
);
300 __wiiuse_push_command(wm
,cmd
);
305 int wiiuse_sendcmd(struct wiimote_t
*wm
,ubyte report_type
,ubyte
*msg
,int len
,cmd_blk_cb cb
)
307 struct cmd_blk_t
*cmd
;
309 cmd
= (struct cmd_blk_t
*)__lwp_queue_get(&wm
->cmdq
);
315 cmd
->data
[0] = report_type
;
316 memcpy(cmd
->data
+1,msg
,len
);
317 __wiiuse_push_command(wm
,cmd
);