comparison Output/pjrcUSB/output_com.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
69 void cliFunc_outputDebug( char* args ); 69 void cliFunc_outputDebug( char* args );
70 void cliFunc_readLEDs ( char* args ); 70 void cliFunc_readLEDs ( char* args );
71 void cliFunc_sendKeys ( char* args ); 71 void cliFunc_sendKeys ( char* args );
72 void cliFunc_setKeys ( char* args ); 72 void cliFunc_setKeys ( char* args );
73 void cliFunc_setMod ( char* args ); 73 void cliFunc_setMod ( char* args );
74 void cliFunc_usbInitTime( char* args );
74 75
75 76
76 77
77 // ----- Variables ----- 78 // ----- Variables -----
78 79
81 CLIDict_Entry( outputDebug, "Toggle Output Debug mode." ); 82 CLIDict_Entry( outputDebug, "Toggle Output Debug mode." );
82 CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc." ); 83 CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc." );
83 CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." ); 84 CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." );
84 CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." ); 85 CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." );
85 CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI" ); 86 CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI" );
87 CLIDict_Entry( usbInitTime, "Displays the time in ms from usb_init() till the last setup call." );
86 88
87 CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { 89 CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
88 CLIDict_Item( kbdProtocol ), 90 CLIDict_Item( kbdProtocol ),
89 CLIDict_Item( outputDebug ), 91 CLIDict_Item( outputDebug ),
90 CLIDict_Item( readLEDs ), 92 CLIDict_Item( readLEDs ),
91 CLIDict_Item( sendKeys ), 93 CLIDict_Item( sendKeys ),
92 CLIDict_Item( setKeys ), 94 CLIDict_Item( setKeys ),
93 CLIDict_Item( setMod ), 95 CLIDict_Item( setMod ),
96 CLIDict_Item( usbInitTime ),
94 { 0, 0, 0 } // Null entry for dictionary end 97 { 0, 0, 0 } // Null entry for dictionary end
95 }; 98 };
96 99
97 100
98 // Which modifier keys are currently pressed 101 // Which modifier keys are currently pressed
160 163
161 // mA - Set by USB module (if exists) 164 // mA - Set by USB module (if exists)
162 // Initially 100 mA, but may be negotiated higher (e.g. 500 mA) 165 // Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
163 uint16_t Output_USBCurrent_Available = 0; 166 uint16_t Output_USBCurrent_Available = 0;
164 167
168 // USB Init Time (ms) - usb_init()
169 volatile uint32_t USBInit_TimeStart;
170 volatile uint32_t USBInit_TimeEnd;
171 volatile uint16_t USBInit_Ticks;
172
165 173
166 174
167 // ----- Capabilities ----- 175 // ----- Capabilities -----
168 176
169 // Set Boot Keyboard Protocol 177 // Set Boot Keyboard Protocol
170 void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 178 void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args )
171 { 179 {
180 #if enableKeyboard_define == 1
172 // Display capability name 181 // Display capability name
173 if ( stateType == 0xFF && state == 0xFF ) 182 if ( stateType == 0xFF && state == 0xFF )
174 { 183 {
175 print("Output_kbdProtocolBoot()"); 184 print("Output_kbdProtocolBoot()");
176 return; 185 return;
188 // Flush the key buffers 197 // Flush the key buffers
189 Output_flushBuffers(); 198 Output_flushBuffers();
190 199
191 // Set the keyboard protocol to Boot Mode 200 // Set the keyboard protocol to Boot Mode
192 USBKeys_Protocol = 0; 201 USBKeys_Protocol = 0;
202 #endif
193 } 203 }
194 204
195 205
196 // Set NKRO Keyboard Protocol 206 // Set NKRO Keyboard Protocol
197 void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 207 void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args )
198 { 208 {
209 #if enableKeyboard_define == 1
199 // Display capability name 210 // Display capability name
200 if ( stateType == 0xFF && state == 0xFF ) 211 if ( stateType == 0xFF && state == 0xFF )
201 { 212 {
202 print("Output_kbdProtocolNKRO()"); 213 print("Output_kbdProtocolNKRO()");
203 return; 214 return;
215 // Flush the key buffers 226 // Flush the key buffers
216 Output_flushBuffers(); 227 Output_flushBuffers();
217 228
218 // Set the keyboard protocol to NKRO Mode 229 // Set the keyboard protocol to NKRO Mode
219 USBKeys_Protocol = 1; 230 USBKeys_Protocol = 1;
231 #endif
220 } 232 }
221 233
222 234
223 // Toggle Keyboard Protocol 235 // Toggle Keyboard Protocol
224 void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 236 void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args )
225 { 237 {
238 #if enableKeyboard_define == 1
226 // Display capability name 239 // Display capability name
227 if ( stateType == 0xFF && state == 0xFF ) 240 if ( stateType == 0xFF && state == 0xFF )
228 { 241 {
229 print("Output_toggleKbdProtocol()"); 242 print("Output_toggleKbdProtocol()");
230 return; 243 return;
237 Output_flushBuffers(); 250 Output_flushBuffers();
238 251
239 // Toggle the keyboard protocol Mode 252 // Toggle the keyboard protocol Mode
240 USBKeys_Protocol = !USBKeys_Protocol; 253 USBKeys_Protocol = !USBKeys_Protocol;
241 } 254 }
255 #endif
242 } 256 }
243 257
244 258
245 // Sends a Consumer Control code to the USB Output buffer 259 // Sends a Consumer Control code to the USB Output buffer
246 void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 260 void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
247 { 261 {
262 #if enableKeyboard_define == 1
248 // Display capability name 263 // Display capability name
249 if ( stateType == 0xFF && state == 0xFF ) 264 if ( stateType == 0xFF && state == 0xFF )
250 { 265 {
251 print("Output_consCtrlSend(consCode)"); 266 print("Output_consCtrlSend(consCode)");
252 return; 267 return;
271 return; 286 return;
272 } 287 }
273 288
274 // Set consumer control code 289 // Set consumer control code
275 USBKeys_ConsCtrl = *(uint16_t*)(&args[0]); 290 USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
291 #endif
276 } 292 }
277 293
278 294
279 // Ignores the given key status update 295 // Ignores the given key status update
280 // Used to prevent fall-through, this is the None keyword in KLL 296 // Used to prevent fall-through, this is the None keyword in KLL
292 308
293 309
294 // Sends a System Control code to the USB Output buffer 310 // Sends a System Control code to the USB Output buffer
295 void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 311 void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
296 { 312 {
313 #if enableKeyboard_define == 1
297 // Display capability name 314 // Display capability name
298 if ( stateType == 0xFF && state == 0xFF ) 315 if ( stateType == 0xFF && state == 0xFF )
299 { 316 {
300 print("Output_sysCtrlSend(sysCode)"); 317 print("Output_sysCtrlSend(sysCode)");
301 return; 318 return;
320 return; 337 return;
321 } 338 }
322 339
323 // Set system control code 340 // Set system control code
324 USBKeys_SysCtrl = args[0]; 341 USBKeys_SysCtrl = args[0];
342 #endif
325 } 343 }
326 344
327 345
328 // Adds a single USB Code to the USB Output buffer 346 // Adds a single USB Code to the USB Output buffer
329 // Argument #1: USB Code 347 // Argument #1: USB Code
330 void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 348 void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
331 { 349 {
350 #if enableKeyboard_define == 1
332 // Display capability name 351 // Display capability name
333 if ( stateType == 0xFF && state == 0xFF ) 352 if ( stateType == 0xFF && state == 0xFF )
334 { 353 {
335 print("Output_usbCodeSend(usbCode)"); 354 print("Output_usbCodeSend(usbCode)");
336 return; 355 return;
527 USBKeys_Sent++; 546 USBKeys_Sent++;
528 } 547 }
529 548
530 break; 549 break;
531 } 550 }
551 #endif
532 } 552 }
533 553
534 void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 554 void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
535 { 555 {
536 // Display capability name 556 // Display capability name
542 562
543 // Start flash mode 563 // Start flash mode
544 Output_firmwareReload(); 564 Output_firmwareReload();
545 } 565 }
546 566
567 #if enableMouse_define == 1
547 // Sends a mouse command over the USB Output buffer 568 // Sends a mouse command over the USB Output buffer
548 // XXX This function *will* be changing in the future 569 // XXX This function *will* be changing in the future
549 // If you use it, be prepared that your .kll files will break in the future (post KLL 0.5) 570 // If you use it, be prepared that your .kll files will break in the future (post KLL 0.5)
550 // Argument #1: USB Mouse Button (16 bit) 571 // Argument #1: USB Mouse Button (16 bit)
551 // Argument #2: USB X Axis (16 bit) relative 572 // Argument #2: USB X Axis (16 bit) relative
598 USBMouse_Changed |= USBMouseChangeState_Buttons; 619 USBMouse_Changed |= USBMouseChangeState_Buttons;
599 620
600 if ( mouse_x || mouse_y ) 621 if ( mouse_x || mouse_y )
601 USBMouse_Changed |= USBMouseChangeState_Relative; 622 USBMouse_Changed |= USBMouseChangeState_Relative;
602 } 623 }
624 #endif
603 625
604 626
605 627
606 // ----- Functions ----- 628 // ----- Functions -----
607 629
640 inline void Output_send() 662 inline void Output_send()
641 { 663 {
642 // USB status checks 664 // USB status checks
643 // Non-standard USB state manipulation, usually does nothing 665 // Non-standard USB state manipulation, usually does nothing
644 usb_device_check(); 666 usb_device_check();
645
646 // Boot Mode Only, unset stale keys
647 if ( USBKeys_Protocol == 0 )
648 for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
649 USBKeys_Keys[c] = 0;
650 667
651 // XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa 668 // XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa
652 /* 669 /*
653 // Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update 670 // Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update
654 // TODO Add joystick as well (may be endpoint specific, currently not kept track of) 671 // TODO Add joystick as well (may be endpoint specific, currently not kept track of)
659 USBKeys_Changed = USBKeyChangeState_All; 676 USBKeys_Changed = USBKeyChangeState_All;
660 USBMouse_Changed = USBMouseChangeState_All; 677 USBMouse_Changed = USBMouseChangeState_All;
661 } 678 }
662 */ 679 */
663 680
681 #if enableMouse_define == 1
664 // Process mouse actions 682 // Process mouse actions
665 while ( USBMouse_Changed ) 683 while ( USBMouse_Changed )
666 usb_mouse_send(); 684 usb_mouse_send();
685 #endif
686
687 #if enableKeyboard_define == 1
688 // Boot Mode Only, unset stale keys
689 if ( USBKeys_Protocol == 0 )
690 for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
691 USBKeys_Keys[c] = 0;
667 692
668 // Send keypresses while there are pending changes 693 // Send keypresses while there are pending changes
669 while ( USBKeys_Changed ) 694 while ( USBKeys_Changed )
670 usb_keyboard_send(); 695 usb_keyboard_send();
671 696
682 break; 707 break;
683 case 1: // NKRO Mode 708 case 1: // NKRO Mode
684 Scan_finishedWithOutput( USBKeys_Sent ); 709 Scan_finishedWithOutput( USBKeys_Sent );
685 break; 710 break;
686 } 711 }
712 #endif
687 } 713 }
688 714
689 715
690 // Sets the device into firmware reload mode 716 // Sets the device into firmware reload mode
691 inline void Output_firmwareReload() 717 inline void Output_firmwareReload()
695 721
696 722
697 // USB Input buffer available 723 // USB Input buffer available
698 inline unsigned int Output_availablechar() 724 inline unsigned int Output_availablechar()
699 { 725 {
726 #if enableVirtualSerialPort_define == 1
700 return usb_serial_available(); 727 return usb_serial_available();
728 #else
729 return 0;
730 #endif
701 } 731 }
702 732
703 733
704 // USB Get Character from input buffer 734 // USB Get Character from input buffer
705 inline int Output_getchar() 735 inline int Output_getchar()
706 { 736 {
737 #if enableVirtualSerialPort_define == 1
707 // XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR) 738 // XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR)
708 return (int)usb_serial_getchar(); 739 return (int)usb_serial_getchar();
740 #else
741 return 0;
742 #endif
709 } 743 }
710 744
711 745
712 // USB Send Character to output buffer 746 // USB Send Character to output buffer
713 inline int Output_putchar( char c ) 747 inline int Output_putchar( char c )
714 { 748 {
749 #if enableVirtualSerialPort_define == 1
715 return usb_serial_putchar( c ); 750 return usb_serial_putchar( c );
751 #else
752 return 0;
753 #endif
716 } 754 }
717 755
718 756
719 // USB Send String to output buffer, null terminated 757 // USB Send String to output buffer, null terminated
720 inline int Output_putstr( char* str ) 758 inline int Output_putstr( char* str )
721 { 759 {
760 #if enableVirtualSerialPort_define == 1
722 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR 761 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
723 uint16_t count = 0; 762 uint16_t count = 0;
724 #elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM 763 #elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM
725 uint32_t count = 0; 764 uint32_t count = 0;
726 #endif 765 #endif
727 // Count characters until NULL character, then send the amount counted 766 // Count characters until NULL character, then send the amount counted
728 while ( str[count] != '\0' ) 767 while ( str[count] != '\0' )
729 count++; 768 count++;
730 769
731 return usb_serial_write( str, count ); 770 return usb_serial_write( str, count );
771 #else
772 return 0;
773 #endif
732 } 774 }
733 775
734 776
735 // Soft Chip Reset 777 // Soft Chip Reset
736 inline void Output_softReset() 778 inline void Output_softReset()
737 { 779 {
738 usb_device_software_reset(); 780 usb_device_software_reset();
781 }
782
783
784 // USB RawIO buffer available
785 inline unsigned int Output_rawio_availablechar()
786 {
787 #if enableRawIO_define == 1
788 return usb_rawio_available();
789 #else
790 return 0;
791 #endif
792 }
793
794
795 // USB RawIO get buffer
796 // XXX Must be a 64 byte buffer
797 inline int Output_rawio_getbuffer( char* buffer )
798 {
799 #if enableRawIO_define == 1
800 // No timeout, fail immediately
801 return usb_rawio_rx( (void*)buffer, 0 );
802 #else
803 return 0;
804 #endif
805 }
806
807
808 // USB RawIO send buffer
809 // XXX Must be a 64 byte buffer
810 inline int Output_rawio_sendbuffer( char* buffer )
811 {
812 #if enableRawIO_define == 1
813 // No timeout, fail immediately
814 return usb_rawio_tx( (void*)buffer, 0 );
815 #else
816 return 0;
817 #endif
739 } 818 }
740 819
741 820
742 // Update USB current (mA) 821 // Update USB current (mA)
743 // Triggers power change event 822 // Triggers power change event
890 CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); 969 CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
891 970
892 USBKeys_ModifiersCLI = numToInt( arg1Ptr ); 971 USBKeys_ModifiersCLI = numToInt( arg1Ptr );
893 } 972 }
894 973
974 void cliFunc_usbInitTime( char* args )
975 {
976 // Calculate overall USB initialization time
977 // XXX A protocol analyzer will be more accurate, however, this is built-in and easier to collect data
978 print(NL);
979 info_msg("USB Init Time: ");
980 printInt32( USBInit_TimeEnd - USBInit_TimeStart );
981 print(" ms - ");
982 printInt16( USBInit_Ticks );
983 print(" ticks");
984 }
985