@@ -315,29 +315,117 @@ uint8_t* EPBuffer<L>::ptr()
315
315
template <size_t L>
316
316
bool EPBuffer<L>::waitForWriteComplete()
317
317
{
318
- // auto start = getCurrentMillis();
319
318
auto ok = true ;
319
+ auto desc = *EPBuffers ().desc (this ->ep );
320
+ auto udev = &USBCore ().usbDev ();
321
+
322
+ /*
323
+ * For interrupt EPs, count from now instead of from previous send.
324
+ * Otherwise, if a send occurs while the bus is suspended, the packet will
325
+ * be cheated of its full timeout.
326
+ */
327
+ if (desc.type () == USB_EP_ATTR_INT) {
328
+ this ->startTime = millis ();
329
+ }
320
330
do {
321
331
usb_enable_interrupts ();
322
- if (this ->txWaiting && millis () - this ->startTime > this ->timeout ) {
323
- ok = false ;
324
- this ->timedOut = true ;
325
- USBCore ().logEP (' X' , this ->ep , ' >' , this ->len ());
326
- break ;
327
- }
328
- switch (USBCore ().usbDev ().cur_status ) {
332
+ switch (udev->cur_status ) {
329
333
case USBD_DEFAULT:
330
334
case USBD_ADDRESSED:
331
335
ok = false ;
332
336
break ;
333
337
default :
334
338
break ;
335
339
}
336
- // if (getCurrentMillis() - start > 5) {
337
- // EPBuffers().buf(ep).transcIn();
338
- // ok = false;
339
- // }
340
340
usb_disable_interrupts ();
341
+ if (this ->txWaiting && millis () - this ->startTime > this ->timeout ) {
342
+ USBCore ().logEP (' X' , this ->ep , ' >' , this ->len ());
343
+ /*
344
+ * For interrupt EPs, overwrite the previous packet. In the common
345
+ * case of a key press HID report initiating a remote wakeup,
346
+ * transmission of the key release event might be delayed, because
347
+ * the host can't poll while the bus is suspended. If the
348
+ * application sends a key release event before the key press event
349
+ * is transmitted, that might time out. If the key release event is
350
+ * discarded due to the timeout, the host will never receive the
351
+ * key release event, leading to a stuck or repeating key.
352
+ */
353
+ if (desc.type () == USB_EP_ATTR_INT) {
354
+ /*
355
+ * Set the endpoint status to NAK, in an attempt to prevent
356
+ * the queued packet from being transmitted while being
357
+ * overwritten.
358
+ *
359
+ * This must be done in two steps. Unfortunately, the USBD
360
+ * peripheral's design doesn't seem to make it possible to
361
+ * atomically abort a queued transmission. Even if interrupts
362
+ * are disabled, the peripheral state machine continues to run.
363
+ *
364
+ * The endpoint status control bits are toggle-only (toggle on
365
+ * writing 1; unchanged on writing 0). If the TX state
366
+ * transitions from VALID to NAK during the read-modify-write,
367
+ * a toggle operation (XOR 0b01) intended to transition from
368
+ * VALID (0b11) to NAK (0b10) will set the status back to
369
+ * VALID. This will cause the previous packet to be sent again.
370
+ *
371
+ * Instead, set the status to DISABLED (0b00, via XOR 0b11),
372
+ * which will become STALL (0b01) if the peripheral transitions
373
+ * the status to NAK between the read and the write. This can
374
+ * happen if the transmission was in progress and the host ACKs
375
+ * exactly between the read and the write to update the status
376
+ * bits.
377
+ *
378
+ * Possible states after the first USBD_EP_TX_STAT_SET:
379
+ *
380
+ * - DISABLED (metastable if TX in progress)
381
+ * - STALL (stable; only possible if we lost the r-m-w race)
382
+ * - NAK (stable; only possible if TX completed after toggle)
383
+ *
384
+ * There is a small theoretical chance that the host will poll
385
+ * the endpoint again between the two updates to the status
386
+ * bits, which could lead to the host receiving a STALL
387
+ * handshake, which would put the data toggle bit out of sync.
388
+ *
389
+ * The second host poll cannot complete sooner than 34 bit times
390
+ * after the ACK from the first host poll. (2 bits inter-packet
391
+ * delay, 8 bits sync, 8 bits PID, 16 bits addr/endpoint/CRC,
392
+ * about 2.83 microseconds) The second status bit update will
393
+ * complete before then, assuming reasonable CPU clock speeds
394
+ * and no lengthy interrupt handler executions occurring.
395
+ *
396
+ * On the other hand, it's unknown when exactly the peripheral
397
+ * checks the endpoint status bits to decide which response to
398
+ * send to an IN poll. It might latch them at EOP, or SOP, or
399
+ * maybe PID, or it might wait until after checking the CRC. So
400
+ * the actual available time might be between 0 and 34 bit
401
+ * times.
402
+ *
403
+ * We could globally disable interrupts to mitigate that, if
404
+ * necessary.
405
+ */
406
+ USBD_EP_TX_STAT_SET (this ->ep , EPTX_DISABLED);
407
+ if (USBD_EPxCS (this ->ep ) & EPxCS_TX_STA == EPTX_DISABLED) {
408
+ /*
409
+ * If the endpoint is disabled, there might still be a
410
+ * transmission in progress. Wait for it to complete:
411
+ *
412
+ * 1 byte sync + 1 byte PID + 64 bytes data + 2 bytes CRC,
413
+ * 1 turn-around time,
414
+ * 1 byte sync + 1 byte PID (handshake)
415
+ * assuming maximum bit stuffing at full speed (12MHz).
416
+ */
417
+ delayMicroseconds (56 );
418
+ }
419
+ // In case TX was in progress and completed
420
+ USBD_EP_TX_ST_CLEAR (this ->ep );
421
+ USBD_EP_TX_STAT_SET (this ->ep , EPTX_NAK);
422
+ break ;
423
+ } else {
424
+ ok = false ;
425
+ this ->timedOut = true ;
426
+ break ;
427
+ }
428
+ }
341
429
} while (ok && this ->txWaiting );
342
430
return ok;
343
431
}
0 commit comments