Skip to content

Commit 4e861b4

Browse files
authored
Merge pull request #444 from ghent360/cdc
USBSerial would not block on write if the USB inteface is not connected
2 parents c7dffcd + eea20ce commit 4e861b4

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

Diff for: cores/arduino/USBSerial.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ size_t USBSerial::write(uint8_t ch)
6666
size_t USBSerial::write(const uint8_t *buffer, size_t size)
6767
{
6868
size_t rest = size;
69-
while (rest > 0) {
69+
while (rest > 0 && CDC_connected()) {
7070
// Determine buffer size available for write
7171
auto portion = (size_t)CDC_TransmitQueue_WriteSize(&TransmitQueue);
7272
// Truncate it to content size (if rest is greater)
@@ -85,7 +85,7 @@ size_t USBSerial::write(const uint8_t *buffer, size_t size)
8585
CDC_continue_transmit();
8686
}
8787
}
88-
return size;
88+
return size - rest;
8989
}
9090

9191
int USBSerial::available(void)

Diff for: cores/arduino/stm32/usb/cdc/usbd_cdc_if.c

+26
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@
3232
#define CDC_MAX_PACKET_SIZE USB_MAX_EP0_SIZE
3333
#endif
3434

35+
/*
36+
* The value USB_CDC_TRANSMIT_TIMEOUT is defined in terms of HAL_GetTick() units.
37+
* Typically it is 1ms value. The timeout determines when we would consider the
38+
* host "too slow" and threat the USB CDC port as disconnected.
39+
*/
40+
#ifndef USB_CDC_TRANSMIT_TIMEOUT
41+
#define USB_CDC_TRANSMIT_TIMEOUT 3
42+
#endif
43+
3544
/* USBD_CDC Private Variables */
3645
/* USB Device Core CDC handle declaration */
3746
USBD_HandleTypeDef hUSBD_Device_CDC;
@@ -43,6 +52,7 @@ CDC_TransmitQueue_TypeDef TransmitQueue;
4352
CDC_ReceiveQueue_TypeDef ReceiveQueue;
4453
__IO uint32_t lineState = 0;
4554
__IO bool receivePended = true;
55+
static uint32_t transmitStart = 0;
4656

4757

4858
/** USBD_CDC Private Function Prototypes */
@@ -169,6 +179,9 @@ static int8_t USBD_CDC_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
169179
case CDC_SET_CONTROL_LINE_STATE:
170180
lineState =
171181
(((USBD_SetupReqTypedef *)pbuf)->wValue & 0x01) != 0; // Check DTR state
182+
if (lineState) { // Reset the transmit timeout when the port is connected
183+
transmitStart = 0;
184+
}
172185
break;
173186

174187
case CDC_SEND_BREAK:
@@ -214,6 +227,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)
214227

215228
static int8_t USBD_CDC_Transferred(void)
216229
{
230+
transmitStart = 0;
217231
CDC_TransmitQueue_CommitRead(&TransmitQueue);
218232
CDC_continue_transmit();
219233
return (USBD_OK);
@@ -247,6 +261,17 @@ void CDC_deInit(void)
247261
}
248262
}
249263

264+
bool CDC_connected()
265+
{
266+
uint32_t transmitTime = 0;
267+
if (transmitStart) {
268+
transmitTime = HAL_GetTick() - transmitStart;
269+
}
270+
return hUSBD_Device_CDC.dev_state == USBD_STATE_CONFIGURED
271+
&& transmitTime < USB_CDC_TRANSMIT_TIMEOUT
272+
&& lineState;
273+
}
274+
250275
void CDC_continue_transmit(void)
251276
{
252277
uint16_t size;
@@ -263,6 +288,7 @@ void CDC_continue_transmit(void)
263288
if (hcdc->TxState == 0U) {
264289
buffer = CDC_TransmitQueue_ReadBlock(&TransmitQueue, &size);
265290
if (size > 0) {
291+
transmitStart = HAL_GetTick();
266292
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, buffer, size);
267293
/*
268294
* size never exceed PMA buffer and USBD_CDC_TransmitPacket make full

Diff for: cores/arduino/stm32/usb/cdc/usbd_cdc_if.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ void CDC_continue_transmit(void);
5050
bool CDC_resume_receive(void);
5151
void CDC_init(void);
5252
void CDC_deInit(void);
53+
bool CDC_connected();
5354

5455
#ifdef __cplusplus
5556
}

0 commit comments

Comments
 (0)