Skip to content

USBSerial would not block on write if the USB inteface is not connected #444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cores/arduino/USBSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ size_t USBSerial::write(uint8_t ch)
size_t USBSerial::write(const uint8_t *buffer, size_t size)
{
size_t rest = size;
while (rest > 0) {
while (rest > 0 && CDC_connected()) {
// Determine buffer size available for write
auto portion = (size_t)CDC_TransmitQueue_WriteSize(&TransmitQueue);
// Truncate it to content size (if rest is greater)
Expand All @@ -85,7 +85,7 @@ size_t USBSerial::write(const uint8_t *buffer, size_t size)
CDC_continue_transmit();
}
}
return size;
return size - rest;
}

int USBSerial::available(void)
Expand Down
26 changes: 26 additions & 0 deletions cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
#define CDC_MAX_PACKET_SIZE USB_MAX_EP0_SIZE
#endif

/*
* The value USB_CDC_TRANSMIT_TIMEOUT is defined in terms of HAL_GetTick() units.
* Typically it is 1ms value. The timeout determines when we would consider the
* host "too slow" and threat the USB CDC port as disconnected.
*/
#ifndef USB_CDC_TRANSMIT_TIMEOUT
#define USB_CDC_TRANSMIT_TIMEOUT 3
#endif

/* USBD_CDC Private Variables */
/* USB Device Core CDC handle declaration */
USBD_HandleTypeDef hUSBD_Device_CDC;
Expand All @@ -43,6 +52,7 @@ CDC_TransmitQueue_TypeDef TransmitQueue;
CDC_ReceiveQueue_TypeDef ReceiveQueue;
__IO uint32_t lineState = 0;
__IO bool receivePended = true;
static uint32_t transmitStart = 0;


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

case CDC_SEND_BREAK:
Expand Down Expand Up @@ -212,6 +225,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)

static int8_t USBD_CDC_Transferred(void)
{
transmitStart = 0;
CDC_TransmitQueue_CommitRead(&TransmitQueue);
CDC_continue_transmit();
return (USBD_OK);
Expand Down Expand Up @@ -245,6 +259,17 @@ void CDC_deInit(void)
}
}

bool CDC_connected()
{
uint32_t transmitTime = 0;
if (transmitStart) {
transmitTime = HAL_GetTick() - transmitStart;
}
return hUSBD_Device_CDC.dev_state == USBD_STATE_CONFIGURED
&& transmitTime < USB_CDC_TRANSMIT_TIMEOUT
&& lineState;
}

void CDC_continue_transmit(void)
{
uint16_t size;
Expand All @@ -261,6 +286,7 @@ void CDC_continue_transmit(void)
if (hcdc->TxState == 0U) {
buffer = CDC_TransmitQueue_ReadBlock(&TransmitQueue, &size);
if (size > 0) {
transmitStart = HAL_GetTick();
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, buffer, size);
/*
* size never exceed PMA buffer and USBD_CDC_TransmitPacket make full
Expand Down
1 change: 1 addition & 0 deletions cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void CDC_continue_transmit(void);
void CDC_resume_receive(void);
void CDC_init(void);
void CDC_deInit(void);
bool CDC_connected();

#ifdef __cplusplus
}
Expand Down