From d1813604258488b65973f4fb8e6c4c97af0ce82e Mon Sep 17 00:00:00 2001 From: Cristian Maglie <c.maglie@arduino.cc> Date: Fri, 6 Mar 2015 15:11:56 +0100 Subject: [PATCH] Fixed incorrect CDC-USB buffer handling --- cores/arduino/USB/CDC.cpp | 33 +++++++++++++++++++++---------- cores/arduino/USB/USBCore.cpp | 29 +++++++++++++++------------ cores/arduino/USB/samd21_device.c | 24 +++++----------------- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp index 33c7b7e8..139e96fe 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 64 +#define CDC_SERIAL_BUFFER_SIZE 512 /* For information purpose only since RTS is not always handled by the terminal application */ #define CDC_LINESTATE_DTR 0x01 // Data Terminal Ready @@ -160,26 +160,39 @@ 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 = ringBuffer->head; + 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); // 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. - uint32_t k = 0; - i = (i + 1) % CDC_SERIAL_BUFFER_SIZE; - while (i != ringBuffer->tail && len>0) { - len--; - ringBuffer->buffer[ringBuffer->head] = buffer[k++]; + 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; 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 8164f252..6addf5db 100644 --- a/cores/arduino/USB/USBCore.cpp +++ b/cores/arduino/USB/USBCore.cpp @@ -105,24 +105,27 @@ uint32_t USBD_Available(uint32_t ep) // Return number of bytes read uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len) { - if (!_usbConfiguration) - return -1; - - uint8_t *buffer; + uint8_t *tmpbuffer; uint8_t *data = (uint8_t *)d; - len = min(UDD_FifoByteCount(ep), len); + if (!_usbConfiguration || len < 0) + return -1; - UDD_Recv_data(ep, len); - UDD_Recv(ep, &buffer); - for (uint32_t i=0; i<len; i++) { - data[i] = buffer[i]; + uint32_t n = UDD_FifoByteCount(ep); + +// len = min(n,len); +// n = len; + + UDD_Recv_data(ep, n); + UDD_Recv(ep, &tmpbuffer); + for (int i=0; i<n; i++) { + data[i] = tmpbuffer[i]; } - if (len && !UDD_FifoByteCount(ep)) // release empty buffer - UDD_ReleaseRX(ep); +// if (n && !UDD_FifoByteCount(ep)) // release empty buffer +// UDD_ReleaseRX(ep); - return len; + return n; } // Recv 1 byte if ready @@ -206,7 +209,7 @@ uint32_t USBD_RecvControl(void* d, uint32_t len) read = len; UDD_Recv(EP0, &buffer); while (!udd_is_OUT_transf_cplt(EP0)); - for (uint32_t i=0; i<read; i++) { + for (int 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 271243a3..e73bf194 100644 --- a/cores/arduino/USB/samd21_device.c +++ b/cores/arduino/USB/samd21_device.c @@ -25,17 +25,11 @@ #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 @@ -270,7 +264,6 @@ 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; @@ -280,7 +273,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]; } @@ -309,7 +302,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) @@ -318,7 +311,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) @@ -342,10 +335,3 @@ uint32_t UDD_GetFrameNumber(void) { return udd_frame_number(); } - -#ifdef __cplusplus -} -#endif - -#endif /* SAMD_SERIES */ - -- GitLab