Skip to content

Commit 3e413aa

Browse files
authored
Merge pull request #3058 from KentLee86/fix-cdc-null-rx-buffer
fix(cdc): stop arming OUT endpoint with a NULL buffer
2 parents 13c9d66 + 22f7dd4 commit 3e413aa

3 files changed

Lines changed: 9 additions & 24 deletions

File tree

‎libraries/USBDevice/inc/usbd_cdc.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,10 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
148148
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
149149
uint32_t length, uint8_t ClassId);
150150
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
151-
uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev, uint8_t ClassId);
152151
#else
153152
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
154153
uint32_t length);
155154
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
156-
uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
157155
#endif /* USE_USBD_COMPOSITE */
158156
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
159157
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);

‎libraries/USBDevice/src/cdc/usbd_cdc.c‎

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,24 +1029,6 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
10291029

10301030
return (uint8_t)USBD_OK;
10311031
}
1032-
#ifdef USE_USBD_COMPOSITE
1033-
uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev, uint8_t ClassId)
1034-
{
1035-
/* Suspend or Resume USB Out process */
1036-
if (pdev->pClassDataCmsit[classId] != NULL) {
1037-
#else
1038-
uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
1039-
{
1040-
/* Suspend or Resume USB Out process */
1041-
if (pdev->pClassDataCmsit[pdev->classId] != NULL) {
1042-
#endif /* USE_USBD_COMPOSITE */
1043-
/* Prepare Out endpoint to receive next packet */
1044-
USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
1045-
return (uint8_t)USBD_OK;
1046-
} else {
1047-
return (uint8_t)USBD_FAIL;
1048-
}
1049-
}
10501032

10511033
#endif /* USBD_USE_CDC */
10521034
#endif /* USBCON */

‎libraries/USBDevice/src/cdc/usbd_cdc_if.c‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,15 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)
240240
/* It always contains required amount of free space for writing */
241241
CDC_ReceiveQueue_CommitBlock(&ReceiveQueue, (uint16_t)(*Len));
242242
receivePended = false;
243-
/* If enough space in the queue for a full buffer then continue receive */
244-
if (!CDC_resume_receive()) {
245-
USBD_CDC_ClearBuffer(&hUSBD_Device_CDC);
246-
}
243+
/*
244+
* If there is enough space in the queue for a full packet, continue receive.
245+
* Else leave the OUT endpoint unarmed: it then NAKs and the host retries.
246+
* USBSerial::read() and the readBytes() family call CDC_resume_receive()
247+
* after dequeuing, so the endpoint is armed again with a valid block as soon
248+
* as the sketch drains data. Arming it with a NULL buffer instead makes the
249+
* low level driver copy the retried packet to address 0.
250+
*/
251+
(void)CDC_resume_receive();
247252
return ((int8_t)USBD_OK);
248253
}
249254

0 commit comments

Comments
 (0)