93 control_dcid[0] = 0x60;
94 control_dcid[1] = 0x00;
95 interrupt_dcid[0] = 0x61;
96 interrupt_dcid[1] = 0x00;
105 activateNunchuck =
false;
106 motionValuesReset =
false;
107 activeConnection =
false;
108 motionPlusInside =
false;
117 if(!motionPlusInside) {
119 #ifdef DEBUG_USB_HOST
120 Notify(
PSTR(
"\r\nDeactivating Motion Plus"), 0x80);
124 timer = (uint32_t)millis() + 1000;
126 timer = (uint32_t)millis();
136 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
140 activeConnection =
true;
148 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
150 #ifdef DEBUG_USB_HOST
151 Notify(
PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
152 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
154 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
156 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
158 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
160 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
162 D_PrintHex<uint8_t > (l2capinbuf[14], 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);
183 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
185 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
187 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
189 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
191 D_PrintHex<uint8_t > (l2capinbuf[9], 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]) {
226 #ifdef DEBUG_USB_HOST
227 Notify(
PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
232 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
233 #ifdef DEBUG_USB_HOST
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);
255 D_PrintHex<uint8_t > (l2capinbuf[8], 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));
279 D_PrintHex<uint32_t > (ButtonState, 0x80);
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) {
302 #ifdef DEBUG_USB_HOST
303 if(!unknownExtensionConnected)
304 Notify(
PSTR(
"\r\nExtension connected"), 0x80);
306 unknownExtensionConnected =
true;
310 setReportMode(
false, 0x35);
312 #ifdef DEBUG_USB_HOST
313 Notify(
PSTR(
"\r\nExtension disconnected"), 0x80);
316 #ifdef DEBUG_USB_HOST
320 if(!activateNunchuck)
324 #ifdef DEBUG_USB_HOST
333 setReportMode(
false, 0x31);
338 setReportMode(
false, 0x31);
344 Notify(
PSTR(
"\r\nChecking battery level"), 0x80);
346 checkBatteryLevel =
false;
348 #ifdef DEBUG_USB_HOST
349 if(l2capinbuf[12] & 0x01)
350 Notify(
PSTR(
"\r\nWARNING: Battery is nearly empty"), 0x80);
355 if((l2capinbuf[12] & 0x0F) == 0) {
356 uint8_t reportLength = (l2capinbuf[12] >> 4) + 1;
358 if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
359 #ifdef DEBUG_USB_HOST
363 }
else if(l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
364 #ifdef DEBUG_USB_HOST
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) {
369 #ifdef DEBUG_USB_HOST
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) {
378 #ifdef DEBUG_USB_HOST
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) {
389 #ifdef DEBUG_USB_HOST
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) {
395 #ifdef DEBUG_USB_HOST
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) {
400 #ifdef DEBUG_USB_HOST
401 Notify(
PSTR(
"\r\nWii Balance Board connected"), 0x80);
403 setReportMode(
false, 0x32);
407 else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x24 && reportLength == 16) {
408 for(uint8_t i = 0; i < 2; i++) {
409 for(uint8_t j = 0; j < 4; j++)
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) {
413 for(uint8_t j = 0; j < 4; j++)
414 wiiBalanceBoardCal[2][j] = l2capinbuf[16 + 2 * j] | l2capinbuf[15 + 2 * j] << 8;
415 #ifdef DEBUG_USB_HOST
416 Notify(
PSTR(
"\r\nWii Balance Board calibration values read successfully"), 0x80);
421 #ifdef DEBUG_USB_HOST
424 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
425 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
427 for(uint8_t i = 0; i < reportLength; i++) {
428 D_PrintHex<uint8_t > (l2capinbuf[15 + i], 0x80);
437 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
438 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
443 #ifdef DEBUG_USB_HOST
444 if(l2capinbuf[13] != 0x00) {
446 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
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))
531 timer = (uint32_t)micros();
548 if((int32_t)((uint32_t)micros() - timer) > 1000000) {
549 #ifdef DEBUG_USB_HOST
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;
565 timer = (uint32_t)micros();
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;
582 #ifdef DEBUG_USB_HOST
583 Notify(
PSTR(
"\r\nExtension connected to Motion Plus"), 0x80);
587 if(extensionConnected && !unknownExtensionConnected) {
588 extensionConnected =
false;
589 unknownExtensionConnected =
true;
590 #ifdef DEBUG_USB_HOST
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);
611 #ifdef DEBUG_USB_HOST
613 Notify(
PSTR(
"\r\nUnknown Report type: "), 0x80);
614 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
624 void WII::L2CAP_task() {
625 switch(l2cap_state) {
629 #ifdef DEBUG_USB_HOST
630 Notify(
PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
638 #ifdef DEBUG_USB_HOST
639 Notify(
PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
655 #ifdef DEBUG_USB_HOST
656 Notify(
PSTR(
"\r\nSend HID Control Config Request"), 0x80);
666 #ifdef DEBUG_USB_HOST
667 Notify(
PSTR(
"\r\nSend HID Interrupt Connection Request"), 0x80);
677 #ifdef DEBUG_USB_HOST
678 Notify(
PSTR(
"\r\nSend HID Interrupt Config Request"), 0x80);
688 #ifdef DEBUG_USB_HOST
689 Notify(
PSTR(
"\r\nHID Channels Established"), 0x80);
702 #ifdef DEBUG_USB_HOST
703 Notify(
PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
713 #ifdef DEBUG_USB_HOST
714 Notify(
PSTR(
"\r\nDisconnected Control Channel"), 0x80);
729 switch(l2cap_state) {
733 activeConnection =
true;
735 #ifdef DEBUG_USB_HOST
736 Notify(
PSTR(
"\r\nSend HID Control Connection Request"), 0x80);
744 #ifdef DEBUG_USB_HOST
745 Notify(
PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
758 #ifdef DEBUG_USB_HOST
759 if(stateCounter == 0)
760 Notify(
PSTR(
"\r\nChecking if a Motion Plus is connected"), 0x80);
763 if(stateCounter % 200 == 0)
764 checkMotionPresent();
768 timer = (uint32_t)micros();
770 if(unknownExtensionConnected) {
771 #ifdef DEBUG_USB_HOST
772 Notify(
PSTR(
"\r\nA extension is also connected"), 0x80);
774 activateNunchuck =
true;
777 }
else if(stateCounter == 601) {
778 #ifdef DEBUG_USB_HOST
779 Notify(
PSTR(
"\r\nNo Motion Plus was detected"), 0x80);
787 #ifdef DEBUG_USB_HOST
788 if(stateCounter == 0)
789 Notify(
PSTR(
"\r\nChecking if there is any extension connected"), 0x80);
792 if(stateCounter == 1)
794 if(stateCounter == 100) {
795 if(unknownExtensionConnected)
799 }
else if(stateCounter == 200)
801 else if(stateCounter == 300) {
803 unknownExtensionConnected =
false;
804 }
else if(stateCounter == 400) {
806 #ifdef DEBUG_USB_HOST
807 Notify(
PSTR(
"\r\nReading Wii Balance Board calibration values"), 0x80);
809 readWiiBalanceBoardCalibration();
812 }
else if(stateCounter == 500) {
820 if(stateCounter == 1)
822 else if(stateCounter == 100)
823 activateMotionPlus();
824 else if(stateCounter == 200)
826 else if(stateCounter == 300) {
828 unknownExtensionConnected =
false;
842 if(unknownExtensionConnected) {
843 #ifdef DEBUG_USB_HOST
844 if(stateCounter == 0)
845 Notify(
PSTR(
"\r\nChecking extension port"), 0x80);
848 if(stateCounter == 50)
850 else if(stateCounter == 100)
852 else if(stateCounter == 150)
857 else if(stateCounter == 200)
859 else if(stateCounter == 250) {
861 #ifdef DEBUG_USB_HOST
862 Notify(
PSTR(
"\r\nNunchuck was reconnected"), 0x80);
864 activateNunchuck =
true;
869 }
else if(stateCounter == 300) {
871 #ifdef DEBUG_USB_HOST
872 Notify(
PSTR(
"\r\nReactivating the Motion Plus"), 0x80);
877 }
else if(stateCounter == 350)
878 activateMotionPlus();
879 else if(stateCounter == 400)
881 else if(stateCounter == 450) {
884 unknownExtensionConnected =
false;
896 void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
906 HID_Command(HIDBuffer, 3);
911 HIDBuffer[2] &= ~0x01;
912 HID_Command(HIDBuffer, 3);
917 HIDBuffer[2] |= 0x01;
918 HID_Command(HIDBuffer, 3);
923 HIDBuffer[2] ^= 0x01;
924 HID_Command(HIDBuffer, 3);
929 HIDBuffer[2] = value | (HIDBuffer[2] & 0x01);
930 HID_Command(HIDBuffer, 3);
936 HID_Command(HIDBuffer, 3);
945 HID_Command(HIDBuffer, 3);
952 HID_Command(HIDBuffer, 3);
957 HIDBuffer[2] = (HIDBuffer[2] & 0x01);
959 HIDBuffer[2] |= 0x10;
961 HIDBuffer[2] |= 0x20;
963 HIDBuffer[2] |= 0x40;
965 HID_Command(HIDBuffer, 3);
969 checkBatteryLevel =
true;
974 void WII::setReportMode(
bool continuous, uint8_t mode) {
976 Notify(
PSTR(
"\r\nReport mode was changed to: "), 0x80);
977 D_PrintHex<uint8_t > (mode, 0x80);
983 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
985 cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01);
987 HID_Command(cmd_buf, 4);
990 void WII::statusRequest() {
994 cmd_buf[2] = (HIDBuffer[2] & 0x01);
995 HID_Command(cmd_buf, 3);
1002 void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
1003 uint8_t cmd_buf[23];
1006 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1007 cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
1008 cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
1009 cmd_buf[5] = (uint8_t)(offset & 0xFF);
1012 for(; i < size; i++)
1013 cmd_buf[7 + i] = data[i];
1015 cmd_buf[7 + i] = 0x00;
1016 HID_Command(cmd_buf, 23);
1019 void WII::initExtension1() {
1022 writeData(0xA400F0, 1, buf);
1025 void WII::initExtension2() {
1028 writeData(0xA400FB, 1, buf);
1031 void WII::initMotionPlus() {
1034 writeData(0xA600F0, 1, buf);
1037 void WII::activateMotionPlus() {
1040 #ifdef DEBUG_USB_HOST
1041 Notify(
PSTR(
"\r\nActivating Wii U Pro Controller"), 0x80);
1044 }
else if(activateNunchuck) {
1045 #ifdef DEBUG_USB_HOST
1046 Notify(
PSTR(
"\r\nActivating Motion Plus in pass-through mode"), 0x80);
1052 #ifdef DEBUG_USB_HOST
1053 Notify(
PSTR(
"\r\nActivating Motion Plus in normal mode"), 0x80);
1057 writeData(0xA600FE, 1, buf);
1060 void WII::readData(uint32_t offset, uint16_t size,
bool EEPROM) {
1065 cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01);
1067 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1068 cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
1069 cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
1070 cmd_buf[5] = (uint8_t)(offset & 0xFF);
1071 cmd_buf[6] = (uint8_t)((size & 0xFF00) >> 8);
1072 cmd_buf[7] = (uint8_t)(size & 0xFF);
1074 HID_Command(cmd_buf, 8);
1077 void WII::readExtensionType() {
1078 readData(0xA400FA, 6,
false);
1081 void WII::readCalData() {
1082 readData(0x0016, 8,
true);
1085 void WII::checkMotionPresent() {
1086 readData(0xA600FA, 6,
false);
1089 void WII::readWiiBalanceBoardCalibration() {
1090 readData(0xA40024, 24,
false);
1097 int8_t WII::getButtonIndexWii(
ButtonEnum b) {
1103 int8_t WII::getButtonIndexWiiPro(
ButtonEnum b) {
1111 const int8_t index = getButtonIndexWiiPro(b);
if (index < 0)
return 0;
1115 const int8_t index = getButtonIndexWii(b);
if (index < 0)
return 0;
1123 const int8_t index = getButtonIndexWiiPro(b);
if (index < 0)
return 0;
1127 const int8_t index = getButtonIndexWii(b);
if (index < 0)
return 0;
1130 bool click = (ButtonClickState & button);
1131 ButtonClickState &= ~button;
1139 uint8_t output = hatValues[(uint8_t)a];
1140 if(output == 0xFF || output == 0x00)
1151 uint16_t output = hatValues[(uint8_t)a];
1175 if(wiiBalanceBoardRaw[pos] < wiiBalanceBoardCal[0][pos])
1177 else if(wiiBalanceBoardRaw[pos] < wiiBalanceBoardCal[1][pos])
1178 return 17.0f * (float)(wiiBalanceBoardRaw[pos] - wiiBalanceBoardCal[0][pos]) / (float)(wiiBalanceBoardCal[1][pos] - wiiBalanceBoardCal[0][pos]);
1180 return 17.0f + 17.0f * (float)(wiiBalanceBoardRaw[pos] - wiiBalanceBoardCal[1][pos]) / (float)(wiiBalanceBoardCal[2][pos] - wiiBalanceBoardCal[1][pos]);
1196 #ifdef DEBUG_USB_HOST
1197 Notify(
PSTR(
"\r\nEnable IR Camera1 Complete"), 0x80);
1202 #ifdef DEBUG_USB_HOST
1203 Notify(
PSTR(
"\r\nEnable IR Camera2 Complete"), 0x80);
1208 #ifdef DEBUG_USB_HOST
1209 Notify(
PSTR(
"\r\nWrote hex number 0x08"), 0x80);
1213 writeSensitivityBlock1();
1214 #ifdef DEBUG_USB_HOST
1215 Notify(
PSTR(
"\r\nWrote Sensitivity Block 1"), 0x80);
1219 writeSensitivityBlock2();
1220 #ifdef DEBUG_USB_HOST
1221 Notify(
PSTR(
"\r\nWrote Sensitivity Block 2"), 0x80);
1225 uint8_t mode_num = 0x03;
1226 setWiiModeNumber(mode_num);
1227 #ifdef DEBUG_USB_HOST
1228 Notify(
PSTR(
"\r\nSet Wii Mode Number To 0x"), 0x80);
1229 D_PrintHex<uint8_t > (mode_num, 0x80);
1234 #ifdef DEBUG_USB_HOST
1235 Notify(
PSTR(
"\r\nWrote Hex Number 0x08"), 0x80);
1239 setReportMode(
false, 0x33);
1241 #ifdef DEBUG_USB_HOST
1242 Notify(
PSTR(
"\r\nSet Report Mode to 0x33"), 0x80);
1247 #ifdef DEBUG_USB_HOST
1252 void WII::enableIRCamera1() {
1256 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1257 HID_Command(cmd_buf, 3);
1260 void WII::enableIRCamera2() {
1264 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1265 HID_Command(cmd_buf, 3);
1268 void WII::writeSensitivityBlock1() {
1280 writeData(0xB00000, 9, buf);
1283 void WII::writeSensitivityBlock2() {
1288 writeData(0xB0001A, 2, buf);
1291 void WII::write0x08Value() {
1293 writeData(0xb00030, 1, &cmd);
1296 void WII::setWiiModeNumber(uint8_t mode_number) {
1297 writeData(0xb00033, 1, &mode_number);
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define WII_CHECK_MOTION_PLUS_STATE
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_FLAG_CONTROL_CONNECTED
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_RESPONSE
#define l2cap_check_flag(flag)
#define l2cap_set_flag(flag)
#define L2CAP_CONTROL_CONNECT_REQUEST
#define L2CAP_CMD_COMMAND_REJECT
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_CMD_CONFIG_RESPONSE
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define WII_CHECK_EXTENSION_STATE
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_CONTROL_CONFIG_REQUEST
#define L2CAP_FLAG_INTERRUPT_CONNECTED
#define L2CAP_INTERRUPT_DISCONNECT
#define L2CAP_CONTROL_SUCCESS
#define L2CAP_CMD_CONNECTION_REQUEST
#define L2CAP_INTERRUPT_SETUP
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define WII_INIT_MOTION_PLUS_STATE
#define L2CAP_CMD_CONNECTION_RESPONSE
#define L2CAP_INTERRUPT_CONNECT_REQUEST
const uint32_t WII_BUTTONS[]
const uint32_t WII_PROCONTROLLER_BUTTONS[]
#define WII_FLAG_MOTION_PLUS_CONNECTED
#define WII_FLAG_CALIBRATE_BALANCE_BOARD
#define wii_check_flag(flag)
#define wii_clear_flag(flag)
#define WII_FLAG_NUNCHUCK_CONNECTED
#define wii_set_flag(flag)
bool l2capConnectionClaimed
void hci_disconnect(uint16_t handle)
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t *scid, uint16_t psm)
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
bool checkHciHandle(uint8_t *buf, uint16_t handle)
void(* pFuncOnInit)(void)
uint32_t l2cap_event_flag
bool wiiBalanceBoardConnected
bool wiiUProControllerConnected
WII(BTD *p, bool pair=false)
bool getButtonPress(ButtonEnum b)
void ACLData(uint8_t *ACLData)
uint8_t getAnalogHat(HatEnum a)
void setLedToggle(LEDEnum a)
float getWeight(BalanceBoardEnum pos)
bool getButtonClick(ButtonEnum b)
void setLedRaw(uint8_t value)
uint8_t getBatteryLevel()
constexpr int8_t ButtonIndex(ButtonEnum key)
#define pgm_read_byte(addr)
#define pgm_read_dword(addr)