Skip to content

Commit b76dd01

Browse files
committed
Merge pull request arduino#1255 from cmaglie/usbcdc-loopback-fix
Fixed SerialUSB data handshake when host sends a lot of data (PeterVH, stimmer)
2 parents 531f1e0 + dbee03a commit b76dd01

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

cores/arduino/USB/CDC.cpp

+25-2
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,39 @@ void Serial_::end(void)
155155

156156
void Serial_::accept(void)
157157
{
158+
static uint32_t guard = 0;
159+
160+
// synchronized access to guard
161+
do {
162+
if (__LDREXW(&guard) != 0) {
163+
__CLREX();
164+
return; // busy
165+
}
166+
} while (__STREXW(1, &guard) != 0); // retry until write succeed
167+
158168
ring_buffer *buffer = &cdc_rx_buffer;
159-
uint32_t c = USBD_Recv(CDC_RX);
160169
uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE;
161170

162171
// if we should be storing the received character into the location
163172
// just before the tail (meaning that the head would advance to the
164173
// current location of the tail), we're about to overflow the buffer
165174
// and so we don't write the character or advance the head.
166-
if (i != buffer->tail) {
175+
while (i != buffer->tail) {
176+
uint32_t c;
177+
if (!USBD_Available(CDC_RX)) {
178+
udd_ack_fifocon(CDC_RX);
179+
break;
180+
}
181+
c = USBD_Recv(CDC_RX);
182+
// c = UDD_Recv8(CDC_RX & 0xF);
167183
buffer->buffer[buffer->head] = c;
168184
buffer->head = i;
185+
186+
i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
169187
}
188+
189+
// release the guard
190+
guard = 0;
170191
}
171192

172193
int Serial_::available(void)
@@ -202,6 +223,8 @@ int Serial_::read(void)
202223
{
203224
unsigned char c = buffer->buffer[buffer->tail];
204225
buffer->tail = (unsigned int)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
226+
if (USBD_Available(CDC_RX))
227+
accept();
205228
return c;
206229
}
207230
}

cores/arduino/USB/USBCore.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -601,10 +601,8 @@ static void USB_ISR(void)
601601
udd_ack_out_received(CDC_RX);
602602

603603
// Handle received bytes
604-
while (USBD_Available(CDC_RX))
604+
if (USBD_Available(CDC_RX))
605605
SerialUSB.accept();
606-
607-
udd_ack_fifocon(CDC_RX);
608606
}
609607

610608
if (Is_udd_sof())

0 commit comments

Comments
 (0)