66
66
67
67
68
68
69
+ // ----- Enumerations -----
70
+
71
+ typedef enum {
72
+ OutputReset_None = 0 , // Do nothing
73
+ OutputReset_Restart = 1 , // Clear USB stack and restart the firmware
74
+ OutputReset_Bootloader = 2 , // Clear USB stack and jump to bootloader
75
+ } OutputReset ;
76
+
77
+
78
+
69
79
// ----- Function Declarations -----
70
80
71
81
void cliFunc_idle ( char * args );
@@ -147,6 +157,11 @@ volatile uint16_t USBInit_Ticks;
147
157
// USB Address - Set by host, unique to the bus
148
158
volatile uint8_t USBDev_Address ;
149
159
160
+ // Scheduled USB resets, used to clear USB packets before bringing down the USB stack
161
+ // This is useful for OSs like Windows where then OS doesn't clear the current state
162
+ // after the keyboard is disconnected (i.e. Ctrl keeps being held until Ctrl is pressed again).
163
+ volatile static uint8_t Output_reset_schedule ;
164
+
150
165
// Latency measurement resource
151
166
static uint8_t outputPeriodicLatencyResource ;
152
167
static uint8_t outputPollLatencyResource ;
@@ -710,6 +725,14 @@ void USB_flushBuffers()
710
725
711
726
// Reset USBKeys_Keys size
712
727
USBKeys_Sent = 0 ;
728
+
729
+ // Clear mouse state
730
+ USBMouse_Buttons = 0 ;
731
+ USBMouse_Relative_x = 0 ;
732
+ USBMouse_Relative_y = 0 ;
733
+ USBMouse_VertWheel = 0 ;
734
+ USBMouse_HoriWheel = 0 ;
735
+ USBMouse_Changed = 0 ;
713
736
}
714
737
715
738
@@ -732,17 +755,12 @@ inline void USB_setup()
732
755
USBKeys_LEDs_prev = 0 ;
733
756
USBKeys_LEDs = 0 ;
734
757
735
- // Clear mouse state
736
- USBMouse_Buttons = 0 ;
737
- USBMouse_Relative_x = 0 ;
738
- USBMouse_Relative_y = 0 ;
739
- USBMouse_VertWheel = 0 ;
740
- USBMouse_HoriWheel = 0 ;
741
- USBMouse_Changed = 0 ;
742
-
743
758
// Clear USB address
744
759
USBDev_Address = 0 ;
745
760
761
+ // Clear USB reset state
762
+ Output_reset_schedule = OutputReset_None ;
763
+
746
764
// Flush key buffers
747
765
USB_flushBuffers ();
748
766
@@ -885,10 +903,21 @@ inline void USB_periodic()
885
903
// Start latency measurement
886
904
Latency_start_time ( outputPeriodicLatencyResource );
887
905
906
+ // Check to see if we need to reset the USB buffers
907
+ switch ( Output_reset_schedule )
908
+ {
909
+ case OutputReset_Restart :
910
+ case OutputReset_Bootloader :
911
+ USB_flushBuffers ();
912
+ break ;
913
+ }
914
+
888
915
#if enableMouse_define == 1
889
916
// Process mouse actions
890
917
while ( USBMouse_Changed )
918
+ {
891
919
usb_mouse_send ();
920
+ }
892
921
#endif
893
922
894
923
#if enableKeyboard_define == 1
@@ -936,6 +965,26 @@ inline void USB_periodic()
936
965
USB_suspend_status_update ();
937
966
#endif
938
967
968
+ // Check if a reset needs to be scheduled
969
+ switch ( Output_reset_schedule )
970
+ {
971
+ case OutputReset_Restart :
972
+ // Clear schedule
973
+ Output_reset_schedule = OutputReset_None ;
974
+
975
+ // Restart firmware
976
+ usb_device_software_reset ();
977
+ break ;
978
+
979
+ case OutputReset_Bootloader :
980
+ // Clear schedule
981
+ Output_reset_schedule = OutputReset_None ;
982
+
983
+ // Jump to bootloader
984
+ usb_device_reload ();
985
+ break ;
986
+ }
987
+
939
988
// End latency measurement
940
989
Latency_end_time ( outputPeriodicLatencyResource );
941
990
}
@@ -1001,14 +1050,14 @@ void USB_NKRODebug( USBKeys *buffer )
1001
1050
// Sets the device into firmware reload mode
1002
1051
inline void USB_firmwareReload ()
1003
1052
{
1004
- usb_device_reload () ;
1053
+ Output_reset_schedule = OutputReset_Bootloader ;
1005
1054
}
1006
1055
1007
1056
1008
1057
// Soft Chip Reset
1009
1058
inline void USB_softReset ()
1010
1059
{
1011
- usb_device_software_reset () ;
1060
+ Output_reset_schedule = OutputReset_Restart ;
1012
1061
}
1013
1062
1014
1063
0 commit comments