136 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
140 activeConnection =
true;
148 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
151 Notify(
PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
165 if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) ==
SUCCESSFUL)) {
166 if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
169 control_scid[0] = l2capinbuf[12];
170 control_scid[1] = l2capinbuf[13];
172 }
else if(l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
175 interrupt_scid[0] = l2capinbuf[12];
176 interrupt_scid[1] = l2capinbuf[13];
182 Notify(
PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
193 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
195 control_scid[0] = l2capinbuf[14];
196 control_scid[1] = l2capinbuf[15];
198 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
200 interrupt_scid[0] = l2capinbuf[14];
201 interrupt_scid[1] = l2capinbuf[15];
205 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
206 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
210 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
217 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
220 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
225 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
227 Notify(
PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
232 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
234 Notify(
PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
241 if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
245 }
else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
254 Notify(
PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
258 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
260 if(l2capinbuf[8] == 0xA1) {
261 if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || (l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) || l2capinbuf[9] == 0x3e || l2capinbuf[9] == 0x3f) {
262 if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33)
263 ButtonState = (
uint32_t)((l2capinbuf[10] & 0x1F) | ((
uint16_t)(l2capinbuf[11] & 0x9F) << 8));
265 ButtonState = (
uint32_t)(((~l2capinbuf[23]) & 0xFE) | ((
uint16_t)(~l2capinbuf[24]) << 8) | ((
uint32_t)((~l2capinbuf[25]) & 0x03) << 16));
267 if(l2capinbuf[20] & 0x02)
268 ButtonState = (
uint32_t)((l2capinbuf[10] & 0x1F) | ((
uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((
uint32_t)(ButtonState & 0xFFFF0000)));
270 ButtonState = (
uint32_t)((l2capinbuf[10] & 0x1F) | ((
uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((
uint32_t)((~l2capinbuf[20]) & 0x0C) << 14));
273 ButtonState = (
uint32_t)((l2capinbuf[10] & 0x1F) | ((
uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((
uint32_t)((~l2capinbuf[20]) & 0x03) << 16));
275 else if(!unknownExtensionConnected)
276 ButtonState = (
uint32_t)((l2capinbuf[10] & 0x1F) | ((
uint16_t)(l2capinbuf[11] & 0x9F) << 8));
282 if(ButtonState != OldButtonState) {
283 ButtonClickState = ButtonState & ~OldButtonState;
284 OldButtonState = ButtonState;
287 if(l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33 || l2capinbuf[9] == 0x35 || l2capinbuf[9] == 0x37) {
288 accXwiimote = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5)) - 500;
289 accYwiimote = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4)) - 500;
290 accZwiimote = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5)) - 500;
292 switch(l2capinbuf[9]) {
295 Notify(
PSTR(
"\r\nStatus report was received"), 0x80);
297 wiiState = l2capinbuf[12];
298 batteryLevel = l2capinbuf[15];
300 if(!checkBatteryLevel) {
301 if(l2capinbuf[12] & 0x02) {
303 if(!unknownExtensionConnected)
304 Notify(
PSTR(
"\r\nExtension connected"), 0x80);
306 unknownExtensionConnected =
true;
310 setReportMode(
false, 0x35);
313 Notify(
PSTR(
"\r\nExtension disconnected"), 0x80);
320 if(!activateNunchuck)
333 setReportMode(
false, 0x31);
338 setReportMode(
false, 0x31);
344 Notify(
PSTR(
"\r\nChecking battery level"), 0x80);
346 checkBatteryLevel =
false;
349 if(l2capinbuf[12] & 0x01)
350 Notify(
PSTR(
"\r\nWARNING: Battery is nearly empty"), 0x80);
355 if((l2capinbuf[12] & 0x0F) == 0) {
358 if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
363 }
else if(l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
365 Notify(
PSTR(
"\r\nMotion Plus connected"), 0x80);
368 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x05) {
370 Notify(
PSTR(
"\r\nMotion Plus activated in normal mode"), 0x80);
376 setReportMode(
false, 0x35);
377 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x05 && l2capinbuf[20] == 0x05) {
379 Notify(
PSTR(
"\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
381 activateNunchuck =
false;
387 setReportMode(
false, 0x35);
388 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA6 && l2capinbuf[18] == 0x20 && (l2capinbuf[19] == 0x00 || l2capinbuf[19] == 0x04 || l2capinbuf[19] == 0x05 || l2capinbuf[19] == 0x07) && l2capinbuf[20] == 0x05) {
390 Notify(
PSTR(
"\r\nInactive Wii Motion Plus"), 0x80);
391 Notify(
PSTR(
"\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension"), 0x80);
394 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x01 && l2capinbuf[20] == 0x20) {
396 Notify(
PSTR(
"\r\nWii U Pro Controller connected"), 0x80);
399 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x02) {
401 Notify(
PSTR(
"\r\nWii Balance Board connected"), 0x80);
403 setReportMode(
false, 0x32);
407 else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x24 &&
reportLength == 16) {
410 wiiBalanceBoardCal[
i][
j] = l2capinbuf[16 + 8 *
i + 2 *
j] | l2capinbuf[15 + 8 *
i + 2 *
j] << 8;
412 }
else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x34 &&
reportLength == 8) {
414 wiiBalanceBoardCal[2][
j] = l2capinbuf[16 + 2 *
j] | l2capinbuf[15 + 2 *
j] << 8;
416 Notify(
PSTR(
"\r\nWii Balance Board calibration values read successfully"), 0x80);
444 if(l2capinbuf[13] != 0x00) {
456 wiiBalanceBoardRaw[
TopRight] = l2capinbuf[13] | l2capinbuf[12] << 8;
457 wiiBalanceBoardRaw[
BotRight] = l2capinbuf[15] | l2capinbuf[14] << 8;
458 wiiBalanceBoardRaw[
TopLeft] = l2capinbuf[17] | l2capinbuf[16] << 8;
459 wiiBalanceBoardRaw[
BotLeft] = l2capinbuf[19] | l2capinbuf[18] << 8;
464 IR_object_x1 = (l2capinbuf[15] | ((
uint16_t)(l2capinbuf[17] & 0x30) << 4));
465 IR_object_y1 = (l2capinbuf[16] | ((
uint16_t)(l2capinbuf[17] & 0xC0) << 2));
466 IR_object_s1 = (l2capinbuf[17] & 0x0F);
468 IR_object_x2 = (l2capinbuf[18] | ((
uint16_t)(l2capinbuf[20] & 0x30) << 4));
469 IR_object_y2 = (l2capinbuf[19] | ((
uint16_t)(l2capinbuf[20] & 0xC0) << 2));
470 IR_object_s2 = (l2capinbuf[20] & 0x0F);
472 IR_object_x3 = (l2capinbuf[21] | ((
uint16_t)(l2capinbuf[23] & 0x30) << 4));
473 IR_object_y3 = (l2capinbuf[22] | ((
uint16_t)(l2capinbuf[23] & 0xC0) << 2));
474 IR_object_s3 = (l2capinbuf[23] & 0x0F);
476 IR_object_x4 = (l2capinbuf[24] | ((
uint16_t)(l2capinbuf[26] & 0x30) << 4));
477 IR_object_y4 = (l2capinbuf[25] | ((
uint16_t)(l2capinbuf[26] & 0xC0) << 2));
478 IR_object_s4 = (l2capinbuf[26] & 0x0F);
507 if(l2capinbuf[20] & 0x02) {
508 if(motionValuesReset) {
518 if(!(l2capinbuf[18] & 0x02))
520 if(!(l2capinbuf[18] & 0x01))
522 if(!(l2capinbuf[19] & 0x02))
550 Notify(
PSTR(
"\r\nThe gyro values has been reset"), 0x80);
552 gyroYawZero = (l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6));
553 gyroRollZero = (l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6));
554 gyroPitchZero = (l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6));
564 motionValuesReset =
true;
570 hatValues[
HatX] = l2capinbuf[15];
571 hatValues[
HatY] = l2capinbuf[16];
572 accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
573 accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x20 >> 4)) - 416;
574 accZnunchuck = (((l2capinbuf[19] & 0xFE) << 2) | (l2capinbuf[20] & 0xC0 >> 5)) - 416;
578 if(l2capinbuf[19] & 0x01) {
579 if(!extensionConnected) {
580 extensionConnected =
true;
581 unknownExtensionConnected =
true;
583 Notify(
PSTR(
"\r\nExtension connected to Motion Plus"), 0x80);
587 if(extensionConnected && !unknownExtensionConnected) {
588 extensionConnected =
false;
589 unknownExtensionConnected =
true;
591 Notify(
PSTR(
"\r\nExtension disconnected from Motion Plus"), 0x80);
598 hatValues[
HatX] = l2capinbuf[15];
599 hatValues[
HatY] = l2capinbuf[16];
600 accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
601 accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
602 accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
604 hatValues[
LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
605 hatValues[
RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
606 hatValues[
LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
607 hatValues[
RightHatY] = (l2capinbuf[21] | l2capinbuf[22] << 8);
613 Notify(
PSTR(
"\r\nUnknown Report type: "), 0x80);