From 7d37753904a09d0d85ecf6dde960b6eed0d444f9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie <c.maglie@arduino.cc> Date: Tue, 28 Jun 2016 15:57:06 +0200 Subject: [PATCH] USB-CDC: OUT EP is now handled with a custom EPHandler --- cores/arduino/USB/CDC.cpp | 85 +++++------------------------------ cores/arduino/USB/USBAPI.h | 2 - cores/arduino/USB/USBCore.cpp | 25 +---------- 3 files changed, 13 insertions(+), 99 deletions(-) diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp index e6fc4a5b..9388652b 100644 --- a/cores/arduino/USB/CDC.cpp +++ b/cores/arduino/USB/CDC.cpp @@ -33,14 +33,6 @@ #define CDC_LINESTATE_READY (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR) -struct ring_buffer { - uint8_t buffer[CDC_SERIAL_BUFFER_SIZE]; - volatile uint32_t head; - volatile uint32_t tail; - volatile bool full; -}; -ring_buffer cdc_rx_buffer = {{0}, 0, 0, false}; - typedef struct { uint32_t dwDTERate; uint8_t bCharFormat; @@ -146,7 +138,6 @@ bool CDC_Setup(USBSetup& setup) return false; } -uint32_t _serialPeek = -1; void Serial_::begin(uint32_t /* baud_count */) { // uart config is ignored in USB-CDC @@ -161,31 +152,9 @@ void Serial_::end(void) { } -void Serial_::accept(uint8_t *data, uint32_t size) -{ - ring_buffer *ringBuffer = &cdc_rx_buffer; - uint32_t i = ringBuffer->head; - while (size--) { - ringBuffer->buffer[i++] = *data; - data++; - i %= CDC_SERIAL_BUFFER_SIZE; - } - ringBuffer->head = i; - if (i == ringBuffer->tail) ringBuffer->full = true; - if (availableForStore() < EPX_SIZE) { - stalled = true; - } else { - usb.epOut(CDC_ENDPOINT_OUT); - } -} - int Serial_::available(void) { - ring_buffer *buffer = &cdc_rx_buffer; - if (buffer->full) { - return CDC_SERIAL_BUFFER_SIZE; - } - return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE; + return usb.available(CDC_ENDPOINT_OUT); } int Serial_::availableForWrite(void) @@ -195,43 +164,24 @@ int Serial_::availableForWrite(void) return (EPX_SIZE - 1); } +int _serialPeek = -1; + int Serial_::peek(void) { - ring_buffer *buffer = &cdc_rx_buffer; - if (buffer->head == buffer->tail && !buffer->full) { - return -1; - } else { - return buffer->buffer[buffer->tail]; - } + if (_serialPeek != -1) + return _serialPeek; + _serialPeek = read(); + return _serialPeek; } - -// if the ringBuffer is empty: try to fill it -// if it's still empty: return -1 -// else return the last char -// so the buffer is filled only when needed int Serial_::read(void) { - ring_buffer *buffer = &cdc_rx_buffer; - - uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0); - __disable_irq(); - - // if we have enough space enable OUT endpoint to receive more data - if (stalled && availableForStore() >= EPX_SIZE) - { - stalled = false; - usb.epOut(CDC_ENDPOINT_OUT); + if (_serialPeek != -1) { + int res = _serialPeek; + _serialPeek = -1; + return res; } - int c = -1; - if (buffer->head != buffer->tail || buffer->full) - { - c = buffer->buffer[buffer->tail]; - buffer->tail = (uint32_t)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE; - buffer->full = false; - } - if (enableInterrupts) __enable_irq(); - return c; + return usb.recv(CDC_ENDPOINT_OUT); } void Serial_::flush(void) @@ -337,17 +287,6 @@ bool Serial_::rts() { return _usbLineInfo.lineState & 0x2; } -int Serial_::availableForStore(void) { - ring_buffer *buffer = &cdc_rx_buffer; - - if (buffer->full) - return 0; - else if (buffer->head >= buffer->tail) - return CDC_SERIAL_BUFFER_SIZE - 1 - buffer->head + buffer->tail; - else - return buffer->tail - buffer->head - 1; -} - Serial_ SerialUSB(USBDevice); #endif diff --git a/cores/arduino/USB/USBAPI.h b/cores/arduino/USB/USBAPI.h index 1591948c..5cc0ba12 100644 --- a/cores/arduino/USB/USBAPI.h +++ b/cores/arduino/USB/USBAPI.h @@ -92,7 +92,6 @@ public: uint32_t available(uint32_t ep); void flush(uint32_t ep); void stall(uint32_t ep); - void epOut(uint32_t ep); // private? uint32_t armSend(uint32_t ep, const void *data, uint32_t len); @@ -120,7 +119,6 @@ public: virtual int available(void); virtual int availableForWrite(void); - virtual void accept(uint8_t *data, uint32_t size); virtual int peek(void); virtual int read(void); virtual void flush(void); diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp index 59cf5f74..d4352488 100644 --- a/cores/arduino/USB/USBCore.cpp +++ b/cores/arduino/USB/USBCore.cpp @@ -387,25 +387,9 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup) return true; } -void USBDeviceClass::epOut(uint32_t ep) -{ - usbd.epBank0AckTransferComplete(ep); - //usbd.epBank0AckTransferFailed(ep); - usbd.epBank0EnableTransferComplete(ep); - usbd.epBank0SetByteCount(ep, 0); - usbd.epBank0ResetReady(ep); -} - void USBDeviceClass::handleEndpoint(uint8_t ep) { #if defined(CDC_ENABLED) - if (ep == CDC_ENDPOINT_OUT && usbd.epBank0IsTransferComplete(CDC_ENDPOINT_OUT)) - { - // Ack Transfer complete - usbd.epBank0AckTransferComplete(CDC_ENDPOINT_OUT); - - SerialUSB.accept(udd_ep_out_cache_buffer[CDC_ENDPOINT_OUT], available(CDC_ENDPOINT_OUT)); - } if (ep == CDC_ENDPOINT_IN) { // NAK on endpoint IN, the bank is not yet filled in. @@ -580,14 +564,7 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config) } else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0))) { - usbd.epBank0SetSize(ep, 64); - usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]); - usbd.epBank0SetType(ep, 3); // BULK OUT - - // Release OUT EP - usbd.epBank0SetMultiPacketSize(ep, 64); - usbd.epBank0SetByteCount(ep, 0); - epOut(ep); + epHandlers[ep] = new DoubleBufferedEPOutHandler(ep, 64); } else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0))) { -- GitLab