@@ -52,11 +52,12 @@ uint8_t extra_report_blank[3] = {0};
52
52
#endif /* EXTRAKEY_ENABLE */
53
53
54
54
#ifdef CONSOLE_ENABLE
55
- /* The emission queue */
56
- output_queue_t console_queue ;
57
- static uint8_t console_queue_buffer [CONSOLE_QUEUE_BUFFER_SIZE ];
55
+ /* The emission buffers queue */
56
+ output_buffers_queue_t console_buf_queue ;
57
+ static uint8_t console_queue_buffer [BQ_BUFFER_SIZE (CONSOLE_QUEUE_CAPACITY , CONSOLE_EPSIZE )];
58
+
58
59
static virtual_timer_t console_flush_timer ;
59
- void console_queue_onotify (io_queue_t * qp );
60
+ void console_queue_onotify (io_buffers_queue_t * bqp );
60
61
static void console_flush_cb (void * arg );
61
62
#endif /* CONSOLE_ENABLE */
62
63
@@ -1019,7 +1020,7 @@ void init_usb_driver(USBDriver *usbp) {
1019
1020
1020
1021
chVTObjectInit (& keyboard_idle_timer );
1021
1022
#ifdef CONSOLE_ENABLE
1022
- oqObjectInit ( & console_queue , console_queue_buffer , sizeof ( console_queue_buffer ), console_queue_onotify , (void * )usbp );
1023
+ obqObjectInit ( & console_buf_queue , console_queue_buffer , CONSOLE_EPSIZE , CONSOLE_QUEUE_CAPACITY , console_queue_onotify , (void * )usbp );
1023
1024
chVTObjectInit (& console_flush_timer );
1024
1025
#endif
1025
1026
}
@@ -1093,10 +1094,7 @@ static void keyboard_idle_timer_cb(void *arg) {
1093
1094
if (keyboard_idle ) {
1094
1095
#endif /* NKRO_ENABLE */
1095
1096
/* TODO: are we sure we want the KBD_ENDPOINT? */
1096
- osalSysUnlockFromISR ();
1097
- usbPrepareTransmit (usbp , KBD_ENDPOINT , (uint8_t * )& keyboard_report_sent , sizeof (keyboard_report_sent ));
1098
- osalSysLockFromISR ();
1099
- usbStartTransmitI (usbp , KBD_ENDPOINT );
1097
+ usbStartTransmitI (usbp , KBD_ENDPOINT , (uint8_t * )& keyboard_report_sent , sizeof (keyboard_report_sent ));
1100
1098
/* rearm the timer */
1101
1099
chVTSetI (& keyboard_idle_timer , 4 * MS2ST (keyboard_idle ), keyboard_idle_timer_cb , (void * )usbp );
1102
1100
}
@@ -1121,26 +1119,28 @@ void send_keyboard(report_keyboard_t *report) {
1121
1119
}
1122
1120
osalSysUnlock ();
1123
1121
1124
- bool ep_not_ready ;
1125
1122
#ifdef NKRO_ENABLE
1126
1123
if (keyboard_nkro ) { /* NKRO protocol */
1127
- usbPrepareTransmit (& USB_DRIVER , NKRO_ENDPOINT , (uint8_t * )report , sizeof (report_keyboard_t ));
1128
1124
/* need to wait until the previous packet has made it through */
1129
- do {
1130
- osalSysLock ();
1131
- ep_not_ready = usbStartTransmitI (& USB_DRIVER , NKRO_ENDPOINT );
1132
- osalSysUnlock ();
1133
- } while (ep_not_ready );
1125
+ /* can rewrite this using the synchronous API, then would wait
1126
+ * until *after* the packet has been transmitted. I think
1127
+ * this is more efficient */
1128
+ /* busy wait, should be short and not very common */
1129
+ osalSysLock ();
1130
+ while (usbGetTransmitStatusI (& USB_DRIVER , NKRO_ENDPOINT ))
1131
+ ;
1132
+ usbStartTransmitI (& USB_DRIVER , NKRO_ENDPOINT , (uint8_t * )report , sizeof (report_keyboard_t ));
1133
+ osalSysUnlock ();
1134
1134
} else
1135
1135
#endif /* NKRO_ENABLE */
1136
1136
{ /* boot protocol */
1137
- usbPrepareTransmit (& USB_DRIVER , KBD_ENDPOINT , (uint8_t * )report , KBD_EPSIZE );
1138
1137
/* need to wait until the previous packet has made it through */
1139
- do {
1140
- osalSysLock ();
1141
- ep_not_ready = usbStartTransmitI (& USB_DRIVER , KBD_ENDPOINT );
1142
- osalSysUnlock ();
1143
- } while (ep_not_ready );
1138
+ /* busy wait, should be short and not very common */
1139
+ osalSysLock ();
1140
+ while (usbGetTransmitStatusI (& USB_DRIVER , KBD_ENDPOINT ))
1141
+ ;
1142
+ usbStartTransmitI (& USB_DRIVER , KBD_ENDPOINT , (uint8_t * )report , KBD_EPSIZE );
1143
+ osalSysUnlock ();
1144
1144
}
1145
1145
keyboard_report_sent = * report ;
1146
1146
}
@@ -1171,9 +1171,8 @@ void send_mouse(report_mouse_t *report) {
1171
1171
* is this really needed?
1172
1172
*/
1173
1173
1174
- usbPrepareTransmit (& USB_DRIVER , MOUSE_ENDPOINT , (uint8_t * )report , sizeof (report_mouse_t ));
1175
1174
osalSysLock ();
1176
- usbStartTransmitI (& USB_DRIVER , MOUSE_ENDPOINT );
1175
+ usbStartTransmitI (& USB_DRIVER , MOUSE_ENDPOINT , ( uint8_t * ) report , sizeof ( report_mouse_t ) );
1177
1176
osalSysUnlock ();
1178
1177
}
1179
1178
@@ -1209,10 +1208,7 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
1209
1208
.usage = data
1210
1209
};
1211
1210
1212
- osalSysUnlock ();
1213
- usbPrepareTransmit (& USB_DRIVER , EXTRA_ENDPOINT , (uint8_t * )& report , sizeof (report_extra_t ));
1214
- osalSysLock ();
1215
- usbStartTransmitI (& USB_DRIVER , EXTRA_ENDPOINT );
1211
+ usbStartTransmitI (& USB_DRIVER , EXTRA_ENDPOINT , (uint8_t * )& report , sizeof (report_extra_t ));
1216
1212
osalSysUnlock ();
1217
1213
}
1218
1214
@@ -1240,48 +1236,62 @@ void send_consumer(uint16_t data) {
1240
1236
1241
1237
#ifdef CONSOLE_ENABLE
1242
1238
1243
- /* debug IN callback hander */
1239
+ /* console IN callback hander */
1244
1240
void console_in_cb (USBDriver * usbp , usbep_t ep ) {
1245
- (void )ep ;
1241
+ (void )ep ; /* should have ep == CONSOLE_ENDPOINT, so use that to save time/space */
1242
+ uint8_t * buf ;
1243
+ size_t n ;
1244
+
1246
1245
osalSysLockFromISR ();
1247
1246
1248
1247
/* rearm the timer */
1249
1248
chVTSetI (& console_flush_timer , MS2ST (CONSOLE_FLUSH_MS ), console_flush_cb , (void * )usbp );
1250
1249
1251
- /* Check if there is data to send left in the output queue */
1252
- if (chOQGetFullI (& console_queue ) >= CONSOLE_EPSIZE ) {
1253
- osalSysUnlockFromISR ();
1254
- usbPrepareQueuedTransmit (usbp , CONSOLE_ENDPOINT , & console_queue , CONSOLE_EPSIZE );
1255
- osalSysLockFromISR ();
1256
- usbStartTransmitI (usbp , CONSOLE_ENDPOINT );
1250
+ /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
1251
+ if (usbp -> epc [CONSOLE_ENDPOINT ]-> in_state -> txsize > 0U ) {
1252
+ obqReleaseEmptyBufferI (& console_buf_queue );
1253
+ }
1254
+
1255
+ /* Checking if there is a buffer ready for transmission.*/
1256
+ buf = obqGetFullBufferI (& console_buf_queue , & n );
1257
+
1258
+ if (buf != NULL ) {
1259
+ /* The endpoint cannot be busy, we are in the context of the callback,
1260
+ so it is safe to transmit without a check.*/
1261
+ /* Should have n == CONSOLE_EPSIZE; check it? */
1262
+ usbStartTransmitI (usbp , CONSOLE_ENDPOINT , buf , CONSOLE_EPSIZE );
1263
+ } else {
1264
+ /* Nothing to transmit.*/
1257
1265
}
1258
1266
1259
1267
osalSysUnlockFromISR ();
1260
1268
}
1261
1269
1262
1270
/* Callback when data is inserted into the output queue
1263
1271
* Called from a locked state */
1264
- void console_queue_onotify (io_queue_t * qp ) {
1265
- USBDriver * usbp = qGetLink (qp );
1272
+ void console_queue_onotify (io_buffers_queue_t * bqp ) {
1273
+ size_t n ;
1274
+ USBDriver * usbp = bqGetLinkX (bqp );
1266
1275
1267
1276
if (usbGetDriverStateI (usbp ) != USB_ACTIVE )
1268
1277
return ;
1269
1278
1270
- if (!usbGetTransmitStatusI (usbp , CONSOLE_ENDPOINT )
1271
- && (chOQGetFullI (& console_queue ) >= CONSOLE_EPSIZE )) {
1272
- osalSysUnlock ();
1273
- usbPrepareQueuedTransmit (usbp , CONSOLE_ENDPOINT , & console_queue , CONSOLE_EPSIZE );
1274
- osalSysLock ();
1275
- usbStartTransmitI (usbp , CONSOLE_ENDPOINT );
1279
+ /* Checking if there is already a transaction ongoing on the endpoint.*/
1280
+ if (!usbGetTransmitStatusI (usbp , CONSOLE_ENDPOINT )) {
1281
+ /* Trying to get a full buffer.*/
1282
+ uint8_t * buf = obqGetFullBufferI (& console_buf_queue , & n );
1283
+ if (buf != NULL ) {
1284
+ /* Buffer found, starting a new transaction.*/
1285
+ /* Should have n == CONSOLE_EPSIZE; check this? */
1286
+ usbStartTransmitI (usbp , CONSOLE_ENDPOINT , buf , CONSOLE_EPSIZE );
1287
+ }
1276
1288
}
1277
1289
}
1278
1290
1279
1291
/* Flush timer code
1280
1292
* callback (called from ISR, unlocked state) */
1281
1293
static void console_flush_cb (void * arg ) {
1282
1294
USBDriver * usbp = (USBDriver * )arg ;
1283
- size_t i , n ;
1284
- uint8_t buf [CONSOLE_EPSIZE ]; /* TODO: a solution without extra buffer? */
1285
1295
osalSysLockFromISR ();
1286
1296
1287
1297
/* check that the states of things are as they're supposed to */
@@ -1292,23 +1302,28 @@ static void console_flush_cb(void *arg) {
1292
1302
return ;
1293
1303
}
1294
1304
1295
- /* don't do anything if the queue is empty or has enough stuff in it */
1296
- if (((n = oqGetFullI (& console_queue )) == 0 ) || (n >= CONSOLE_EPSIZE )) {
1305
+ /* If there is already a transaction ongoing then another one cannot be
1306
+ started.*/
1307
+ if (usbGetTransmitStatusI (usbp , CONSOLE_ENDPOINT )) {
1297
1308
/* rearm the timer */
1298
1309
chVTSetI (& console_flush_timer , MS2ST (CONSOLE_FLUSH_MS ), console_flush_cb , (void * )usbp );
1299
1310
osalSysUnlockFromISR ();
1300
1311
return ;
1301
1312
}
1302
1313
1303
- /* there's stuff hanging in the queue - so dequeue and send */
1304
- for (i = 0 ; i < n ; i ++ )
1305
- buf [i ] = (uint8_t )oqGetI (& console_queue );
1306
- for (i = n ; i < CONSOLE_EPSIZE ; i ++ )
1307
- buf [i ] = 0 ;
1308
- osalSysUnlockFromISR ();
1309
- usbPrepareTransmit (usbp , CONSOLE_ENDPOINT , buf , CONSOLE_EPSIZE );
1310
- osalSysLockFromISR ();
1311
- (void )usbStartTransmitI (usbp , CONSOLE_ENDPOINT );
1314
+ /* Checking if there only a buffer partially filled, if so then it is
1315
+ enforced in the queue and transmitted.*/
1316
+ if (obqTryFlushI (& console_buf_queue )) {
1317
+ size_t n ,i ;
1318
+ uint8_t * buf = obqGetFullBufferI (& console_buf_queue , & n );
1319
+
1320
+ osalDbgAssert (buf != NULL , "queue is empty" );
1321
+
1322
+ /* zero the rest of the buffer (buf should point to allocated space) */
1323
+ for (i = n ; i < CONSOLE_EPSIZE ; i ++ )
1324
+ buf [i ]= 0 ;
1325
+ usbStartTransmitI (usbp , CONSOLE_ENDPOINT , buf , CONSOLE_EPSIZE );
1326
+ }
1312
1327
1313
1328
/* rearm the timer */
1314
1329
chVTSetI (& console_flush_timer , MS2ST (CONSOLE_FLUSH_MS ), console_flush_cb , (void * )usbp );
@@ -1329,7 +1344,7 @@ int8_t sendchar(uint8_t c) {
1329
1344
* for USB/HIDRAW to dequeue). Another possibility
1330
1345
* for fixing this kind of thing is to increase
1331
1346
* CONSOLE_QUEUE_CAPACITY. */
1332
- return (chOQPutTimeout ( & console_queue , c , US2ST (5 )));
1347
+ return (obqPutTimeout ( & console_buf_queue , c , US2ST (100 )));
1333
1348
}
1334
1349
1335
1350
#else /* CONSOLE_ENABLE */
0 commit comments