Skip to content

Commit 3e68807

Browse files
committed
Chibios: add more guards for transmitting (fix a deadlock bug).
1 parent d01d959 commit 3e68807

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

protocol/chibios/usb_main.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,9 @@ static void keyboard_idle_timer_cb(void *arg) {
10941094
if(keyboard_idle) {
10951095
#endif /* NKRO_ENABLE */
10961096
/* TODO: are we sure we want the KBD_ENDPOINT? */
1097-
usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent));
1097+
if(!usbGetTransmitStatusI(usbp, KBD_ENDPOINT)) {
1098+
usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, KBD_EPSIZE);
1099+
}
10981100
/* rearm the timer */
10991101
chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
11001102
}
@@ -1127,8 +1129,13 @@ void send_keyboard(report_keyboard_t *report) {
11271129
* this is more efficient */
11281130
/* busy wait, should be short and not very common */
11291131
osalSysLock();
1130-
while(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT))
1131-
;
1132+
if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) {
1133+
/* Need to either suspend, or loop and call unlock/lock during
1134+
* every iteration - otherwise the system will remain locked,
1135+
* no interrupts served, so USB not going through as well.
1136+
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
1137+
osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_ENDPOINT]->in_state->thread);
1138+
}
11321139
usbStartTransmitI(&USB_DRIVER, NKRO_ENDPOINT, (uint8_t *)report, sizeof(report_keyboard_t));
11331140
osalSysUnlock();
11341141
} else
@@ -1137,8 +1144,13 @@ void send_keyboard(report_keyboard_t *report) {
11371144
/* need to wait until the previous packet has made it through */
11381145
/* busy wait, should be short and not very common */
11391146
osalSysLock();
1140-
while(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT))
1141-
;
1147+
if(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) {
1148+
/* Need to either suspend, or loop and call unlock/lock during
1149+
* every iteration - otherwise the system will remain locked,
1150+
* no interrupts served, so USB not going through as well.
1151+
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
1152+
osalThreadSuspendS(&(&USB_DRIVER)->epc[KBD_ENDPOINT]->in_state->thread);
1153+
}
11421154
usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)report, KBD_EPSIZE);
11431155
osalSysUnlock();
11441156
}

0 commit comments

Comments
 (0)