Skip to content

Commit 3677a99

Browse files
committed
Delaying jump to bootloader and restart firmware when using USB module
- Delaying reset until a USB packet can be sent that clears all OS state the keyboard may have created - This prevents keys on Windows from being held down while in flash mode as Windows maintains keypresses if holding down while unplugging a keyboard
1 parent 85b0ed5 commit 3677a99

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

Diff for: Output/USB/output_usb.c

+59-10
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@
6666

6767

6868

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+
6979
// ----- Function Declarations -----
7080

7181
void cliFunc_idle ( char* args );
@@ -147,6 +157,11 @@ volatile uint16_t USBInit_Ticks;
147157
// USB Address - Set by host, unique to the bus
148158
volatile uint8_t USBDev_Address;
149159

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+
150165
// Latency measurement resource
151166
static uint8_t outputPeriodicLatencyResource;
152167
static uint8_t outputPollLatencyResource;
@@ -710,6 +725,14 @@ void USB_flushBuffers()
710725

711726
// Reset USBKeys_Keys size
712727
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;
713736
}
714737

715738

@@ -732,17 +755,12 @@ inline void USB_setup()
732755
USBKeys_LEDs_prev = 0;
733756
USBKeys_LEDs = 0;
734757

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-
743758
// Clear USB address
744759
USBDev_Address = 0;
745760

761+
// Clear USB reset state
762+
Output_reset_schedule = OutputReset_None;
763+
746764
// Flush key buffers
747765
USB_flushBuffers();
748766

@@ -885,10 +903,21 @@ inline void USB_periodic()
885903
// Start latency measurement
886904
Latency_start_time( outputPeriodicLatencyResource );
887905

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+
888915
#if enableMouse_define == 1
889916
// Process mouse actions
890917
while ( USBMouse_Changed )
918+
{
891919
usb_mouse_send();
920+
}
892921
#endif
893922

894923
#if enableKeyboard_define == 1
@@ -936,6 +965,26 @@ inline void USB_periodic()
936965
USB_suspend_status_update();
937966
#endif
938967

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+
939988
// End latency measurement
940989
Latency_end_time( outputPeriodicLatencyResource );
941990
}
@@ -1001,14 +1050,14 @@ void USB_NKRODebug( USBKeys *buffer )
10011050
// Sets the device into firmware reload mode
10021051
inline void USB_firmwareReload()
10031052
{
1004-
usb_device_reload();
1053+
Output_reset_schedule = OutputReset_Bootloader;
10051054
}
10061055

10071056

10081057
// Soft Chip Reset
10091058
inline void USB_softReset()
10101059
{
1011-
usb_device_software_reset();
1060+
Output_reset_schedule = OutputReset_Restart;
10121061
}
10131062

10141063

0 commit comments

Comments
 (0)