From b57b2ae3c163a855efca331bf817d566e328f88b Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Thu, 20 Mar 2014 22:44:41 +0000 Subject: Fix race condition in USB CDC transmit If the Start of Frame interrupt triggers just after the call to USB_SendSpace in USB_Send then we can get data loss. When the first bank is full and the second partially full, the SOF handler will release the second bank via USB_Flush. Data is then lost due to overflow as USB_Send continues writing data to the now-closed bank. Fix this by re-checking the FIFO status inside LockEP, immediately before doing the data write. Signed-off-by: Paul Brook --- cores/arduino/USBCore.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'cores/arduino/USBCore.cpp') diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index d3e0170..76ceb01 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -290,9 +290,12 @@ int USB_Send(u8 ep, const void* d, int len) if (n > len) n = len; - len -= n; { LockEP lock(ep); + // Frame may have been released by the SOF interrupt handler + if (!ReadWriteAllowed()) + continue; + len -= n; if (ep & TRANSFER_ZERO) { while (n--) -- cgit v1.2.3-18-g5258 From 5962f155f70a5c67d14280d1b178f5197fb00df4 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Fri, 21 Mar 2014 18:43:19 +0000 Subject: Improve CDC read code Read CDC data from USB FIFO on demand instead of in ISR. Remove superfluous ring buffer. Signed-off-by: Paul Brook --- cores/arduino/USBCore.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'cores/arduino/USBCore.cpp') diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 76ceb01..f8123e5 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -614,8 +614,6 @@ ISR(USB_GEN_vect) { #ifdef CDC_ENABLED USB_Flush(CDC_TX); // Send a tx frame if found - if (USB_Available(CDC_RX)) // Handle received bytes (if any) - Serial.accept(); #endif // check whether the one-shot period has elapsed. if so, turn off the LED -- cgit v1.2.3-18-g5258