96 control_dcid[0] = 0x60;
97 control_dcid[1] = 0x00;
98 interrupt_dcid[0] = 0x61;
99 interrupt_dcid[1] = 0x00;
108 activateNunchuck =
false;
109 motionValuesReset =
false;
110 activeConnection =
false;
111 motionPlusInside =
false;
114 l2cap_event_flag = 0;
119 if(!motionPlusInside) {
121 #ifdef DEBUG_USB_HOST
122 Notify(PSTR(
"\r\nDeactivating Motion Plus"), 0x80);
126 timer = millis() + 1000;
138 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
142 activeConnection =
true;
150 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
152 #ifdef DEBUG_USB_HOST
153 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
154 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
156 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
158 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
160 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
162 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
164 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
167 if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) ==
SUCCESSFUL)) {
168 if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
170 identifier = l2capinbuf[9];
171 control_scid[0] = l2capinbuf[12];
172 control_scid[1] = l2capinbuf[13];
174 }
else if(l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
176 identifier = l2capinbuf[9];
177 interrupt_scid[0] = l2capinbuf[12];
178 interrupt_scid[1] = l2capinbuf[13];
184 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
185 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
187 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
188 Notify(PSTR(
" SCID: "), 0x80);
189 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
191 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
192 Notify(PSTR(
" Identifier: "), 0x80);
193 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
195 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
196 identifier = l2capinbuf[9];
197 control_scid[0] = l2capinbuf[14];
198 control_scid[1] = l2capinbuf[15];
200 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
201 identifier = l2capinbuf[9];
202 interrupt_scid[0] = l2capinbuf[14];
203 interrupt_scid[1] = l2capinbuf[15];
207 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
208 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
210 identifier = l2capinbuf[9];
212 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
214 identifier = l2capinbuf[9];
219 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
222 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
227 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
228 #ifdef DEBUG_USB_HOST
229 Notify(PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
231 identifier = l2capinbuf[9];
234 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
235 #ifdef DEBUG_USB_HOST
236 Notify(PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
238 identifier = l2capinbuf[9];
243 if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
245 identifier = l2capinbuf[9];
247 }
else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
249 identifier = l2capinbuf[9];
255 identifier = l2capinbuf[9];
256 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
257 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
260 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
262 if(l2capinbuf[8] == 0xA1) {
263 if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || (l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) || l2capinbuf[9] == 0x3e || l2capinbuf[9] == 0x3f) {
264 if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33)
265 ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
267 ButtonState = (uint32_t)(((~l2capinbuf[23]) & 0xFE) | ((uint16_t)(~l2capinbuf[24]) << 8) | ((uint32_t)((~l2capinbuf[25]) & 0x03) << 16));
269 if(l2capinbuf[20] & 0x02)
270 ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)(ButtonState & 0xFFFF0000)));
272 ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x0C) << 14));
275 ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x03) << 16));
277 else if(!unknownExtensionConnected)
278 ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
280 Notify(PSTR(
"ButtonState: "), 0x80);
281 D_PrintHex<uint32_t > (ButtonState, 0x80);
282 Notify(PSTR(
"\r\n"), 0x80);
284 if(ButtonState != OldButtonState) {
285 ButtonClickState = ButtonState & ~OldButtonState;
286 OldButtonState = ButtonState;
289 if(l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33 || l2capinbuf[9] == 0x35 || l2capinbuf[9] == 0x37) {
290 accXwiimote = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5)) - 500;
291 accYwiimote = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4)) - 500;
292 accZwiimote = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5)) - 500;
294 switch(l2capinbuf[9]) {
297 Notify(PSTR(
"\r\nStatus report was received"), 0x80);
299 wiiState = l2capinbuf[12];
300 batteryLevel = l2capinbuf[15];
301 #ifdef DEBUG_USB_HOST
302 if(l2capinbuf[12] & 0x01)
303 Notify(PSTR(
"\r\nWARNING: Battery is nearly empty"), 0x80);
306 if(l2capinbuf[12] & 0x02) {
307 #ifdef DEBUG_USB_HOST
308 if(!unknownExtensionConnected)
309 Notify(PSTR(
"\r\nExtension connected"), 0x80);
311 unknownExtensionConnected =
true;
315 setReportMode(
false, 0x35);
317 #ifdef DEBUG_USB_HOST
318 Notify(PSTR(
"\r\nExtension disconnected"), 0x80);
321 #ifdef DEBUG_USB_HOST
322 Notify(PSTR(
" - from Motion Plus"), 0x80);
325 if(!activateNunchuck)
329 #ifdef DEBUG_USB_HOST
330 Notify(PSTR(
" - Nunchuck"), 0x80);
335 setReportMode(
false, 0x31);
337 setReportMode(
false, 0x31);
340 checkExtension =
true;
343 if((l2capinbuf[12] & 0x0F) == 0) {
345 if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
346 #ifdef DEBUG_USB_HOST
347 Notify(PSTR(
"\r\nNunchuck connected"), 0x80);
350 }
else if(l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
351 #ifdef DEBUG_USB_HOST
352 Notify(PSTR(
"\r\nMotion Plus connected"), 0x80);
355 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x05) {
356 #ifdef DEBUG_USB_HOST
357 Notify(PSTR(
"\r\nMotion Plus activated in normal mode"), 0x80);
363 setReportMode(
false, 0x35);
364 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x05 && l2capinbuf[20] == 0x05) {
365 #ifdef DEBUG_USB_HOST
366 Notify(PSTR(
"\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
368 activateNunchuck =
false;
374 setReportMode(
false, 0x35);
375 }
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) {
376 #ifdef DEBUG_USB_HOST
377 Notify(PSTR(
"\r\nInactive Wii Motion Plus"), 0x80);
378 Notify(PSTR(
"\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension"), 0x80);
381 }
else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x01 && l2capinbuf[20] == 0x20) {
382 #ifdef DEBUG_USB_HOST
383 Notify(PSTR(
"\r\nWii U Pro Controller connected"), 0x80);
387 #ifdef DEBUG_USB_HOST
389 Notify(PSTR(
"\r\nUnknown Device: "), 0x80);
390 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
391 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
392 Notify(PSTR(
"\r\nData: "), 0x80);
393 for(uint8_t i = 0; i < ((l2capinbuf[12] >> 4) + 1); i++) {
394 D_PrintHex<uint8_t > (l2capinbuf[15 + i], 0x80);
402 Notify(PSTR(
"\r\nReport Error: "), 0x80);
403 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
404 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
409 #ifdef DEBUG_USB_HOST
410 if(l2capinbuf[13] != 0x00) {
411 Notify(PSTR(
"\r\nCommand failed: "), 0x80);
412 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
425 IR_object_x1 = (l2capinbuf[15] | ((uint16_t)(l2capinbuf[17] & 0x30) << 4));
426 IR_object_y1 = (l2capinbuf[16] | ((uint16_t)(l2capinbuf[17] & 0xC0) << 2));
427 IR_object_s1 = (l2capinbuf[17] & 0x0F);
429 IR_object_x2 = (l2capinbuf[18] | ((uint16_t)(l2capinbuf[20] & 0x30) << 4));
430 IR_object_y2 = (l2capinbuf[19] | ((uint16_t)(l2capinbuf[20] & 0xC0) << 2));
431 IR_object_s2 = (l2capinbuf[20] & 0x0F);
433 IR_object_x3 = (l2capinbuf[21] | ((uint16_t)(l2capinbuf[23] & 0x30) << 4));
434 IR_object_y3 = (l2capinbuf[22] | ((uint16_t)(l2capinbuf[23] & 0xC0) << 2));
435 IR_object_s3 = (l2capinbuf[23] & 0x0F);
437 IR_object_x4 = (l2capinbuf[24] | ((uint16_t)(l2capinbuf[26] & 0x30) << 4));
438 IR_object_y4 = (l2capinbuf[25] | ((uint16_t)(l2capinbuf[26] & 0xC0) << 2));
439 IR_object_s4 = (l2capinbuf[26] & 0x0F);
467 if(l2capinbuf[20] & 0x02) {
468 if(motionValuesReset) {
478 if(!(l2capinbuf[18] & 0x02))
480 if(!(l2capinbuf[18] & 0x01))
482 if(!(l2capinbuf[19] & 0x02))
508 if((micros() - timer) > 1000000) {
509 #ifdef DEBUG_USB_HOST
510 Notify(PSTR(
"\r\nThe gyro values has been reset"), 0x80);
512 gyroYawZero = (l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6));
513 gyroRollZero = (l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6));
514 gyroPitchZero = (l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6));
524 motionValuesReset =
true;
530 hatValues[
HatX] = l2capinbuf[15];
531 hatValues[
HatY] = l2capinbuf[16];
532 accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
533 accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x20 >> 4)) - 416;
534 accZnunchuck = (((l2capinbuf[19] & 0xFE) << 2) | (l2capinbuf[20] & 0xC0 >> 5)) - 416;
538 if(l2capinbuf[19] & 0x01) {
539 if(!extensionConnected) {
540 extensionConnected =
true;
541 unknownExtensionConnected =
true;
542 #ifdef DEBUG_USB_HOST
543 Notify(PSTR(
"\r\nExtension connected to Motion Plus"), 0x80);
547 if(extensionConnected && !unknownExtensionConnected) {
548 extensionConnected =
false;
549 unknownExtensionConnected =
true;
550 #ifdef DEBUG_USB_HOST
551 Notify(PSTR(
"\r\nExtension disconnected from Motion Plus"), 0x80);
558 hatValues[
HatX] = l2capinbuf[15];
559 hatValues[
HatY] = l2capinbuf[16];
560 accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
561 accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
562 accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
564 hatValues[
LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
565 hatValues[
RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
566 hatValues[
LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
567 hatValues[
RightHatY] = (l2capinbuf[21] | l2capinbuf[22] << 8);
570 #ifdef DEBUG_USB_HOST
572 Notify(PSTR(
"\r\nUnknown Report type: "), 0x80);
573 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
583 void WII::L2CAP_task() {
584 switch(l2cap_state) {
588 #ifdef DEBUG_USB_HOST
589 Notify(PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
597 #ifdef DEBUG_USB_HOST
598 Notify(PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
614 #ifdef DEBUG_USB_HOST
615 Notify(PSTR(
"\r\nSend HID Control Config Request"), 0x80);
625 #ifdef DEBUG_USB_HOST
626 Notify(PSTR(
"\r\nSend HID Interrupt Connection Request"), 0x80);
636 #ifdef DEBUG_USB_HOST
637 Notify(PSTR(
"\r\nSend HID Interrupt Config Request"), 0x80);
647 #ifdef DEBUG_USB_HOST
648 Notify(PSTR(
"\r\nHID Channels Established"), 0x80);
661 #ifdef DEBUG_USB_HOST
662 Notify(PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
672 #ifdef DEBUG_USB_HOST
673 Notify(PSTR(
"\r\nDisconnected Control Channel"), 0x80);
677 l2cap_event_flag = 0;
688 switch(l2cap_state) {
692 activeConnection =
true;
694 #ifdef DEBUG_USB_HOST
695 Notify(PSTR(
"\r\nSend HID Control Connection Request"), 0x80);
698 l2cap_event_flag = 0;
703 #ifdef DEBUG_USB_HOST
704 Notify(PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
717 #ifdef DEBUG_USB_HOST
718 if(stateCounter == 0)
719 Notify(PSTR(
"\r\nChecking if a Motion Plus is connected"), 0x80);
722 if(stateCounter % 200 == 0)
723 checkMotionPresent();
729 if(unknownExtensionConnected) {
730 #ifdef DEBUG_USB_HOST
731 Notify(PSTR(
"\r\nA extension is also connected"), 0x80);
733 activateNunchuck =
true;
736 }
else if(stateCounter == 601) {
737 #ifdef DEBUG_USB_HOST
738 Notify(PSTR(
"\r\nNo Motion Plus was detected"), 0x80);
746 #ifdef DEBUG_USB_HOST
747 if(stateCounter == 0)
748 Notify(PSTR(
"\r\nChecking if there is any extension connected"), 0x80);
751 if(stateCounter == 1)
753 if(stateCounter == 100) {
754 if(unknownExtensionConnected)
758 }
else if(stateCounter == 200)
760 else if(stateCounter == 300) {
762 unknownExtensionConnected =
false;
763 }
else if(stateCounter == 400) {
771 if(stateCounter == 1)
773 else if(stateCounter == 100)
774 activateMotionPlus();
775 else if(stateCounter == 200)
777 else if(stateCounter == 300) {
779 unknownExtensionConnected =
false;
793 if(unknownExtensionConnected) {
794 #ifdef DEBUG_USB_HOST
795 if(stateCounter == 0)
796 Notify(PSTR(
"\r\nChecking extension port"), 0x80);
799 if(stateCounter == 50)
801 else if(stateCounter == 100)
803 else if(stateCounter == 150)
808 else if(stateCounter == 200)
810 else if(stateCounter == 250) {
812 #ifdef DEBUG_USB_HOST
813 Notify(PSTR(
"\r\nNunchuck was reconnected"), 0x80);
815 activateNunchuck =
true;
820 }
else if(stateCounter == 300) {
822 #ifdef DEBUG_USB_HOST
823 Notify(PSTR(
"\r\nReactivating the Motion Plus"), 0x80);
828 }
else if(stateCounter == 350)
829 activateMotionPlus();
830 else if(stateCounter == 400)
832 else if(stateCounter == 450) {
835 unknownExtensionConnected =
false;
847 void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
849 pBtd->
L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]);
851 pBtd->
L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
857 HID_Command(HIDBuffer, 3);
862 HIDBuffer[2] &= ~0x01;
863 HID_Command(HIDBuffer, 3);
868 HIDBuffer[2] |= 0x01;
869 HID_Command(HIDBuffer, 3);
874 HIDBuffer[2] ^= 0x01;
875 HID_Command(HIDBuffer, 3);
880 HIDBuffer[2] = value | (HIDBuffer[2] & 0x01);
881 HID_Command(HIDBuffer, 3);
886 HIDBuffer[2] &= ~(pgm_read_byte(&
WII_LEDS[(uint8_t)a]));
887 HID_Command(HIDBuffer, 3);
895 HIDBuffer[2] |= pgm_read_byte(&
WII_LEDS[(uint8_t)a]);
896 HID_Command(HIDBuffer, 3);
902 HIDBuffer[2] ^= pgm_read_byte(&
WII_LEDS[(uint8_t)a]);
903 HID_Command(HIDBuffer, 3);
908 HIDBuffer[2] = (HIDBuffer[2] & 0x01);
910 HIDBuffer[2] |= 0x10;
912 HIDBuffer[2] |= 0x20;
914 HIDBuffer[2] |= 0x40;
916 HID_Command(HIDBuffer, 3);
920 checkExtension =
false;
925 void WII::setReportMode(
bool continuous, uint8_t mode) {
930 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
932 cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01);
934 HID_Command(cmd_buf, 4);
937 void WII::statusRequest() {
941 cmd_buf[2] = (HIDBuffer[2] & 0x01);
942 HID_Command(cmd_buf, 3);
949 void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
953 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
954 cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
955 cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
956 cmd_buf[5] = (uint8_t)(offset & 0xFF);
960 cmd_buf[7 + i] = data[i];
962 cmd_buf[7 + i] = 0x00;
963 HID_Command(cmd_buf, 23);
966 void WII::initExtension1() {
969 writeData(0xA400F0, 1, buf);
972 void WII::initExtension2() {
975 writeData(0xA400FB, 1, buf);
978 void WII::initMotionPlus() {
981 writeData(0xA600F0, 1, buf);
984 void WII::activateMotionPlus() {
987 #ifdef DEBUG_USB_HOST
988 Notify(PSTR(
"\r\nActivating Wii U Pro Controller"), 0x80);
991 }
else if(activateNunchuck) {
992 #ifdef DEBUG_USB_HOST
993 Notify(PSTR(
"\r\nActivating Motion Plus in pass-through mode"), 0x80);
999 #ifdef DEBUG_USB_HOST
1000 Notify(PSTR(
"\r\nActivating Motion Plus in normal mode"), 0x80);
1004 writeData(0xA600FE, 1, buf);
1007 void WII::readData(uint32_t offset, uint16_t size,
bool EEPROM) {
1012 cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01);
1014 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1015 cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
1016 cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
1017 cmd_buf[5] = (uint8_t)(offset & 0xFF);
1018 cmd_buf[6] = (uint8_t)((size & 0xFF00) >> 8);
1019 cmd_buf[7] = (uint8_t)(size & 0xFF);
1021 HID_Command(cmd_buf, 8);
1024 void WII::readExtensionType() {
1025 readData(0xA400FA, 6,
false);
1028 void WII::readCalData() {
1029 readData(0x0016, 8,
true);
1032 void WII::checkMotionPresent() {
1033 readData(0xA600FA, 6,
false);
1045 return (ButtonState & pgm_read_dword(&
WII_BUTTONS[(uint8_t)b]));
1053 button = pgm_read_dword(&
WII_BUTTONS[(uint8_t)b]);
1054 bool click = (ButtonClickState & button);
1055 ButtonClickState &= ~button;
1063 uint8_t output = hatValues[(uint8_t)a];
1064 if(output == 0xFF || output == 0x00)
1075 uint16_t output = hatValues[(uint8_t)a];
1083 void WII::onInit() {
1099 #ifdef DEBUG_USB_HOST
1100 Notify(PSTR(
"\r\nEnable IR Camera1 Complete"), 0x80);
1105 #ifdef DEBUG_USB_HOST
1106 Notify(PSTR(
"\r\nEnable IR Camera2 Complete"), 0x80);
1111 #ifdef DEBUG_USB_HOST
1112 Notify(PSTR(
"\r\nWrote hex number 0x08"), 0x80);
1116 writeSensitivityBlock1();
1117 #ifdef DEBUG_USB_HOST
1118 Notify(PSTR(
"\r\nWrote Sensitivity Block 1"), 0x80);
1122 writeSensitivityBlock2();
1123 #ifdef DEBUG_USB_HOST
1124 Notify(PSTR(
"\r\nWrote Sensitivity Block 2"), 0x80);
1128 uint8_t mode_num = 0x03;
1129 setWiiModeNumber(mode_num);
1130 #ifdef DEBUG_USB_HOST
1131 Notify(PSTR(
"\r\nSet Wii Mode Number To 0x"), 0x80);
1132 D_PrintHex<uint8_t > (mode_num, 0x80);
1137 #ifdef DEBUG_USB_HOST
1138 Notify(PSTR(
"\r\nWrote Hex Number 0x08"), 0x80);
1142 setReportMode(
false, 0x33);
1144 #ifdef DEBUG_USB_HOST
1145 Notify(PSTR(
"\r\nSet Report Mode to 0x33"), 0x80);
1150 #ifdef DEBUG_USB_HOST
1151 Notify(PSTR(
"\r\nIR Initialized"), 0x80);
1155 void WII::enableIRCamera1() {
1159 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1160 HID_Command(cmd_buf, 3);
1163 void WII::enableIRCamera2() {
1167 cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01);
1168 HID_Command(cmd_buf, 3);
1171 void WII::writeSensitivityBlock1() {
1183 writeData(0xB00000, 9, buf);
1186 void WII::writeSensitivityBlock2() {
1191 writeData(0xB0001A, 2, buf);
1194 void WII::write0x08Value() {
1196 writeData(0xb00030, 1, &cmd);
1199 void WII::setWiiModeNumber(uint8_t mode_number) {
1200 writeData(0xb00033, 1, &mode_number);
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define UHS_ACL_HANDLE_OK(x, y)
#define wii_clear_flag(flag)
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_INTERRUPT_SETUP
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_FLAG_CONNECTION_INTERRUPT_REQUEST
void setLedToggle(LEDEnum a)
void setLedRaw(uint8_t value)
uint8_t getAnalogHat(HatEnum a)
#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)
uint8_t getBatteryLevel()
virtual void disconnect()
#define wii_set_flag(flag)
#define L2CAP_CONTROL_SUCCESS
#define L2CAP_CONTROL_CONFIG_REQUEST
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define L2CAP_CONTROL_CONNECT_REQUEST
WII(BTD *p, bool pair=false)
#define WII_CHECK_EXTENSION_STATE
void hci_disconnect(uint16_t handle)
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define WII_FLAG_MOTION_PLUS_CONNECTED
bool getButtonClick(ButtonEnum b)
bool wiiUProControllerConnected
#define l2cap_check_flag(flag)
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_FLAG_CONTROL_CONNECTED
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_CONTROL_DISCONNECT
const uint32_t WII_BUTTONS[]
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define WII_CHECK_MOTION_PLUS_STATE
int8_t registerServiceClass(BluetoothService *pService)
bool l2capConnectionClaimed
const uint32_t WII_PROCONTROLLER_BUTTONS[]
#define L2CAP_CMD_DISCONNECT_RESPONSE
#define L2CAP_CMD_CONNECTION_RESPONSE
#define L2CAP_CMD_CONFIG_RESPONSE
#define wii_check_flag(flag)
#define WII_INIT_MOTION_PLUS_STATE
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)
#define L2CAP_FLAG_INTERRUPT_CONNECTED
#define l2cap_set_flag(flag)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
bool getButtonPress(ButtonEnum b)
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_CMD_CONNECTION_REQUEST
#define L2CAP_INTERRUPT_CONNECT_REQUEST
#define L2CAP_INTERRUPT_DISCONNECT
#define L2CAP_CMD_COMMAND_REJECT