comparison Output/usbMuxUart/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
49 49
50 50
51 // ----- Macros ----- 51 // ----- Macros -----
52 52
53 // Used to build a bitmap lookup table from a byte addressable array 53 // Used to build a bitmap lookup table from a byte addressable array
54 #define byteLookup( byte ) case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \ 54 #define byteLookup( byte ) \
55 case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \ 55 case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \
56 case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \ 56 case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \
57 case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \ 57 case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \
58 case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \ 58 case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \
59 case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \ 59 case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \
60 case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \ 60 case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \
61 case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break 61 case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \
62 case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break
62 63
63 64
64 65
65 // ----- Function Declarations ----- 66 // ----- Function Declarations -----
66 67
70 void cliFunc_readUART ( char* args ); 71 void cliFunc_readUART ( char* args );
71 void cliFunc_sendKeys ( char* args ); 72 void cliFunc_sendKeys ( char* args );
72 void cliFunc_sendUART ( char* args ); 73 void cliFunc_sendUART ( char* args );
73 void cliFunc_setKeys ( char* args ); 74 void cliFunc_setKeys ( char* args );
74 void cliFunc_setMod ( char* args ); 75 void cliFunc_setMod ( char* args );
76 void cliFunc_usbInitTime( char* args );
75 77
76 78
77 79
78 // ----- Variables ----- 80 // ----- Variables -----
79 81
84 CLIDict_Entry( readUART, "Read UART buffer until empty." ); 86 CLIDict_Entry( readUART, "Read UART buffer until empty." );
85 CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." ); 87 CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." );
86 CLIDict_Entry( sendUART, "Send characters over UART0." ); 88 CLIDict_Entry( sendUART, "Send characters over UART0." );
87 CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." ); 89 CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." );
88 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" ); 90 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" );
91 CLIDict_Entry( usbInitTime, "Displays the time in ms from usb_init() till the last setup call." );
89 92
90 CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { 93 CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
91 CLIDict_Item( kbdProtocol ), 94 CLIDict_Item( kbdProtocol ),
92 CLIDict_Item( outputDebug ), 95 CLIDict_Item( outputDebug ),
93 CLIDict_Item( readLEDs ), 96 CLIDict_Item( readLEDs ),
94 CLIDict_Item( readUART ), 97 CLIDict_Item( readUART ),
95 CLIDict_Item( sendKeys ), 98 CLIDict_Item( sendKeys ),
96 CLIDict_Item( sendUART ), 99 CLIDict_Item( sendUART ),
97 CLIDict_Item( setKeys ), 100 CLIDict_Item( setKeys ),
98 CLIDict_Item( setMod ), 101 CLIDict_Item( setMod ),
102 CLIDict_Item( usbInitTime ),
99 { 0, 0, 0 } // Null entry for dictionary end 103 { 0, 0, 0 } // Null entry for dictionary end
100 }; 104 };
101 105
102 106
103 // Which modifier keys are currently pressed 107 // Which modifier keys are currently pressed
165 169
166 // mA - Set by USB module (if exists) 170 // mA - Set by USB module (if exists)
167 // Initially 100 mA, but may be negotiated higher (e.g. 500 mA) 171 // Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
168 uint16_t Output_USBCurrent_Available = 0; 172 uint16_t Output_USBCurrent_Available = 0;
169 173
174 // USB Init Time (ms)
175 volatile uint32_t USBInit_TimeStart;
176 volatile uint32_t USBInit_TimeEnd;
177 volatile uint16_t USBInit_Ticks;
178
170 179
171 180
172 // ----- Capabilities ----- 181 // ----- Capabilities -----
173 182
174 // Set Boot Keyboard Protocol 183 // Set Boot Keyboard Protocol
175 void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 184 void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args )
176 { 185 {
186 #if enableKeyboard_define == 1
177 // Display capability name 187 // Display capability name
178 if ( stateType == 0xFF && state == 0xFF ) 188 if ( stateType == 0xFF && state == 0xFF )
179 { 189 {
180 print("Output_kbdProtocolBoot()"); 190 print("Output_kbdProtocolBoot()");
181 return; 191 return;
193 // Flush the key buffers 203 // Flush the key buffers
194 Output_flushBuffers(); 204 Output_flushBuffers();
195 205
196 // Set the keyboard protocol to Boot Mode 206 // Set the keyboard protocol to Boot Mode
197 USBKeys_Protocol = 0; 207 USBKeys_Protocol = 0;
208 #endif
198 } 209 }
199 210
200 211
201 // Set NKRO Keyboard Protocol 212 // Set NKRO Keyboard Protocol
202 void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 213 void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args )
203 { 214 {
215 #if enableKeyboard_define == 1
204 // Display capability name 216 // Display capability name
205 if ( stateType == 0xFF && state == 0xFF ) 217 if ( stateType == 0xFF && state == 0xFF )
206 { 218 {
207 print("Output_kbdProtocolNKRO()"); 219 print("Output_kbdProtocolNKRO()");
208 return; 220 return;
220 // Flush the key buffers 232 // Flush the key buffers
221 Output_flushBuffers(); 233 Output_flushBuffers();
222 234
223 // Set the keyboard protocol to NKRO Mode 235 // Set the keyboard protocol to NKRO Mode
224 USBKeys_Protocol = 1; 236 USBKeys_Protocol = 1;
237 #endif
225 } 238 }
226 239
227 240
228 // Toggle Keyboard Protocol 241 // Toggle Keyboard Protocol
229 void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 242 void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args )
230 { 243 {
244 #if enableKeyboard_define == 1
231 // Display capability name 245 // Display capability name
232 if ( stateType == 0xFF && state == 0xFF ) 246 if ( stateType == 0xFF && state == 0xFF )
233 { 247 {
234 print("Output_toggleKbdProtocol()"); 248 print("Output_toggleKbdProtocol()");
235 return; 249 return;
242 Output_flushBuffers(); 256 Output_flushBuffers();
243 257
244 // Toggle the keyboard protocol Mode 258 // Toggle the keyboard protocol Mode
245 USBKeys_Protocol = !USBKeys_Protocol; 259 USBKeys_Protocol = !USBKeys_Protocol;
246 } 260 }
261 #endif
247 } 262 }
248 263
249 264
250 // Sends a Consumer Control code to the USB Output buffer 265 // Sends a Consumer Control code to the USB Output buffer
251 void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 266 void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
252 { 267 {
268 #if enableKeyboard_define == 1
253 // Display capability name 269 // Display capability name
254 if ( stateType == 0xFF && state == 0xFF ) 270 if ( stateType == 0xFF && state == 0xFF )
255 { 271 {
256 print("Output_consCtrlSend(consCode)"); 272 print("Output_consCtrlSend(consCode)");
257 return; 273 return;
276 return; 292 return;
277 } 293 }
278 294
279 // Set consumer control code 295 // Set consumer control code
280 USBKeys_ConsCtrl = *(uint16_t*)(&args[0]); 296 USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
297 #endif
281 } 298 }
282 299
283 300
284 // Ignores the given key status update 301 // Ignores the given key status update
285 // Used to prevent fall-through, this is the None keyword in KLL 302 // Used to prevent fall-through, this is the None keyword in KLL
297 314
298 315
299 // Sends a System Control code to the USB Output buffer 316 // Sends a System Control code to the USB Output buffer
300 void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 317 void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
301 { 318 {
319 #if enableKeyboard_define == 1
302 // Display capability name 320 // Display capability name
303 if ( stateType == 0xFF && state == 0xFF ) 321 if ( stateType == 0xFF && state == 0xFF )
304 { 322 {
305 print("Output_sysCtrlSend(sysCode)"); 323 print("Output_sysCtrlSend(sysCode)");
306 return; 324 return;
325 return; 343 return;
326 } 344 }
327 345
328 // Set system control code 346 // Set system control code
329 USBKeys_SysCtrl = args[0]; 347 USBKeys_SysCtrl = args[0];
348 #endif
330 } 349 }
331 350
332 351
333 // Adds a single USB Code to the USB Output buffer 352 // Adds a single USB Code to the USB Output buffer
334 // Argument #1: USB Code 353 // Argument #1: USB Code
335 void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 354 void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
336 { 355 {
356 #if enableKeyboard_define == 1
337 // Display capability name 357 // Display capability name
338 if ( stateType == 0xFF && state == 0xFF ) 358 if ( stateType == 0xFF && state == 0xFF )
339 { 359 {
340 print("Output_usbCodeSend(usbCode)"); 360 print("Output_usbCodeSend(usbCode)");
341 return; 361 return;
532 USBKeys_Sent++; 552 USBKeys_Sent++;
533 } 553 }
534 554
535 break; 555 break;
536 } 556 }
557 #endif
537 } 558 }
538 559
539 void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 560 void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
540 { 561 {
541 // Display capability name 562 // Display capability name
555 // Argument #1: USB Mouse Button (16 bit) 576 // Argument #1: USB Mouse Button (16 bit)
556 // Argument #2: USB X Axis (16 bit) relative 577 // Argument #2: USB X Axis (16 bit) relative
557 // Argument #3: USB Y Axis (16 bit) relative 578 // Argument #3: USB Y Axis (16 bit) relative
558 void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 579 void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args )
559 { 580 {
581 #if enableMouse_define == 1
560 // Display capability name 582 // Display capability name
561 if ( stateType == 0xFF && state == 0xFF ) 583 if ( stateType == 0xFF && state == 0xFF )
562 { 584 {
563 print("Output_usbMouse(mouseButton,relX,relY)"); 585 print("Output_usbMouse(mouseButton,relX,relY)");
564 return; 586 return;
602 if ( mouse_button ) 624 if ( mouse_button )
603 USBMouse_Changed |= USBMouseChangeState_Buttons; 625 USBMouse_Changed |= USBMouseChangeState_Buttons;
604 626
605 if ( mouse_x || mouse_y ) 627 if ( mouse_x || mouse_y )
606 USBMouse_Changed |= USBMouseChangeState_Relative; 628 USBMouse_Changed |= USBMouseChangeState_Relative;
629 #endif
607 } 630 }
608 631
609 632
610 633
611 // ----- Functions ----- 634 // ----- Functions -----
650 // USB status checks 673 // USB status checks
651 // Non-standard USB state manipulation, usually does nothing 674 // Non-standard USB state manipulation, usually does nothing
652 usb_device_check(); 675 usb_device_check();
653 676
654 // Boot Mode Only, unset stale keys 677 // Boot Mode Only, unset stale keys
655 if ( USBKeys_Protocol == 0 )
656 for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
657 USBKeys_Keys[c] = 0;
658
659 // XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa 678 // XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa
660 /* 679 /*
661 // Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update 680 // Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update
662 // TODO Add joystick as well (may be endpoint specific, currently not kept track of) 681 // TODO Add joystick as well (may be endpoint specific, currently not kept track of)
663 if ( usb_configuration && USBKeys_Idle_Config && ( 682 if ( usb_configuration && USBKeys_Idle_Config && (
667 USBKeys_Changed = USBKeyChangeState_All; 686 USBKeys_Changed = USBKeyChangeState_All;
668 USBMouse_Changed = USBMouseChangeState_All; 687 USBMouse_Changed = USBMouseChangeState_All;
669 } 688 }
670 */ 689 */
671 690
691 #if enableMouse_define == 1
672 // Process mouse actions 692 // Process mouse actions
673 while ( USBMouse_Changed ) 693 while ( USBMouse_Changed )
674 usb_mouse_send(); 694 usb_mouse_send();
695 #endif
696
697 #if enableKeyboard_define == 1
698 if ( USBKeys_Protocol == 0 )
699 for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
700 USBKeys_Keys[c] = 0;
675 701
676 // Send keypresses while there are pending changes 702 // Send keypresses while there are pending changes
677 while ( USBKeys_Changed ) 703 while ( USBKeys_Changed )
678 usb_keyboard_send(); 704 usb_keyboard_send();
679 705
690 break; 716 break;
691 case 1: // NKRO Mode 717 case 1: // NKRO Mode
692 Scan_finishedWithOutput( USBKeys_Sent ); 718 Scan_finishedWithOutput( USBKeys_Sent );
693 break; 719 break;
694 } 720 }
721 #endif
695 } 722 }
696 723
697 724
698 // Sets the device into firmware reload mode 725 // Sets the device into firmware reload mode
699 void Output_firmwareReload() 726 void Output_firmwareReload()
703 730
704 731
705 // USB Input buffer available 732 // USB Input buffer available
706 inline unsigned int Output_availablechar() 733 inline unsigned int Output_availablechar()
707 { 734 {
735 #if enableVirtualSerialPort_define == 1
708 return usb_serial_available() + uart_serial_available(); 736 return usb_serial_available() + uart_serial_available();
737 #else
738 return uart_serial_available();
739 #endif
709 } 740 }
710 741
711 742
712 // USB Get Character from input buffer 743 // USB Get Character from input buffer
713 inline int Output_getchar() 744 inline int Output_getchar()
714 { 745 {
746 #if enableVirtualSerialPort_define == 1
715 // XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR) 747 // XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR)
716 if ( usb_serial_available() > 0 ) 748 if ( usb_serial_available() > 0 )
717 { 749 {
718 return (int)usb_serial_getchar(); 750 return (int)usb_serial_getchar();
719 } 751 }
752 #endif
720 753
721 if ( uart_serial_available() > 0 ) 754 if ( uart_serial_available() > 0 )
722 { 755 {
723 return (int)uart_serial_getchar(); 756 return (int)uart_serial_getchar();
724 } 757 }
728 761
729 762
730 // USB Send Character to output buffer 763 // USB Send Character to output buffer
731 inline int Output_putchar( char c ) 764 inline int Output_putchar( char c )
732 { 765 {
766 #if enableVirtualSerialPort_define == 1
733 // First send to UART 767 // First send to UART
734 uart_serial_putchar( c ); 768 uart_serial_putchar( c );
735 769
736 // Then send to USB 770 // Then send to USB
737 return usb_serial_putchar( c ); 771 return usb_serial_putchar( c );
772 #else
773 return uart_serial_putchar( c );
774 #endif
738 } 775 }
739 776
740 777
741 // USB Send String to output buffer, null terminated 778 // USB Send String to output buffer, null terminated
742 inline int Output_putstr( char* str ) 779 inline int Output_putstr( char* str )
748 #endif 785 #endif
749 // Count characters until NULL character, then send the amount counted 786 // Count characters until NULL character, then send the amount counted
750 while ( str[count] != '\0' ) 787 while ( str[count] != '\0' )
751 count++; 788 count++;
752 789
790 #if enableVirtualSerialPort_define == 1
753 // First send to UART 791 // First send to UART
754 uart_serial_write( str, count ); 792 uart_serial_write( str, count );
755 793
756 // Then send to USB 794 // Then send to USB
757 return usb_serial_write( str, count ); 795 return usb_serial_write( str, count );
796 #else
797 return uart_serial_write( str, count );
798 #endif
758 } 799 }
759 800
760 801
761 // Soft Chip Reset 802 // Soft Chip Reset
762 inline void Output_softReset() 803 inline void Output_softReset()
936 CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); 977 CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
937 978
938 USBKeys_ModifiersCLI = numToInt( arg1Ptr ); 979 USBKeys_ModifiersCLI = numToInt( arg1Ptr );
939 } 980 }
940 981
982 void cliFunc_usbInitTime( char* args )
983 {
984 // Calculate overall USB initialization time
985 // XXX A protocol analyzer will be more accurate, however, this is built-in and easier to collect data
986 print(NL);
987 info_msg("USB Init Time: ");
988 printInt32( USBInit_TimeEnd - USBInit_TimeStart );
989 print(" ms - ");
990 printInt16( USBInit_Ticks );
991 print(" ticks");
992 }
993