Skip to content

Commit

Permalink
Merge pull request #1255 from cmaglie/usbcdc-loopback-fix
Browse files Browse the repository at this point in the history
Fixed SerialUSB data handshake when host sends a lot of data (PeterVH, stimmer)
  • Loading branch information
cmaglie committed Feb 6, 2013
2 parents e903a6d + d66d4c4 commit 6b25f0c
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
5 changes: 3 additions & 2 deletions build/shared/revisions.txt
Expand Up @@ -23,8 +23,9 @@ ARDUINO 1.5.2 BETA - 2012.01.23
* sam: fixed BSoD on some Windows machine (louismdavis)
* sam: added CANRX1/CANTX1 pins 88/89 (same physical pin for 66/53)
* sam: fixed analogWrite when used in very thight write loops (V.Dorrich)
* sam: fixed USBSerial.write() while sending big buffers (Bill Dreschel)
* sam: USBSerial receive buffer size is now 512 (PeterVH)
* sam: fixed SerialUSB.write() while sending big buffers (Bill Dreschel)
* sam: SerialUSB receive buffer size is now 512 (PeterVH)
* sam: Fixed SerialUSB data handshake when host sends a lot of data (PeterVH, stimmer)

[libraries]
* sam: Added Servo library
Expand Down
27 changes: 25 additions & 2 deletions hardware/arduino/sam/cores/arduino/USB/CDC.cpp
Expand Up @@ -155,18 +155,39 @@ void Serial_::end(void)

void Serial_::accept(void)
{
static uint32_t guard = 0;

// synchronized access to guard
do {
if (__LDREXW(&guard) != 0) {
__CLREX();
return; // busy
}
} while (__STREXW(1, &guard) != 0); // retry until write succeed

ring_buffer *buffer = &cdc_rx_buffer;
uint32_t c = USBD_Recv(CDC_RX);
uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE;

// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
while (i != buffer->tail) {
uint32_t c;
if (!USBD_Available(CDC_RX)) {
udd_ack_fifocon(CDC_RX);
break;
}
c = USBD_Recv(CDC_RX);
// c = UDD_Recv8(CDC_RX & 0xF);
buffer->buffer[buffer->head] = c;
buffer->head = i;

i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
}

// release the guard
guard = 0;
}

int Serial_::available(void)
Expand Down Expand Up @@ -202,6 +223,8 @@ int Serial_::read(void)
{
unsigned char c = buffer->buffer[buffer->tail];
buffer->tail = (unsigned int)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
if (USBD_Available(CDC_RX))
accept();
return c;
}
}
Expand Down
4 changes: 1 addition & 3 deletions hardware/arduino/sam/cores/arduino/USB/USBCore.cpp
Expand Up @@ -601,10 +601,8 @@ static void USB_ISR(void)
udd_ack_out_received(CDC_RX);

// Handle received bytes
while (USBD_Available(CDC_RX))
if (USBD_Available(CDC_RX))
SerialUSB.accept();

udd_ack_fifocon(CDC_RX);
}

if (Is_udd_sof())
Expand Down

0 comments on commit 6b25f0c

Please sign in to comment.