From 889332c3df80586a03a6aa3c29c1a0144ec13d59 Mon Sep 17 00:00:00 2001
From: Cristian Maglie <c.maglie@arduino.cc>
Date: Fri, 13 Mar 2015 13:23:10 +0100
Subject: [PATCH] Revert " Fixed incorrect CDC-USB buffer handling"

This reverts commit bc7115b104428f9bea4fdfa1b6af245085f6f542.
---
 cores/arduino/USB/CDC.cpp         | 33 ++++++++++---------------------
 cores/arduino/USB/USBCore.cpp     | 29 ++++++++++++---------------
 cores/arduino/USB/samd21_device.c | 24 +++++++++++++++++-----
 3 files changed, 42 insertions(+), 44 deletions(-)

diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp
index 139e96fe..33c7b7e8 100644
--- a/cores/arduino/USB/CDC.cpp
+++ b/cores/arduino/USB/CDC.cpp
@@ -34,7 +34,7 @@
 
 #ifdef CDC_ENABLED
 
-#define CDC_SERIAL_BUFFER_SIZE	512
+#define CDC_SERIAL_BUFFER_SIZE	64
 
 /* For information purpose only since RTS is not always handled by the terminal application */
 #define CDC_LINESTATE_DTR		0x01 // Data Terminal Ready
@@ -160,39 +160,26 @@ void Serial_::end(void)
 
 void Serial_::accept(void)
 {
-	volatile uint32_t len,k=0, size=0;
 	uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
+	uint32_t len = USBD_Recv(CDC_ENDPOINT_OUT, (void*)&buffer, CDC_SERIAL_BUFFER_SIZE);
 
+	noInterrupts();
 	ring_buffer *ringBuffer = &cdc_rx_buffer;
-	uint32_t i = (uint32_t)(ringBuffer->head+1) % CDC_SERIAL_BUFFER_SIZE;
-
-	size = 0;
-	do
-	{
-		len = USBD_Recv(CDC_ENDPOINT_OUT, (void*)&buffer+size, CDC_SERIAL_BUFFER_SIZE);
-		size += len;
-		if( size >= 512) break;
-	} while(len != 0 );
-
-	udd_clear_OUT_transf_cplt(CDC_ENDPOINT_OUT);
+	uint32_t i = ringBuffer->head;
 
 	// 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.
-	while (i != ringBuffer->tail) {
-		uint32_t c;
-		if (size == 0) {  // if (!USBD_Available(CDC_RX)) { udd_ack_fifocon(CDC_RX);
-			break;
-		}
-		size--;
-		c = buffer[k++];
-		// c = UDD_Recv8(CDC_RX & 0xF);
-		ringBuffer->buffer[ringBuffer->head] = c;
+	uint32_t k = 0;
+	i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
+	while (i != ringBuffer->tail && len>0) {
+		len--;
+		ringBuffer->buffer[ringBuffer->head] = buffer[k++];
 		ringBuffer->head = i;
-
 		i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
 	}
+	interrupts();
 }
 
 int Serial_::available(void)
diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp
index 6addf5db..8164f252 100644
--- a/cores/arduino/USB/USBCore.cpp
+++ b/cores/arduino/USB/USBCore.cpp
@@ -105,27 +105,24 @@ uint32_t USBD_Available(uint32_t ep)
 //	Return number of bytes read
 uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len)
 {
-	uint8_t *tmpbuffer;
-	uint8_t *data = (uint8_t *)d;
-
-	if (!_usbConfiguration || len < 0)
+	if (!_usbConfiguration)
 		return -1;
 
-	uint32_t n = UDD_FifoByteCount(ep);
-	
-// 	len = min(n,len);
-// 	n = len;
+	uint8_t *buffer;
+	uint8_t *data = (uint8_t *)d;
+
+	len = min(UDD_FifoByteCount(ep), len);
 
-	UDD_Recv_data(ep, n);
-	UDD_Recv(ep, &tmpbuffer);
-	for (int i=0; i<n; i++) {
-		data[i] = tmpbuffer[i];
+	UDD_Recv_data(ep, len);
+	UDD_Recv(ep, &buffer);
+	for (uint32_t i=0; i<len; i++) {
+		data[i] = buffer[i];
 	}
 
-// 	if (n && !UDD_FifoByteCount(ep)) // release empty buffer
-// 		UDD_ReleaseRX(ep);
+	if (len && !UDD_FifoByteCount(ep)) // release empty buffer
+		UDD_ReleaseRX(ep);
 
-	return n;
+	return len;
 }
 
 //	Recv 1 byte if ready
@@ -209,7 +206,7 @@ uint32_t USBD_RecvControl(void* d, uint32_t len)
 		read = len;
 	UDD_Recv(EP0, &buffer);
 	while (!udd_is_OUT_transf_cplt(EP0));
-	for (int i=0; i<read; i++) {
+	for (uint32_t i=0; i<read; i++) {
 		data[i] = buffer[i];
 	}
 	udd_OUT_transfer_allowed(EP0);
diff --git a/cores/arduino/USB/samd21_device.c b/cores/arduino/USB/samd21_device.c
index e73bf194..271243a3 100644
--- a/cores/arduino/USB/samd21_device.c
+++ b/cores/arduino/USB/samd21_device.c
@@ -25,11 +25,17 @@
 #include "USB/samd21_device.h"
 #include "sam.h"
 
+#ifdef __cplusplus
+extern "C"{
+#endif // __cplusplus
+
+#ifdef SAMD_SERIES
+
 //#define TRACE_DEVICE(x)	x
 #define TRACE_DEVICE(x)
 
-__attribute__((__aligned__(4)))   __attribute__((__section__(".bss_hram0"))) uint8_t udd_ep_out_cache_buffer[4][64];
-__attribute__((__aligned__(4)))   __attribute__((__section__(".bss_hram0"))) uint8_t udd_ep_in_cache_buffer[4][128];
+__attribute__((__aligned__(4))) /*__attribute__((__section__(".bss_hram0")))*/ uint8_t udd_ep_out_cache_buffer[4][64];
+__attribute__((__aligned__(4))) /*__attribute__((__section__(".bss_hram0")))*/ uint8_t udd_ep_in_cache_buffer[4][128];
 
 /**
  * USB SRAM data containing pipe descriptor table
@@ -264,6 +270,7 @@ uint8_t UDD_Recv_data(uint32_t ep, uint32_t len)
 {
 	TRACE_DEVICE(printf("=> UDD_Recvdata : ep=%d\r\n", (char)ep);)
 
+	if (len>64) len=64;
 	usb_endpoint_table[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[ep];
 	usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = len;
 	usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
@@ -273,7 +280,7 @@ uint8_t UDD_Recv_data(uint32_t ep, uint32_t len)
 	/* Wait for transfer to complete */
 	while (!udd_is_OUT_transf_cplt(ep));
 	/* Clear Transfer complete 0 flag */
-//	udd_clear_OUT_transf_cplt(ep);
+	udd_clear_OUT_transf_cplt(ep);
 
 	return udd_ep_out_cache_buffer[ep][0];
 }
@@ -302,7 +309,7 @@ void UDD_ReleaseRX(uint32_t ep)
 	// The RAM Buffer is empty: we can receive data
 	udd_OUT_transfer_allowed(ep);
 	/* Clear Transfer complete 0 flag */
-//	udd_clear_OUT_transf_cplt(ep);
+	udd_clear_OUT_transf_cplt(ep);
 }
 
 void UDD_ReleaseTX(uint32_t ep)
@@ -311,7 +318,7 @@ void UDD_ReleaseTX(uint32_t ep)
 	// The RAM Buffer is full: we can send data
     udd_IN_transfer_allowed(ep);
  	/* Clear the transfer complete flag  */
-   // udd_clear_IN_transf_cplt(ep);
+    udd_clear_IN_transf_cplt(ep);
 }
 
 void UDD_SetAddress(uint32_t addr)
@@ -335,3 +342,10 @@ uint32_t UDD_GetFrameNumber(void)
 {
 	return udd_frame_number();
 }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SAMD_SERIES */
+
-- 
GitLab