Mercurial > louis > kiibohd-controller
comparison Output/pjrcUSB/arm/usb_dev.c @ 449:45feb80a2ad1
Major USB update, fixes most (if not all) known issues
USB - General
- Refactored descriptors
- Enabled/Disable USB endpoints
- Added debug flags for special features
- Code cleanup
- Interface count calculation based off of enabled endpoints
- Delayed wTotalLength calculation to simplify descriptor offsets
- Re-ordered endpoints and interfaces
- Added more debug output
- Added usbInitTime to show how long keyboard initialization took
(Useful when debugging bad init sequences)
- Added function for usb_resume() which takes care of the resume sequence
* Resume is now only called if packets are starting to timeout
USB - Special Options
- Added enableDeviceRestartOnUSBTimeout
* A last resort hammer for bad USB Chipsets/OSs, don't use if you can help it
* Disabled
- Added enableUSBResume
* Enables host resume wake-up signalling, required to wake a computer from sleep
* Enabled
- Added enableUSBLowPowerNegotiation
* Enables power negotiation hack
* Required to use firmware with an IPad and other hard-limit low-power USB hosts
* Hasn't been tested with the recent changes
* Disabled
- Added enableUSBSuspend
* Enables power down events on host USB bus suspend
* Enabled
USB - Keyboard
- Attempted to cleanup HID SET_REPORT
* Works much better
* Still has an issue under Linux which generates *a lot* of NAKs (initializes quickly regardless)
+ Not present on other keyboards
+ SETUP -> OUT -> IN : This sequence is the problem
+ Specifically during the OUT phase
- Enabled
USB - CDC Virtual Serial Port
- Code cleanup
- Added convenience struct USBCDCLineCoding for easier debugging
- Attempted to cleanup CDC_SET_LING_CODING
* Works much better
* Still has an issue under Linux which generates *a lot* of NAKs (initializes quickly regardless)
+ SETUP -> OUT -> IN : This sequence is the problem
+ Specifically during the OUT phase
+ Likely the same issues as HID SET_REPORT
- Enabled
USB - Mouse
- Enabled
USB - Joystick
- Disabled
USB - RawIO
- Initial code, API not used yet
- Disabled
DFU
- Updated load script, now faster
author | Jacob Alexander <haata@kiibohd.com> |
---|---|
date | Tue, 31 May 2016 00:19:45 -0700 |
parents | 56237ba5da6f |
children |
comparison
equal
deleted
inserted
replaced
448:077a1dfd8529 | 449:45feb80a2ad1 |
---|---|
38 | 38 |
39 // Local Includes | 39 // Local Includes |
40 #include "usb_dev.h" | 40 #include "usb_dev.h" |
41 #include "usb_mem.h" | 41 #include "usb_mem.h" |
42 | 42 |
43 #if enableVirtualSerialPort_define == 1 | |
44 #include "usb_serial.h" | |
45 #endif | |
46 | |
43 | 47 |
44 | 48 |
45 // ----- Defines ----- | 49 // ----- Defines ----- |
46 | 50 |
47 // DEBUG Mode | 51 // DEBUG Mode |
178 // ----- Functions ----- | 182 // ----- Functions ----- |
179 | 183 |
180 static void endpoint0_stall() | 184 static void endpoint0_stall() |
181 { | 185 { |
182 #ifdef UART_DEBUG_UNKNOWN | 186 #ifdef UART_DEBUG_UNKNOWN |
183 print("STALL" NL ); | 187 print("STALL : "); |
188 printInt32( systick_millis_count - USBInit_TimeStart ); | |
189 print(" ms"); | |
190 print(NL); | |
184 #endif | 191 #endif |
185 USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; | 192 USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; |
186 } | 193 } |
187 | 194 |
188 static void endpoint0_transmit( const void *data, uint32_t len ) | 195 static void endpoint0_transmit( const void *data, uint32_t len ) |
193 ep0_tx_bdt_bank ^= 1; | 200 ep0_tx_bdt_bank ^= 1; |
194 } | 201 } |
195 | 202 |
196 void usb_reinit() | 203 void usb_reinit() |
197 { | 204 { |
198 power_neg_delay = 0; | |
199 usb_configuration = 0; // Clear USB configuration if we have one | 205 usb_configuration = 0; // Clear USB configuration if we have one |
200 USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect | 206 USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect |
201 delay(10); // Delay is necessary to simulate disconnect | 207 delay(10); // Delay is necessary to simulate disconnect |
202 usb_init(); | 208 usb_init(); |
203 } | 209 } |
211 if ( power_neg_delay ) | 217 if ( power_neg_delay ) |
212 { | 218 { |
213 // Check if 100 ms has elapsed | 219 // Check if 100 ms has elapsed |
214 if ( systick_millis_count - power_neg_time > 100 ) | 220 if ( systick_millis_count - power_neg_time > 100 ) |
215 { | 221 { |
222 power_neg_delay = 0; | |
223 | |
224 // USB Low Power Negotiation | |
225 #if enableUSBLowPowerNegotiation_define == 1 | |
226 // Check to see if bMaxPower has already be lowered | |
227 // This generally points to a USB bug (host or device?) | |
228 if ( *usb_bMaxPower == 50 ) | |
229 { | |
230 warn_msg("Power negotiation delay detected again, likely a system/device USB bug"); | |
231 return; | |
232 } | |
233 | |
216 // Update bMaxPower | 234 // Update bMaxPower |
217 // The value set is in increments of 2 mA | 235 // The value set is in increments of 2 mA |
218 // So 50 * 2 mA = 100 mA | 236 // So 50 * 2 mA = 100 mA |
219 // XXX Currently only transitions to 100 mA | 237 // XXX Currently only transitions to 100 mA |
220 // It may be possible to transition down again to 20 mA | 238 // It may be possible to transition down again to 20 mA |
221 *usb_bMaxPower = 50; | 239 *usb_bMaxPower = 50; |
222 | 240 |
223 // Re-initialize USB | 241 // Re-initialize USB |
224 usb_reinit(); | 242 usb_reinit(); |
243 #else | |
244 warn_msg("USB Low Power Negotation Disabled, condition detected."); | |
245 #endif | |
225 } | 246 } |
226 } | 247 } |
227 } | 248 } |
228 | 249 |
229 static void usb_setup() | 250 static void usb_setup() |
234 uint32_t size; | 255 uint32_t size; |
235 volatile uint8_t *reg; | 256 volatile uint8_t *reg; |
236 uint8_t epconf; | 257 uint8_t epconf; |
237 const uint8_t *cfg; | 258 const uint8_t *cfg; |
238 int i; | 259 int i; |
260 | |
261 // Reset USB Init timer | |
262 USBInit_TimeEnd = systick_millis_count; | |
263 USBInit_Ticks++; | |
239 | 264 |
240 // If another request is made, disable the power negotiation check | 265 // If another request is made, disable the power negotiation check |
241 // See GET_DESCRIPTOR - Configuration | 266 // See GET_DESCRIPTOR - Configuration |
242 if ( power_neg_delay ) | 267 if ( power_neg_delay ) |
243 { | 268 { |
515 print( "desc: not found" NL ); | 540 print( "desc: not found" NL ); |
516 #endif | 541 #endif |
517 endpoint0_stall(); | 542 endpoint0_stall(); |
518 return; | 543 return; |
519 | 544 |
545 #if enableVirtualSerialPort_define == 1 | |
520 case 0x2221: // CDC_SET_CONTROL_LINE_STATE | 546 case 0x2221: // CDC_SET_CONTROL_LINE_STATE |
521 usb_cdc_line_rtsdtr = setup.wValue; | 547 usb_cdc_line_rtsdtr = setup.wValue; |
522 //serial_print("set control line state\n"); | 548 //info_print("set control line state"); |
523 goto send; | 549 goto send; |
524 | 550 |
525 case 0x21A1: // CDC_GET_LINE_CODING | 551 case 0x21A1: // CDC_GET_LINE_CODING |
526 data = (uint8_t*)usb_cdc_line_coding; | 552 data = (uint8_t*)&usb_cdc_line_coding; |
527 datalen = sizeof( usb_cdc_line_coding ); | 553 datalen = sizeof( usb_cdc_line_coding ); |
528 goto send; | 554 goto send; |
529 | 555 |
530 case 0x2021: // CDC_SET_LINE_CODING | 556 case 0x2021: // CDC_SET_LINE_CODING |
531 // XXX Needed? | 557 // ZLP Reply |
532 //serial_print("set coding, waiting...\n"); | 558 // Settings are applied in PID=OUT |
533 return; | 559 goto send; |
560 #endif | |
534 | 561 |
535 case 0x0921: // HID SET_REPORT | 562 case 0x0921: // HID SET_REPORT |
563 // ZLP Reply | |
564 // Settings are applied in PID=OUT | |
565 | |
566 #ifdef UART_DEBUG | |
567 print("report_type("); | |
568 printHex( setup.wValue >> 8 ); | |
569 print(")report_id("); | |
570 printHex( setup.wValue & 0xFF ); | |
571 print(")interface("); | |
572 printHex( setup.wIndex ); | |
573 print(")len("); | |
574 printHex( setup.wLength ); | |
575 print(")"); | |
576 print( NL ); | |
577 #endif | |
578 | |
536 // Interface | 579 // Interface |
537 switch ( setup.wIndex & 0xFF ) | 580 switch ( setup.wIndex & 0xFF ) |
538 { | 581 { |
539 // Keyboard Interface | 582 // Keyboard Interface |
540 case KEYBOARD_INTERFACE: | 583 case KEYBOARD_INTERFACE: |
545 default: | 588 default: |
546 warn_msg("Unknown interface - "); | 589 warn_msg("Unknown interface - "); |
547 printHex( setup.wIndex ); | 590 printHex( setup.wIndex ); |
548 print( NL ); | 591 print( NL ); |
549 endpoint0_stall(); | 592 endpoint0_stall(); |
550 break; | 593 return; |
551 } | 594 } |
552 | 595 |
553 goto send; | 596 goto send; |
554 | 597 |
555 case 0x01A1: // HID GET_REPORT | 598 case 0x01A1: // HID GET_REPORT |
569 { | 612 { |
570 data = list->addr; | 613 data = list->addr; |
571 datalen = list->length; | 614 datalen = list->length; |
572 goto send; | 615 goto send; |
573 } | 616 } |
574 } | 617 } |
575 endpoint0_stall(); | 618 endpoint0_stall(); |
576 return; | 619 return; |
577 | 620 |
578 case 0x0A21: // HID SET_IDLE | 621 case 0x0A21: // HID SET_IDLE |
579 #ifdef UART_DEBUG | 622 #ifdef UART_DEBUG |
580 print("SET_IDLE - "); | 623 print("SET_IDLE - "); |
581 printHex( setup.wValue ); | 624 printHex( setup.wValue ); |
594 print(" - "); | 637 print(" - "); |
595 printHex( USBKeys_Idle_Config ); | 638 printHex( USBKeys_Idle_Config ); |
596 print(NL); | 639 print(NL); |
597 #endif | 640 #endif |
598 reply_buffer[0] = USBKeys_Idle_Config; | 641 reply_buffer[0] = USBKeys_Idle_Config; |
642 data = reply_buffer; | |
599 datalen = 1; | 643 datalen = 1; |
600 goto send; | 644 goto send; |
601 | 645 |
602 | 646 |
603 case 0x0B21: // HID SET_PROTOCOL | 647 case 0x0B21: // HID SET_PROTOCOL |
618 print(" - "); | 662 print(" - "); |
619 printHex( USBKeys_Protocol ); | 663 printHex( USBKeys_Protocol ); |
620 print(NL); | 664 print(NL); |
621 #endif | 665 #endif |
622 reply_buffer[0] = USBKeys_Protocol; | 666 reply_buffer[0] = USBKeys_Protocol; |
667 data = reply_buffer; | |
623 datalen = 1; | 668 datalen = 1; |
624 goto send; | 669 goto send; |
625 | 670 |
626 // case 0xC940: | 671 // case 0xC940: |
627 default: | 672 default: |
628 #ifdef UART_DEBUG_UNKNOWN | 673 #ifdef UART_DEBUG_UNKNOWN |
629 print("UNKNOWN"); | 674 print("UNKNOWN: "); |
675 printInt32( systick_millis_count - USBInit_TimeStart ); | |
676 print(" ms"); | |
630 print(NL); | 677 print(NL); |
631 #endif | 678 #endif |
632 endpoint0_stall(); | 679 endpoint0_stall(); |
633 return; | 680 return; |
634 } | 681 } |
653 | 700 |
654 size = datalen; | 701 size = datalen; |
655 if ( size > EP0_SIZE ) | 702 if ( size > EP0_SIZE ) |
656 size = EP0_SIZE; | 703 size = EP0_SIZE; |
657 | 704 |
658 endpoint0_transmit(data, size); | 705 endpoint0_transmit( data, size ); |
659 data += size; | 706 data += size; |
660 datalen -= size; | 707 datalen -= size; |
661 | 708 |
662 // See if transmit has finished | 709 // See if transmit has finished |
663 if ( datalen == 0 && size < EP0_SIZE ) | 710 if ( datalen == 0 && size < EP0_SIZE ) |
664 return; | 711 return; |
665 | 712 |
666 size = datalen; | 713 size = datalen; |
667 if ( size > EP0_SIZE ) | 714 if ( size > EP0_SIZE ) |
668 size = EP0_SIZE; | 715 size = EP0_SIZE; |
669 endpoint0_transmit(data, size); | 716 endpoint0_transmit( data, size ); |
670 data += size; | 717 data += size; |
671 datalen -= size; | 718 datalen -= size; |
672 | 719 |
673 // See if transmit has finished | 720 // See if transmit has finished |
674 if ( datalen == 0 && size < EP0_SIZE ) | 721 if ( datalen == 0 && size < EP0_SIZE ) |
687 //Configuring a device or changing an alternate setting causes all of the status | 734 //Configuring a device or changing an alternate setting causes all of the status |
688 //and configuration values associated with endpoints in the affected interfaces | 735 //and configuration values associated with endpoints in the affected interfaces |
689 //to be set to their default values. This includes setting the data toggle of | 736 //to be set to their default values. This includes setting the data toggle of |
690 //any endpoint using data toggles to the value DATA0. | 737 //any endpoint using data toggles to the value DATA0. |
691 | 738 |
692 //For endpoints using data toggle, regardless of whether an endpoint has the | 739 // For endpoints using data toggle, regardless of whether an endpoint has the |
693 //Halt feature set, a ClearFeature(ENDPOINT_HALT) request always results in the | 740 // Halt feature set, a ClearFeature(ENDPOINT_HALT) request always results in the |
694 //data toggle being reinitialized to DATA0. | 741 // data toggle being reinitialized to DATA0. |
695 | 742 |
696 static void usb_control( uint32_t stat ) | 743 static void usb_control( uint32_t stat ) |
697 { | 744 { |
698 #ifdef UART_DEBUG | 745 #ifdef UART_DEBUG |
699 print("CONTROL - "); | 746 print("CONTROL - "); |
712 print(", count:"); | 759 print(", count:"); |
713 printHex32(b->desc); | 760 printHex32(b->desc); |
714 print(" - "); | 761 print(" - "); |
715 #endif | 762 #endif |
716 | 763 |
717 switch (pid) | 764 switch ( pid ) |
718 { | 765 { |
719 case 0x0D: // Setup received from host | 766 case 0x0D: // Setup received from host |
720 //serial_print("PID=Setup\n"); | |
721 //if (count != 8) ; // panic? | |
722 // grab the 8 byte setup info | 767 // grab the 8 byte setup info |
723 setup.word1 = *(uint32_t *)(buf); | 768 setup.word1 = *(uint32_t *)(buf); |
724 setup.word2 = *(uint32_t *)(buf + 4); | 769 setup.word2 = *(uint32_t *)(buf + 4); |
725 | 770 |
726 // give the buffer back | 771 // give the buffer back |
739 //if (table[index(0, TX, ODD)].desc & 0x80) { | 784 //if (table[index(0, TX, ODD)].desc & 0x80) { |
740 //serial_print("leftover tx odd\n"); | 785 //serial_print("leftover tx odd\n"); |
741 //} | 786 //} |
742 table[index(0, TX, EVEN)].desc = 0; | 787 table[index(0, TX, EVEN)].desc = 0; |
743 table[index(0, TX, ODD)].desc = 0; | 788 table[index(0, TX, ODD)].desc = 0; |
789 | |
744 // first IN after Setup is always DATA1 | 790 // first IN after Setup is always DATA1 |
745 ep0_tx_data_toggle = 1; | 791 ep0_tx_data_toggle = 1; |
746 | 792 |
747 #ifdef UART_DEBUG_UNKNOWN | 793 #ifdef UART_DEBUG_UNKNOWN |
748 print("bmRequestType:"); | 794 printHex( stat ); |
749 printHex(setup.bmRequestType); | 795 print(" PID=SETUP wRequestAndType:"); |
750 print(", bRequest:"); | |
751 printHex(setup.bRequest); | |
752 print(", wValue:"); | |
753 printHex(setup.wValue); | |
754 print(", wIndex:"); | |
755 printHex(setup.wIndex); | |
756 print(", len:"); | |
757 printHex(setup.wLength); | |
758 print(" -- "); | |
759 printHex32(setup.word1); | |
760 print(" "); | |
761 printHex32(setup.word2); | |
762 print(NL); | |
763 #endif | |
764 // actually "do" the setup request | |
765 usb_setup(); | |
766 // unfreeze the USB, now that we're ready | |
767 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit | |
768 break; | |
769 | |
770 case 0x01: // OUT transaction received from host | |
771 case 0x02: | |
772 #ifdef UART_DEBUG_UNKNOWN | |
773 print("PID=OUT wRequestAndType:"); | |
774 printHex(setup.wRequestAndType); | 796 printHex(setup.wRequestAndType); |
775 print(", wValue:"); | 797 print(", wValue:"); |
776 printHex(setup.wValue); | 798 printHex(setup.wValue); |
777 print(", wIndex:"); | 799 print(", wIndex:"); |
778 printHex(setup.wIndex); | 800 printHex(setup.wIndex); |
780 printHex(setup.wLength); | 802 printHex(setup.wLength); |
781 print(" -- "); | 803 print(" -- "); |
782 printHex32(setup.word1); | 804 printHex32(setup.word1); |
783 print(" "); | 805 print(" "); |
784 printHex32(setup.word2); | 806 printHex32(setup.word2); |
807 print(": "); | |
808 printInt32( systick_millis_count - USBInit_TimeStart ); | |
809 print(" ms"); | |
785 print(NL); | 810 print(NL); |
786 #endif | 811 #endif |
787 | 812 |
813 // actually "do" the setup request | |
814 usb_setup(); | |
815 // unfreeze the USB, now that we're ready | |
816 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit | |
817 break; | |
818 | |
819 case 0x01: // OUT transaction received from host | |
820 case 0x02: | |
821 #ifdef UART_DEBUG_UNKNOWN | |
822 printHex( stat ); | |
823 print(" PID=OUT wRequestAndType:"); | |
824 printHex(setup.wRequestAndType); | |
825 print(", wValue:"); | |
826 printHex(setup.wValue); | |
827 print(", wIndex:"); | |
828 printHex(setup.wIndex); | |
829 print(", len:"); | |
830 printHex(setup.wLength); | |
831 print(" -- "); | |
832 printHex32(setup.word1); | |
833 print(" "); | |
834 printHex32(setup.word2); | |
835 print(": "); | |
836 printInt32( systick_millis_count - USBInit_TimeStart ); | |
837 print(" ms"); | |
838 print(NL); | |
839 #endif | |
840 | |
788 // CDC Interface | 841 // CDC Interface |
789 if ( setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/ ) | 842 #if enableVirtualSerialPort_define == 1 |
790 { | 843 // CDC_SET_LINE_CODING - PID=OUT |
791 int i; | 844 // XXX - Getting lots of NAKs in Linux |
792 uint8_t *dst = (uint8_t *)usb_cdc_line_coding; | 845 if ( setup.wRequestAndType == 0x2021 ) |
793 //serial_print("set line coding "); | 846 { |
794 for ( i = 0; i < 7; i++ ) | 847 // Copy over new line coding |
848 memcpy( (void*)&usb_cdc_line_coding, buf, 7 ); | |
849 | |
850 #ifdef UART_DEBUG | |
851 // - Unused, but for the readers info - | |
852 print("dwDTERate("); | |
853 printInt32( usb_cdc_line_coding.dwDTERate ); | |
854 print(")bCharFormat("); | |
855 printHex( usb_cdc_line_coding.bCharFormat ); | |
856 print(")bParityType("); | |
857 printHex( usb_cdc_line_coding.bParityType ); | |
858 print(")bDataBits("); | |
859 printHex( usb_cdc_line_coding.bDataBits ); | |
860 print(")"); | |
861 print( NL ); | |
862 #endif | |
863 | |
864 // XXX ZLP causes timeout/delay, why? -HaaTa | |
865 //endpoint0_transmit( NULL, 0 ); | |
866 } | |
867 #endif | |
868 | |
869 // Keyboard HID SET_REPORT - PID=OUT | |
870 #if enableKeyboard_define == 1 | |
871 // XXX - Getting lots of NAKs in Linux | |
872 if ( setup.wRequestAndType == 0x0921 && setup.wValue & 0x200 ) | |
873 { | |
874 #ifdef UART_DEBUG | |
875 print("report_type("); | |
876 printHex( setup.wValue >> 8 ); | |
877 print(")report_id("); | |
878 printHex( setup.wValue & 0xFF ); | |
879 print(")interface("); | |
880 printHex( setup.wIndex ); | |
881 print(")len("); | |
882 printHex( setup.wLength ); | |
883 print(")["); | |
884 | |
885 for ( size_t len = 0; len < setup.wLength; len++ ) | |
795 { | 886 { |
796 //serial_phex(*buf); | 887 printHex( buf[ len ] ); |
797 *dst++ = *buf++; | 888 print(" "); |
798 } | 889 } |
799 //serial_phex32(usb_cdc_line_coding[0]); | 890 print("]"); |
800 //serial_print("\n"); | 891 print( NL ); |
801 if ( usb_cdc_line_coding[0] == 134 ) | 892 #endif |
802 usb_reboot_timer = 15; | 893 |
803 endpoint0_transmit( NULL, 0 ); | |
804 } | |
805 | |
806 // Keyboard SET_REPORT | |
807 if ( setup.wRequestAndType == 0x921 && setup.wValue & 0x200 ) | |
808 { | |
809 // Interface | 894 // Interface |
810 switch ( setup.wIndex & 0xFF ) | 895 switch ( setup.wIndex & 0xFF ) |
811 { | 896 { |
812 // Keyboard Interface | 897 // Keyboard Interface |
813 case KEYBOARD_INTERFACE: | 898 case KEYBOARD_INTERFACE: |
814 USBKeys_LEDs = buf[0]; | 899 USBKeys_LEDs = buf[0]; |
815 endpoint0_transmit( NULL, 0 ); | |
816 break; | 900 break; |
817 // NKRO Keyboard Interface | 901 // NKRO Keyboard Interface |
818 case NKRO_KEYBOARD_INTERFACE: | 902 case NKRO_KEYBOARD_INTERFACE: |
903 // Already set with the control sequence | |
819 // Only use 2nd byte, first byte is the report id | 904 // Only use 2nd byte, first byte is the report id |
820 USBKeys_LEDs = buf[1]; | 905 USBKeys_LEDs = buf[1]; |
821 endpoint0_transmit( NULL, 0 ); | |
822 break; | 906 break; |
823 default: | 907 default: |
824 warn_msg("Unknown interface - "); | 908 warn_msg("Unknown interface - "); |
825 printHex( setup.wIndex ); | 909 printHex( setup.wIndex ); |
826 print( NL ); | 910 print( NL ); |
827 break; | 911 break; |
828 } | 912 } |
829 | 913 |
830 #ifdef UART_DEBUG | 914 // XXX ZLP causes timeout/delay, why? -HaaTa |
831 for ( size_t len = 0; len < setup.wLength; len++ ) | 915 //endpoint0_transmit( NULL, 0 ); |
832 { | 916 } |
833 printHex( buf[ len ] ); | 917 #endif |
834 print(" "); | |
835 } | |
836 print( NL ); | |
837 #endif | |
838 } | |
839 | 918 |
840 // give the buffer back | 919 // give the buffer back |
841 b->desc = BDT_DESC( EP0_SIZE, DATA1 ); | 920 b->desc = BDT_DESC( EP0_SIZE, DATA1 ); |
842 break; | 921 break; |
843 | 922 |
844 case 0x09: // IN transaction completed to host | 923 case 0x09: // IN transaction completed to host |
845 #ifdef UART_DEBUG | 924 data = ep0_tx_ptr; |
846 print("PID=IN:"); | 925 |
847 printHex(stat); | 926 #ifdef UART_DEBUG_UNKNOWN |
927 printHex( stat ); | |
928 print(" PID=IN wRequestAndType:"); | |
929 printHex(setup.wRequestAndType); | |
930 print(", wValue:"); | |
931 printHex(setup.wValue); | |
932 print(", wIndex:"); | |
933 printHex(setup.wIndex); | |
934 print(", len:"); | |
935 printHex(setup.wLength); | |
936 print(" -- "); | |
937 printHex32(setup.word1); | |
938 print(" "); | |
939 printHex32(setup.word2); | |
940 print(": "); | |
941 printInt32( systick_millis_count - USBInit_TimeStart ); | |
942 print(" ms"); | |
943 if ( data ) print(" DATA "); | |
848 print(NL); | 944 print(NL); |
849 #endif | 945 #endif |
850 | 946 |
851 // send remaining data, if any... | 947 // send remaining data, if any... |
852 data = ep0_tx_ptr; | |
853 if ( data ) | 948 if ( data ) |
854 { | 949 { |
855 size = ep0_tx_len; | 950 size = ep0_tx_len; |
856 if (size > EP0_SIZE) size = EP0_SIZE; | 951 if (size > EP0_SIZE) |
857 endpoint0_transmit(data, size); | 952 { |
953 size = EP0_SIZE; | |
954 } | |
955 endpoint0_transmit( data, size ); | |
858 data += size; | 956 data += size; |
859 ep0_tx_len -= size; | 957 ep0_tx_len -= size; |
860 ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL; | 958 ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL; |
861 } | 959 } |
862 | 960 |
869 print(NL); | 967 print(NL); |
870 #endif | 968 #endif |
871 USB0_ADDR = setup.wValue; | 969 USB0_ADDR = setup.wValue; |
872 } | 970 } |
873 | 971 |
972 // CDC_SET_LINE_CODING - PID=IN | |
973 #if enableVirtualSerialPort_define == 1 | |
974 if ( setup.wRequestAndType == 0x2021 ) | |
975 { | |
976 // XXX ZLP causes timeout/delay, why? -HaaTa | |
977 //endpoint0_transmit( NULL, 0 ); | |
978 } | |
979 #endif | |
980 | |
981 // Keyboard HID SET_REPORT - PID=IN | |
982 #if enableKeyboard_define == 1 | |
983 // XXX - Getting lots of NAKs in Linux | |
984 if ( setup.wRequestAndType == 0x0921 && setup.wValue & 0x200 ) | |
985 { | |
986 // XXX ZLP causes timeout/delay, why? -HaaTa | |
987 //endpoint0_transmit( NULL, 0 ); | |
988 } | |
989 #endif | |
990 | |
874 break; | 991 break; |
875 | 992 |
876 default: | 993 default: |
877 #ifdef UART_DEBUG | 994 #ifdef UART_DEBUG_UNKNOWN |
878 print("PID=unknown:"); | 995 print("PID=unknown: "); |
879 printHex(pid); | 996 printHex(pid); |
997 print(": "); | |
998 printInt32( systick_millis_count - USBInit_TimeStart ); | |
999 print(" ms"); | |
880 print(NL); | 1000 print(NL); |
881 #endif | 1001 #endif |
882 break; | 1002 break; |
883 } | 1003 } |
884 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit | 1004 USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit |
887 usb_packet_t *usb_rx( uint32_t endpoint ) | 1007 usb_packet_t *usb_rx( uint32_t endpoint ) |
888 { | 1008 { |
889 //print("USB RX"); | 1009 //print("USB RX"); |
890 usb_packet_t *ret; | 1010 usb_packet_t *ret; |
891 endpoint--; | 1011 endpoint--; |
1012 | |
1013 // Make sure this is a valid endpoint | |
892 if ( endpoint >= NUM_ENDPOINTS ) | 1014 if ( endpoint >= NUM_ENDPOINTS ) |
1015 { | |
893 return NULL; | 1016 return NULL; |
1017 } | |
1018 | |
894 __disable_irq(); | 1019 __disable_irq(); |
1020 | |
1021 // Receive packet, check pointer | |
895 ret = rx_first[endpoint]; | 1022 ret = rx_first[endpoint]; |
896 if ( ret ) | 1023 if ( ret ) |
1024 { | |
897 rx_first[ endpoint ] = ret->next; | 1025 rx_first[ endpoint ] = ret->next; |
898 usb_rx_byte_count_data[ endpoint ] -= ret->len; | 1026 usb_rx_byte_count_data[ endpoint ] -= ret->len; |
1027 } | |
1028 | |
899 __enable_irq(); | 1029 __enable_irq(); |
1030 | |
900 //serial_print("rx, epidx="); | 1031 //serial_print("rx, epidx="); |
901 //serial_phex(endpoint); | 1032 //serial_phex(endpoint); |
902 //serial_print(", packet="); | 1033 //serial_print(", packet="); |
903 //serial_phex32(ret); | 1034 //serial_phex32(ret); |
904 //serial_print("\n"); | 1035 //serial_print("\n"); |
992 usb_rx_memory_needed = 0; | 1123 usb_rx_memory_needed = 0; |
993 usb_free( packet ); | 1124 usb_free( packet ); |
994 return; | 1125 return; |
995 } | 1126 } |
996 | 1127 |
997 //#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd)) | 1128 // Call whenever there's an action that may wake the host device |
998 //#define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) | 1129 void usb_resume() |
999 | 1130 { |
1000 void usb_tx( uint32_t endpoint, usb_packet_t *packet ) | |
1001 { | |
1002 // Update expiry counter | |
1003 USBKeys_Idle_Expiry = systick_millis_count; | |
1004 | |
1005 // If we have been sleeping, try to wake up host | 1131 // If we have been sleeping, try to wake up host |
1006 if ( usb_dev_sleep ) | 1132 if ( usb_dev_sleep && usb_configured() ) |
1007 { | 1133 { |
1134 #if enableUSBResume_define == 1 | |
1135 #if enableVirtualSerialPort_define != 1 | |
1136 info_print("Attempting to resume the host"); | |
1137 #endif | |
1008 // Force wake-up for 10 ms | 1138 // Force wake-up for 10 ms |
1009 // According to the USB Spec a device must hold resume for at least 1 ms but no more than 15 ms | 1139 // According to the USB Spec a device must hold resume for at least 1 ms but no more than 15 ms |
1010 USB0_CTL |= USB_CTL_RESUME; | 1140 USB0_CTL |= USB_CTL_RESUME; |
1011 delay(10); | 1141 delay(10); |
1012 USB0_CTL &= ~(USB_CTL_RESUME); | 1142 USB0_CTL &= ~(USB_CTL_RESUME); |
1013 delay(50); // Wait for at least 50 ms to make sure the bus is clear | 1143 delay(50); // Wait for at least 50 ms to make sure the bus is clear |
1014 usb_dev_sleep = 0; // Make sure we don't call this again, may crash system | 1144 usb_dev_sleep = 0; // Make sure we don't call this again, may crash system |
1015 } | 1145 #else |
1146 warn_print("Host Resume Disabled"); | |
1147 #endif | |
1148 } | |
1149 | |
1150 } | |
1151 | |
1152 void usb_tx( uint32_t endpoint, usb_packet_t *packet ) | |
1153 { | |
1154 // Update expiry counter | |
1155 USBKeys_Idle_Expiry = systick_millis_count; | |
1016 | 1156 |
1017 // Since we are transmitting data, USB will be brought out of sleep/suspend | 1157 // Since we are transmitting data, USB will be brought out of sleep/suspend |
1018 // if it's in that state | 1158 // if it's in that state |
1019 // Use the currently set descriptor value | 1159 // Use the currently set descriptor value |
1020 Output_update_usb_current( *usb_bMaxPower * 2 ); | 1160 Output_update_usb_current( *usb_bMaxPower * 2 ); |
1085 | 1225 |
1086 void usb_isr() | 1226 void usb_isr() |
1087 { | 1227 { |
1088 uint8_t status, stat, t; | 1228 uint8_t status, stat, t; |
1089 | 1229 |
1090 //serial_print("isr"); | |
1091 //status = USB0_ISTAT; | |
1092 //serial_phex(status); | |
1093 //serial_print("\n"); | |
1094 restart: | 1230 restart: |
1095 status = USB0_ISTAT; | 1231 status = USB0_ISTAT; |
1096 /* | 1232 /* |
1097 print("USB ISR STATUS: "); | 1233 print(" ISR("); |
1098 printHex( status ); | 1234 printHex( status ); |
1099 print( NL ); | 1235 print(") "); |
1100 */ | 1236 */ |
1101 | 1237 |
1102 if ( (status & USB_INTEN_SOFTOKEN /* 04 */ ) ) | 1238 if ( (status & USB_INTEN_SOFTOKEN /* 04 */ ) ) |
1103 { | 1239 { |
1104 if ( usb_configuration ) | 1240 if ( usb_configuration ) |
1110 if ( !t ) | 1246 if ( !t ) |
1111 usb_device_reload(); | 1247 usb_device_reload(); |
1112 } | 1248 } |
1113 | 1249 |
1114 // CDC Interface | 1250 // CDC Interface |
1251 #if enableVirtualSerialPort_define == 1 | |
1115 t = usb_cdc_transmit_flush_timer; | 1252 t = usb_cdc_transmit_flush_timer; |
1116 if ( t ) | 1253 if ( t ) |
1117 { | 1254 { |
1118 usb_cdc_transmit_flush_timer = --t; | 1255 usb_cdc_transmit_flush_timer = --t; |
1119 if ( t == 0 ) | 1256 if ( t == 0 ) |
1120 usb_serial_flush_callback(); | 1257 usb_serial_flush_callback(); |
1121 } | 1258 } |
1259 #endif | |
1122 | 1260 |
1123 } | 1261 } |
1124 USB0_ISTAT = USB_INTEN_SOFTOKEN; | 1262 USB0_ISTAT = USB_INTEN_SOFTOKEN; |
1125 } | 1263 } |
1126 | 1264 |
1321 | 1459 |
1322 // USB Host signalling device to enter 'sleep' state | 1460 // USB Host signalling device to enter 'sleep' state |
1323 // The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms | 1461 // The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms |
1324 if ( (status & USB_ISTAT_SLEEP /* 10 */ ) ) | 1462 if ( (status & USB_ISTAT_SLEEP /* 10 */ ) ) |
1325 { | 1463 { |
1326 //info_print("Host has requested USB sleep/suspend state"); | 1464 #if enableUSBSuspend_define == 1 |
1465 // Can cause issues with the virtual serial port | |
1466 #if enableVirtualSerialPort_define != 1 | |
1467 info_print("Host has requested USB sleep/suspend state"); | |
1468 #endif | |
1327 Output_update_usb_current( 100 ); // Set to 100 mA | 1469 Output_update_usb_current( 100 ); // Set to 100 mA |
1328 usb_dev_sleep = 1; | 1470 usb_dev_sleep = 1; |
1471 #else | |
1472 info_print("USB Suspend Detected - Firmware USB Suspend Disabled"); | |
1473 #endif | |
1329 USB0_ISTAT |= USB_ISTAT_SLEEP; | 1474 USB0_ISTAT |= USB_ISTAT_SLEEP; |
1330 } | 1475 } |
1331 | 1476 |
1332 // On USB Resume, unset the usb_dev_sleep so we don't keep sending resume signals | 1477 // On USB Resume, unset the usb_dev_sleep so we don't keep sending resume signals |
1333 if ( (status & USB_ISTAT_RESUME /* 20 */ ) ) | 1478 if ( (status & USB_ISTAT_RESUME /* 20 */ ) ) |
1334 { | 1479 { |
1335 //info_print("Host has woken-up/resumed from sleep/suspend state"); | 1480 // Can cause issues with the virtual serial port |
1481 #if enableVirtualSerialPort_define != 1 | |
1482 info_print("Host has woken-up/resumed from sleep/suspend state"); | |
1483 #endif | |
1336 Output_update_usb_current( *usb_bMaxPower * 2 ); | 1484 Output_update_usb_current( *usb_bMaxPower * 2 ); |
1337 usb_dev_sleep = 0; | 1485 usb_dev_sleep = 0; |
1338 USB0_ISTAT |= USB_ISTAT_RESUME; | 1486 USB0_ISTAT |= USB_ISTAT_RESUME; |
1339 } | 1487 } |
1340 } | 1488 } |
1344 uint8_t usb_init() | 1492 uint8_t usb_init() |
1345 { | 1493 { |
1346 #ifdef UART_DEBUG | 1494 #ifdef UART_DEBUG |
1347 print("USB INIT"NL); | 1495 print("USB INIT"NL); |
1348 #endif | 1496 #endif |
1497 | |
1498 USBInit_TimeStart = systick_millis_count; | |
1499 USBInit_Ticks = 0; | |
1500 | |
1501 // XXX Set wTotalLength here instead of using defines | |
1502 // Simplifies defines considerably | |
1503 usb_set_config_descriptor_size(); | |
1349 | 1504 |
1350 // Clear out endpoints table | 1505 // Clear out endpoints table |
1351 for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ ) | 1506 for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ ) |
1352 { | 1507 { |
1353 table[i].desc = 0; | 1508 table[i].desc = 0; |