Skip to content

Commit 7d37753

Browse files
committed
USB-CDC: OUT EP is now handled with a custom EPHandler
1 parent 9f24bbe commit 7d37753

File tree

3 files changed

+13
-99
lines changed

3 files changed

+13
-99
lines changed

cores/arduino/USB/CDC.cpp

Lines changed: 12 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,6 @@
3333

3434
#define CDC_LINESTATE_READY (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR)
3535

36-
struct ring_buffer {
37-
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
38-
volatile uint32_t head;
39-
volatile uint32_t tail;
40-
volatile bool full;
41-
};
42-
ring_buffer cdc_rx_buffer = {{0}, 0, 0, false};
43-
4436
typedef struct {
4537
uint32_t dwDTERate;
4638
uint8_t bCharFormat;
@@ -146,7 +138,6 @@ bool CDC_Setup(USBSetup& setup)
146138
return false;
147139
}
148140

149-
uint32_t _serialPeek = -1;
150141
void Serial_::begin(uint32_t /* baud_count */)
151142
{
152143
// uart config is ignored in USB-CDC
@@ -161,31 +152,9 @@ void Serial_::end(void)
161152
{
162153
}
163154

164-
void Serial_::accept(uint8_t *data, uint32_t size)
165-
{
166-
ring_buffer *ringBuffer = &cdc_rx_buffer;
167-
uint32_t i = ringBuffer->head;
168-
while (size--) {
169-
ringBuffer->buffer[i++] = *data;
170-
data++;
171-
i %= CDC_SERIAL_BUFFER_SIZE;
172-
}
173-
ringBuffer->head = i;
174-
if (i == ringBuffer->tail) ringBuffer->full = true;
175-
if (availableForStore() < EPX_SIZE) {
176-
stalled = true;
177-
} else {
178-
usb.epOut(CDC_ENDPOINT_OUT);
179-
}
180-
}
181-
182155
int Serial_::available(void)
183156
{
184-
ring_buffer *buffer = &cdc_rx_buffer;
185-
if (buffer->full) {
186-
return CDC_SERIAL_BUFFER_SIZE;
187-
}
188-
return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE;
157+
return usb.available(CDC_ENDPOINT_OUT);
189158
}
190159

191160
int Serial_::availableForWrite(void)
@@ -195,43 +164,24 @@ int Serial_::availableForWrite(void)
195164
return (EPX_SIZE - 1);
196165
}
197166

167+
int _serialPeek = -1;
168+
198169
int Serial_::peek(void)
199170
{
200-
ring_buffer *buffer = &cdc_rx_buffer;
201-
if (buffer->head == buffer->tail && !buffer->full) {
202-
return -1;
203-
} else {
204-
return buffer->buffer[buffer->tail];
205-
}
171+
if (_serialPeek != -1)
172+
return _serialPeek;
173+
_serialPeek = read();
174+
return _serialPeek;
206175
}
207176

208-
209-
// if the ringBuffer is empty: try to fill it
210-
// if it's still empty: return -1
211-
// else return the last char
212-
// so the buffer is filled only when needed
213177
int Serial_::read(void)
214178
{
215-
ring_buffer *buffer = &cdc_rx_buffer;
216-
217-
uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0);
218-
__disable_irq();
219-
220-
// if we have enough space enable OUT endpoint to receive more data
221-
if (stalled && availableForStore() >= EPX_SIZE)
222-
{
223-
stalled = false;
224-
usb.epOut(CDC_ENDPOINT_OUT);
179+
if (_serialPeek != -1) {
180+
int res = _serialPeek;
181+
_serialPeek = -1;
182+
return res;
225183
}
226-
int c = -1;
227-
if (buffer->head != buffer->tail || buffer->full)
228-
{
229-
c = buffer->buffer[buffer->tail];
230-
buffer->tail = (uint32_t)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
231-
buffer->full = false;
232-
}
233-
if (enableInterrupts) __enable_irq();
234-
return c;
184+
return usb.recv(CDC_ENDPOINT_OUT);
235185
}
236186

237187
void Serial_::flush(void)
@@ -337,17 +287,6 @@ bool Serial_::rts() {
337287
return _usbLineInfo.lineState & 0x2;
338288
}
339289

340-
int Serial_::availableForStore(void) {
341-
ring_buffer *buffer = &cdc_rx_buffer;
342-
343-
if (buffer->full)
344-
return 0;
345-
else if (buffer->head >= buffer->tail)
346-
return CDC_SERIAL_BUFFER_SIZE - 1 - buffer->head + buffer->tail;
347-
else
348-
return buffer->tail - buffer->head - 1;
349-
}
350-
351290
Serial_ SerialUSB(USBDevice);
352291

353292
#endif

cores/arduino/USB/USBAPI.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ class USBDeviceClass {
9292
uint32_t available(uint32_t ep);
9393
void flush(uint32_t ep);
9494
void stall(uint32_t ep);
95-
void epOut(uint32_t ep);
9695

9796
// private?
9897
uint32_t armSend(uint32_t ep, const void *data, uint32_t len);
@@ -120,7 +119,6 @@ class Serial_ : public Stream
120119

121120
virtual int available(void);
122121
virtual int availableForWrite(void);
123-
virtual void accept(uint8_t *data, uint32_t size);
124122
virtual int peek(void);
125123
virtual int read(void);
126124
virtual void flush(void);

cores/arduino/USB/USBCore.cpp

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -387,25 +387,9 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup)
387387
return true;
388388
}
389389

390-
void USBDeviceClass::epOut(uint32_t ep)
391-
{
392-
usbd.epBank0AckTransferComplete(ep);
393-
//usbd.epBank0AckTransferFailed(ep);
394-
usbd.epBank0EnableTransferComplete(ep);
395-
usbd.epBank0SetByteCount(ep, 0);
396-
usbd.epBank0ResetReady(ep);
397-
}
398-
399390
void USBDeviceClass::handleEndpoint(uint8_t ep)
400391
{
401392
#if defined(CDC_ENABLED)
402-
if (ep == CDC_ENDPOINT_OUT && usbd.epBank0IsTransferComplete(CDC_ENDPOINT_OUT))
403-
{
404-
// Ack Transfer complete
405-
usbd.epBank0AckTransferComplete(CDC_ENDPOINT_OUT);
406-
407-
SerialUSB.accept(udd_ep_out_cache_buffer[CDC_ENDPOINT_OUT], available(CDC_ENDPOINT_OUT));
408-
}
409393
if (ep == CDC_ENDPOINT_IN)
410394
{
411395
// NAK on endpoint IN, the bank is not yet filled in.
@@ -580,14 +564,7 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config)
580564
}
581565
else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0)))
582566
{
583-
usbd.epBank0SetSize(ep, 64);
584-
usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
585-
usbd.epBank0SetType(ep, 3); // BULK OUT
586-
587-
// Release OUT EP
588-
usbd.epBank0SetMultiPacketSize(ep, 64);
589-
usbd.epBank0SetByteCount(ep, 0);
590-
epOut(ep);
567+
epHandlers[ep] = new DoubleBufferedEPOutHandler(ep, 64);
591568
}
592569
else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0)))
593570
{

0 commit comments

Comments
 (0)