@@ -63,11 +63,15 @@ extern bool keyboard_nkro;
63
63
#endif /* NKRO_ENABLE */
64
64
65
65
report_keyboard_t keyboard_report_sent = {{0 }};
66
+ report_keyboard_t * keyboard_report_not_yet_sent = NULL ;
66
67
#ifdef MOUSE_ENABLE
67
68
report_mouse_t mouse_report_blank = {0 };
69
+ report_mouse_t * mouse_report_not_yet_sent = NULL ;
68
70
#endif /* MOUSE_ENABLE */
69
71
#ifdef EXTRAKEY_ENABLE
70
72
uint8_t extra_report_blank [3 ] = {0 };
73
+ report_extra_t extra_report_not_yet_sent ;
74
+ bool extra_report_waiting = FALSE;
71
75
#endif /* EXTRAKEY_ENABLE */
72
76
73
77
#ifdef CONSOLE_ENABLE
@@ -1066,17 +1070,23 @@ void send_remote_wakeup(USBDriver *usbp) {
1066
1070
1067
1071
/* keyboard IN callback hander (a kbd report has made it IN) */
1068
1072
void kbd_in_cb (USBDriver * usbp , usbep_t ep ) {
1069
- /* STUB */
1070
- (void )usbp ;
1071
- (void )ep ;
1073
+ if (keyboard_report_not_yet_sent != NULL ) {
1074
+ osalSysLockFromISR ();
1075
+ usbStartTransmitI (usbp , ep , (uint8_t * )keyboard_report_not_yet_sent , KBD_EPSIZE );
1076
+ keyboard_report_not_yet_sent = NULL ;
1077
+ osalSysUnlockFromISR ();
1078
+ }
1072
1079
}
1073
1080
1074
1081
#ifdef NKRO_ENABLE
1075
1082
/* nkro IN callback hander (a nkro report has made it IN) */
1076
1083
void nkro_in_cb (USBDriver * usbp , usbep_t ep ) {
1077
- /* STUB */
1078
- (void )usbp ;
1079
- (void )ep ;
1084
+ if (keyboard_report_not_yet_sent != NULL ) {
1085
+ osalSysLockFromISR ();
1086
+ usbStartTransmitI (usbp , ep , (uint8_t * )keyboard_report_not_yet_sent , sizeof (report_keyboard_t ));
1087
+ keyboard_report_not_yet_sent = NULL ;
1088
+ osalSysUnlockFromISR ();
1089
+ }
1080
1090
}
1081
1091
#endif /* NKRO_ENABLE */
1082
1092
@@ -1132,41 +1142,30 @@ void send_keyboard(report_keyboard_t *report) {
1132
1142
osalSysUnlock ();
1133
1143
return ;
1134
1144
}
1135
- osalSysUnlock ();
1136
1145
1137
1146
#ifdef NKRO_ENABLE
1138
1147
if (keyboard_nkro ) { /* NKRO protocol */
1139
1148
/* need to wait until the previous packet has made it through */
1140
- /* can rewrite this using the synchronous API, then would wait
1141
- * until *after* the packet has been transmitted. I think
1142
- * this is more efficient */
1143
- /* busy wait, should be short and not very common */
1144
- osalSysLock ();
1149
+ /* save the pointer to the current report to send it later */
1145
1150
if (usbGetTransmitStatusI (& USB_DRIVER , NKRO_ENDPOINT )) {
1146
- /* Need to either suspend, or loop and call unlock/lock during
1147
- * every iteration - otherwise the system will remain locked,
1148
- * no interrupts served, so USB not going through as well.
1149
- * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
1150
- osalThreadSuspendS (& (& USB_DRIVER )-> epc [NKRO_ENDPOINT ]-> in_state -> thread );
1151
+ keyboard_report_not_yet_sent = report ;
1152
+ osalSysUnlock ();
1153
+ return ;
1151
1154
}
1152
1155
usbStartTransmitI (& USB_DRIVER , NKRO_ENDPOINT , (uint8_t * )report , sizeof (report_keyboard_t ));
1153
- osalSysUnlock ();
1154
1156
} else
1155
1157
#endif /* NKRO_ENABLE */
1156
1158
{ /* boot protocol */
1157
1159
/* need to wait until the previous packet has made it through */
1158
- /* busy wait, should be short and not very common */
1159
- osalSysLock ();
1160
+ /* save the pointer to the current report to send it later */
1160
1161
if (usbGetTransmitStatusI (& USB_DRIVER , KBD_ENDPOINT )) {
1161
- /* Need to either suspend, or loop and call unlock/lock during
1162
- * every iteration - otherwise the system will remain locked,
1163
- * no interrupts served, so USB not going through as well.
1164
- * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
1165
- osalThreadSuspendS (& (& USB_DRIVER )-> epc [KBD_ENDPOINT ]-> in_state -> thread );
1162
+ keyboard_report_not_yet_sent = report ;
1163
+ osalSysUnlock ();
1164
+ return ;
1166
1165
}
1167
1166
usbStartTransmitI (& USB_DRIVER , KBD_ENDPOINT , (uint8_t * )report , KBD_EPSIZE );
1168
- osalSysUnlock ();
1169
1167
}
1168
+ osalSysUnlock ();
1170
1169
keyboard_report_sent = * report ;
1171
1170
}
1172
1171
@@ -1179,8 +1178,12 @@ void send_keyboard(report_keyboard_t *report) {
1179
1178
1180
1179
/* mouse IN callback hander (a mouse report has made it IN) */
1181
1180
void mouse_in_cb (USBDriver * usbp , usbep_t ep ) {
1182
- (void )usbp ;
1183
- (void )ep ;
1181
+ if (mouse_report_not_yet_sent != NULL ) {
1182
+ osalSysLockFromISR ();
1183
+ usbStartTransmitI (usbp , ep , (uint8_t * )mouse_report_not_yet_sent , sizeof (report_mouse_t ));
1184
+ mouse_report_not_yet_sent = NULL ;
1185
+ osalSysUnlockFromISR ();
1186
+ }
1184
1187
}
1185
1188
1186
1189
void send_mouse (report_mouse_t * report ) {
@@ -1189,14 +1192,17 @@ void send_mouse(report_mouse_t *report) {
1189
1192
osalSysUnlock ();
1190
1193
return ;
1191
1194
}
1192
- osalSysUnlock ();
1193
1195
1194
1196
/* TODO: LUFA manually waits for the endpoint to become ready
1195
1197
* for about 10ms for mouse, kbd, system; 1ms for nkro
1196
1198
* is this really needed?
1197
1199
*/
1198
1200
1199
- osalSysLock ();
1201
+ if (usbGetTransmitStatusI (& USB_DRIVER , MOUSE_ENDPOINT )) {
1202
+ mouse_report_not_yet_sent = report ;
1203
+ osalSysUnlock ();
1204
+ return ;
1205
+ }
1200
1206
usbStartTransmitI (& USB_DRIVER , MOUSE_ENDPOINT , (uint8_t * )report , sizeof (report_mouse_t ));
1201
1207
osalSysUnlock ();
1202
1208
}
@@ -1216,9 +1222,12 @@ void send_mouse(report_mouse_t *report) {
1216
1222
1217
1223
/* extrakey IN callback hander */
1218
1224
void extra_in_cb (USBDriver * usbp , usbep_t ep ) {
1219
- /* STUB */
1220
- (void )usbp ;
1221
- (void )ep ;
1225
+ if (extra_report_waiting ) {
1226
+ osalSysLockFromISR ();
1227
+ usbStartTransmitI (usbp , ep , (uint8_t * )& extra_report_not_yet_sent , sizeof (report_extra_t ));
1228
+ extra_report_waiting = FALSE;
1229
+ osalSysUnlockFromISR ();
1230
+ }
1222
1231
}
1223
1232
1224
1233
static void send_extra_report (uint8_t report_id , uint16_t data ) {
@@ -1233,6 +1242,12 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
1233
1242
.usage = data
1234
1243
};
1235
1244
1245
+ if (usbGetTransmitStatusI (& USB_DRIVER , EXTRA_ENDPOINT )) {
1246
+ extra_report_not_yet_sent = report ;
1247
+ extra_report_waiting = TRUE;
1248
+ osalSysUnlock ();
1249
+ return ;
1250
+ }
1236
1251
usbStartTransmitI (& USB_DRIVER , EXTRA_ENDPOINT , (uint8_t * )& report , sizeof (report_extra_t ));
1237
1252
osalSysUnlock ();
1238
1253
}
0 commit comments