25 const uint8_t
LEDS[] PROGMEM = {
95 control_dcid[0] = 0x60;
96 control_dcid[1] = 0x00;
97 interrupt_dcid[0] = 0x61;
98 interrupt_dcid[1] = 0x00;
107 activateNunchuck =
false;
108 motionValuesReset =
false;
109 activeConnection =
false;
110 motionPlusInside =
false;
113 l2cap_event_flag = 0;
118 if (!motionPlusInside) {
120 #ifdef DEBUG_USB_HOST
121 Notify(PSTR(
"\r\nDeactivating Motion Plus"), 0x80);
125 timer = millis() + 1000;
137 if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
141 activeConnection =
true;
147 if ((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) {
148 if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) {
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]) {
168 identifier = l2capinbuf[9];
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]) {
174 identifier = l2capinbuf[9];
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);
186 Notify(PSTR(
" SCID: "), 0x80);
187 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
189 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
190 Notify(PSTR(
" Identifier: "), 0x80);
191 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
193 if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
194 identifier = l2capinbuf[9];
195 control_scid[0] = l2capinbuf[14];
196 control_scid[1] = l2capinbuf[15];
198 }
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
199 identifier = l2capinbuf[9];
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]) {
208 identifier = l2capinbuf[9];
210 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
212 identifier = l2capinbuf[9];
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);
229 identifier = l2capinbuf[9];
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);
236 identifier = l2capinbuf[9];
241 if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
243 identifier = l2capinbuf[9];
245 }
else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
247 identifier = l2capinbuf[9];
253 identifier = l2capinbuf[9];
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));
278 Notify(PSTR(
"ButtonState: "), 0x80);
279 D_PrintHex<uint32_t > (ButtonState, 0x80);
280 Notify(PSTR(
"\r\n"), 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];
299 #ifdef DEBUG_USB_HOST
300 if (l2capinbuf[12] & 0x01)
301 Notify(PSTR(
"\r\nWARNING: Battery is nearly empty"), 0x80);
303 if (checkExtension) {
304 if (l2capinbuf[12] & 0x02) {
305 #ifdef DEBUG_USB_HOST
306 if (!unknownExtensionConnected)
307 Notify(PSTR(
"\r\nExtension connected"), 0x80);
309 unknownExtensionConnected =
true;
313 setReportMode(
false, 0x35);
315 #ifdef DEBUG_USB_HOST
316 Notify(PSTR(
"\r\nExtension disconnected"), 0x80);
319 #ifdef DEBUG_USB_HOST
320 Notify(PSTR(
" - from Motion Plus"), 0x80);
323 if (!activateNunchuck)
327 #ifdef DEBUG_USB_HOST
328 Notify(PSTR(
" - Nunchuck"), 0x80);
333 setReportMode(
false, 0x31);
335 setReportMode(
false, 0x31);
338 checkExtension =
true;
341 if ((l2capinbuf[12] & 0x0F) == 0) {
343 if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
344 #ifdef DEBUG_USB_HOST
345 Notify(PSTR(
"\r\nNunchuck connected"), 0x80);
348 }
else if (l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
349 #ifdef DEBUG_USB_HOST
350 Notify(PSTR(
"\r\nMotion Plus connected"), 0x80);
353 }
else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x05) {
354 #ifdef DEBUG_USB_HOST
355 Notify(PSTR(
"\r\nMotion Plus activated in normal mode"), 0x80);
361 setReportMode(
false, 0x35);
362 }
else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x05 && l2capinbuf[20] == 0x05) {
363 #ifdef DEBUG_USB_HOST
364 Notify(PSTR(
"\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
366 activateNunchuck =
false;
372 setReportMode(
false, 0x35);
373 }
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) {
374 #ifdef DEBUG_USB_HOST
375 Notify(PSTR(
"\r\nInactive Wii Motion Plus"), 0x80);
376 Notify(PSTR(
"\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension"), 0x80);
379 }
else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x01 && l2capinbuf[20] == 0x20) {
380 #ifdef DEBUG_USB_HOST
381 Notify(PSTR(
"\r\nWii U Pro Controller connected"), 0x80);
385 #ifdef DEBUG_USB_HOST
387 Notify(PSTR(
"\r\nUnknown Device: "), 0x80);
388 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
389 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
390 Notify(PSTR(
"\r\nData: "), 0x80);
391 for (uint8_t i = 0; i < ((l2capinbuf[12] >> 4) + 1); i++) {
392 D_PrintHex<uint8_t > (l2capinbuf[15 + i], 0x80);
400 Notify(PSTR(
"\r\nReport Error: "), 0x80);
401 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
402 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
407 #ifdef DEBUG_USB_HOST
408 if (l2capinbuf[13] != 0x00) {
409 Notify(PSTR(
"\r\nCommand failed: "), 0x80);
410 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
423 IR_object_x1 = (l2capinbuf[15] | ((uint16_t)(l2capinbuf[17] & 0x30) << 4));
424 IR_object_y1 = (l2capinbuf[16] | ((uint16_t)(l2capinbuf[17] & 0xC0) << 2));
425 IR_object_s1 = (l2capinbuf[17] & 0x0F);
427 IR_object_x2 = (l2capinbuf[18] | ((uint16_t)(l2capinbuf[20] & 0x30) << 4));
428 IR_object_y2 = (l2capinbuf[19] | ((uint16_t)(l2capinbuf[20] & 0xC0) << 2));
429 IR_object_s2 = (l2capinbuf[20] & 0x0F);
431 IR_object_x3 = (l2capinbuf[21] | ((uint16_t)(l2capinbuf[23] & 0x30) << 4));
432 IR_object_y3 = (l2capinbuf[22] | ((uint16_t)(l2capinbuf[23] & 0xC0) << 2));
433 IR_object_s3 = (l2capinbuf[23] & 0x0F);
435 IR_object_x4 = (l2capinbuf[24] | ((uint16_t)(l2capinbuf[26] & 0x30) << 4));
436 IR_object_y4 = (l2capinbuf[25] | ((uint16_t)(l2capinbuf[26] & 0xC0) << 2));
437 IR_object_s4 = (l2capinbuf[26] & 0x0F);
465 if (l2capinbuf[20] & 0x02) {
466 if (motionValuesReset) {
476 if (!(l2capinbuf[18] & 0x02))
478 if (!(l2capinbuf[18] & 0x01))
480 if (!(l2capinbuf[19] & 0x02))
506 if ((micros() - timer) > 1000000) {
507 #ifdef DEBUG_USB_HOST
508 Notify(PSTR(
"\r\nThe gyro values has been reset"), 0x80);
510 gyroYawZero = (l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6));
511 gyroRollZero = (l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6));
512 gyroPitchZero = (l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6));
522 motionValuesReset =
true;
528 hatValues[
HatX] = l2capinbuf[15];
529 hatValues[
HatY] = l2capinbuf[16];
530 accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
531 accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x20 >> 4)) - 416;
532 accZnunchuck = (((l2capinbuf[19] & 0xFE) << 2) | (l2capinbuf[20] & 0xC0 >> 5)) - 416;
536 if (l2capinbuf[19] & 0x01) {
537 if (!extensionConnected) {
538 extensionConnected =
true;
539 unknownExtensionConnected =
true;
540 #ifdef DEBUG_USB_HOST
541 Notify(PSTR(
"\r\nExtension connected to Motion Plus"), 0x80);
545 if (extensionConnected && !unknownExtensionConnected) {
546 extensionConnected =
false;
547 unknownExtensionConnected =
true;
548 #ifdef DEBUG_USB_HOST
549 Notify(PSTR(
"\r\nExtension disconnected from Motion Plus"), 0x80);
556 hatValues[
HatX] = l2capinbuf[15];
557 hatValues[
HatY] = l2capinbuf[16];
558 accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
559 accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
560 accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
562 hatValues[
LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
563 hatValues[
RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
564 hatValues[
LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
565 hatValues[
RightHatY] = (l2capinbuf[21] | l2capinbuf[22] << 8);
568 #ifdef DEBUG_USB_HOST
570 Notify(PSTR(
"\r\nUnknown Report type: "), 0x80);
571 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
581 void WII::L2CAP_task() {
582 switch (l2cap_state) {
586 #ifdef DEBUG_USB_HOST
587 Notify(PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
595 #ifdef DEBUG_USB_HOST
596 Notify(PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
612 #ifdef DEBUG_USB_HOST
613 Notify(PSTR(
"\r\nSend HID Control Config Request"), 0x80);
623 #ifdef DEBUG_USB_HOST
624 Notify(PSTR(
"\r\nSend HID Interrupt Connection Request"), 0x80);
634 #ifdef DEBUG_USB_HOST
635 Notify(PSTR(
"\r\nSend HID Interrupt Config Request"), 0x80);
645 #ifdef DEBUG_USB_HOST
646 Notify(PSTR(
"\r\nHID Channels Established"), 0x80);
659 #ifdef DEBUG_USB_HOST
660 Notify(PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
670 #ifdef DEBUG_USB_HOST
671 Notify(PSTR(
"\r\nDisconnected Control Channel"), 0x80);
675 l2cap_event_flag = 0;
686 switch (l2cap_state) {
690 activeConnection =
true;
692 #ifdef DEBUG_USB_HOST
693 Notify(PSTR(
"\r\nSend HID Control Connection Request"), 0x80);
696 l2cap_event_flag = 0;
701 #ifdef DEBUG_USB_HOST
702 Notify(PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
715 #ifdef DEBUG_USB_HOST
716 if (stateCounter == 0)
717 Notify(PSTR(
"\r\nChecking if a Motion Plus is connected"), 0x80);
720 if (stateCounter % 200 == 0)
721 checkMotionPresent();
727 if (unknownExtensionConnected) {
728 #ifdef DEBUG_USB_HOST
729 Notify(PSTR(
"\r\nA extension is also connected"), 0x80);
731 activateNunchuck =
true;
734 }
else if (stateCounter == 601) {
735 #ifdef DEBUG_USB_HOST
736 Notify(PSTR(
"\r\nNo Motion Plus was detected"), 0x80);
744 #ifdef DEBUG_USB_HOST
745 if (stateCounter == 0)
746 Notify(PSTR(
"\r\nChecking if there is any extension connected"), 0x80);
749 if (stateCounter == 1)
751 if (stateCounter == 100) {
752 if (unknownExtensionConnected)
756 }
else if (stateCounter == 200)
758 else if (stateCounter == 300) {
760 unknownExtensionConnected =
false;
761 }
else if (stateCounter == 400) {
769 if (stateCounter == 1)
771 else if (stateCounter == 100)
772 activateMotionPlus();
773 else if (stateCounter == 200)
775 else if (stateCounter == 300) {
777 unknownExtensionConnected =
false;
791 if (unknownExtensionConnected) {
792 #ifdef DEBUG_USB_HOST
793 if (stateCounter == 0)
794 Notify(PSTR(
"\r\nChecking extension port"), 0x80);
797 if (stateCounter == 50)
799 else if (stateCounter == 100)
801 else if (stateCounter == 150)
806 else if (stateCounter == 200)
808 else if (stateCounter == 250) {
810 #ifdef DEBUG_USB_HOST
811 Notify(PSTR(
"\r\nNunchuck was reconnected"), 0x80);
813 activateNunchuck =
true;
818 }
else if (stateCounter == 300) {
820 #ifdef DEBUG_USB_HOST
821 Notify(PSTR(
"\r\nReactivating the Motion Plus"), 0x80);
826 }
else if (stateCounter == 350)
827 activateMotionPlus();
828 else if (stateCounter == 400)
830 else if (stateCounter == 450) {
833 unknownExtensionConnected =
false;
845 void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
846 if (motionPlusInside)
847 pBtd->
L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]);
849 pBtd->
L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
855 HID_Command(HIDBuffer, 3);
860 HIDBuffer[2] &= ~0x01;
861 HID_Command(HIDBuffer, 3);
866 HIDBuffer[2] |= 0x01;
867 HID_Command(HIDBuffer, 3);
872 HIDBuffer[2] ^= 0x01;
873 HID_Command(HIDBuffer, 3);
878 HIDBuffer[2] = value | (HIDBuffer[2] & 0x01);
879 HID_Command(HIDBuffer, 3);
883 HIDBuffer[2] &= ~(pgm_read_byte(&
LEDS[(uint8_t)a]));
884 HID_Command(HIDBuffer, 3);
889 HIDBuffer[2] |= pgm_read_byte(&
LEDS[(uint8_t)a]);
890 HID_Command(HIDBuffer, 3);
895 HIDBuffer[2] ^= pgm_read_byte(&
LEDS[(uint8_t)a]);
896 HID_Command(HIDBuffer, 3);
901 HIDBuffer[2] = (HIDBuffer[2] & 0x01);
903 HIDBuffer[2] |= 0x10;
905 HIDBuffer[2] |= 0x20;
907 HIDBuffer[2] |= 0x40;
909 HID_Command(HIDBuffer, 3);
913 checkExtension =
false;
918 void WII::setReportMode(
bool continuous, uint8_t mode) {
923 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
925 cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01);
927 HID_Command(cmd_buf, 4);
930 void WII::statusRequest() {
934 cmd_buf[2] = (HIDBuffer[2] & 0x01);
935 HID_Command(cmd_buf, 3);
942 void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
946 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
947 cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
948 cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
949 cmd_buf[5] = (uint8_t)(offset & 0xFF);
952 for (; i < size; i++)
953 cmd_buf[7 + i] = data[i];
955 cmd_buf[7 + i] = 0x00;
956 HID_Command(cmd_buf, 23);
959 void WII::initExtension1() {
962 writeData(0xA400F0, 1, buf);
965 void WII::initExtension2() {
968 writeData(0xA400FB, 1, buf);
971 void WII::initMotionPlus() {
974 writeData(0xA600F0, 1, buf);
977 void WII::activateMotionPlus() {
980 #ifdef DEBUG_USB_HOST
981 Notify(PSTR(
"\r\nActivating Wii U Pro Controller"), 0x80);
984 }
else if (activateNunchuck) {
985 #ifdef DEBUG_USB_HOST
986 Notify(PSTR(
"\r\nActivating Motion Plus in pass-through mode"), 0x80);
992 #ifdef DEBUG_USB_HOST
993 Notify(PSTR(
"\r\nActivating Motion Plus in normal mode"), 0x80);
997 writeData(0xA600FE, 1, buf);
1000 void WII::readData(uint32_t offset, uint16_t size,
bool EEPROM) {
1005 cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01);
1007 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1008 cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
1009 cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
1010 cmd_buf[5] = (uint8_t)(offset & 0xFF);
1011 cmd_buf[6] = (uint8_t)((size & 0xFF00) >> 8);
1012 cmd_buf[7] = (uint8_t)(size & 0xFF);
1014 HID_Command(cmd_buf, 8);
1017 void WII::readExtensionType() {
1018 readData(0xA400FA, 6,
false);
1021 void WII::readCalData() {
1022 readData(0x0016, 8,
true);
1025 void WII::checkMotionPresent() {
1026 readData(0xA600FA, 6,
false);
1038 return (ButtonState & pgm_read_dword(&
BUTTONS[(uint8_t)b]));
1046 button = pgm_read_dword(&
BUTTONS[(uint8_t)b]);
1047 bool click = (ButtonClickState & button);
1048 ButtonClickState &= ~button;
1056 uint8_t output = hatValues[(uint8_t)a];
1057 if (output == 0xFF || output == 0x00)
1068 uint16_t output = hatValues[(uint8_t)a];
1076 void WII::onInit() {
1092 #ifdef DEBUG_USB_HOST
1093 Notify(PSTR(
"\r\nEnable IR Camera1 Complete"), 0x80);
1098 #ifdef DEBUG_USB_HOST
1099 Notify(PSTR(
"\r\nEnable IR Camera2 Complete"), 0x80);
1104 #ifdef DEBUG_USB_HOST
1105 Notify(PSTR(
"\r\nWrote hex number 0x08"), 0x80);
1109 writeSensitivityBlock1();
1110 #ifdef DEBUG_USB_HOST
1111 Notify(PSTR(
"\r\nWrote Sensitivity Block 1"), 0x80);
1115 writeSensitivityBlock2();
1116 #ifdef DEBUG_USB_HOST
1117 Notify(PSTR(
"\r\nWrote Sensitivity Block 2"), 0x80);
1121 uint8_t mode_num = 0x03;
1122 setWiiModeNumber(mode_num);
1123 #ifdef DEBUG_USB_HOST
1124 Notify(PSTR(
"\r\nSet Wii Mode Number To 0x"), 0x80);
1125 D_PrintHex<uint8_t > (mode_num, 0x80);
1130 #ifdef DEBUG_USB_HOST
1131 Notify(PSTR(
"\r\nWrote Hex Number 0x08"), 0x80);
1135 setReportMode(
false, 0x33);
1137 #ifdef DEBUG_USB_HOST
1138 Notify(PSTR(
"\r\nSet Report Mode to 0x33"), 0x80);
1143 #ifdef DEBUG_USB_HOST
1144 Notify(PSTR(
"\r\nIR Initialized"), 0x80);
1148 void WII::enableIRCamera1() {
1152 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1153 HID_Command(cmd_buf, 3);
1156 void WII::enableIRCamera2() {
1160 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1161 HID_Command(cmd_buf, 3);
1164 void WII::writeSensitivityBlock1() {
1176 writeData(0xB00000, 9, buf);
1179 void WII::writeSensitivityBlock2() {
1184 writeData(0xB0001A, 2, buf);
1187 void WII::write0x08Value() {
1189 writeData(0xb00030, 1, &cmd);
1192 void WII::setWiiModeNumber(uint8_t mode_number) {
1193 writeData(0xb00033, 1, &mode_number);
#define nunchuck_connected_flag
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t *scid, uint16_t psm)
#define L2CAP_CONTROL_CONFIG_REQUEST
void setLedRaw(uint8_t value)
#define WII_FLAG_NUNCHUCK_CONNECTED
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
virtual void ACLData(uint8_t *ACLData)
#define l2cap_disconnect_response_interrupt_flag
#define motion_plus_connected_flag
uint8_t getBatteryLevel()
virtual void disconnect()
bool getButtonClick(Button b)
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define l2cap_connection_request_control_flag
const uint32_t PROCONTROLLERBUTTONS[]
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define L2CAP_FLAG_INTERRUPT_CONNECTED
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define l2cap_connection_request_interrupt_flag
WII(BTD *p, bool pair=false)
#define L2CAP_INTERRUPT_DISCONNECT
void hci_disconnect(uint16_t handle)
#define WII_FLAG_MOTION_PLUS_CONNECTED
#define L2CAP_CONTROL_CONNECT_REQUEST
bool wiiUProControllerConnected
#define L2CAP_INTERRUPT_SETUP
#define l2cap_disconnect_response_control_flag
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define L2CAP_CHECK_EXTENSION_STATE
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_INTERRUPT_CONNECT_REQUEST
int8_t registerServiceClass(BluetoothService *pService)
bool l2capConnectionClaimed
bool getButtonPress(Button b)
#define L2CAP_CMD_DISCONNECT_RESPONSE
#define L2CAP_CMD_CONNECTION_RESPONSE
#define l2cap_connected_interrupt_flag
#define L2CAP_CMD_CONFIG_RESPONSE
#define L2CAP_FLAG_CONTROL_CONNECTED
#define l2cap_config_success_control_flag
#define l2cap_config_success_interrupt_flag
#define l2cap_connected_control_flag
#define L2CAP_CHECK_MOTION_PLUS_STATE
#define L2CAP_CONTROL_SUCCESS
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_CMD_CONNECTION_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define L2CAP_INIT_MOTION_PLUS_STATE
uint8_t getAnalogHat(Hat a)
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_CMD_COMMAND_REJECT