Skip to content

Commit 9f678cb

Browse files
committed
USB-CDC: Refactored EP OUT handling
1 parent e4f7bf5 commit 9f678cb

File tree

3 files changed

+30
-33
lines changed

3 files changed

+30
-33
lines changed

cores/arduino/USB/CDC.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -161,32 +161,21 @@ void Serial_::end(void)
161161
{
162162
}
163163

164-
void Serial_::accept(void)
164+
void Serial_::accept(uint8_t *data, uint32_t size)
165165
{
166-
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
167-
uint32_t len = usb.recv(CDC_ENDPOINT_OUT, &buffer, CDC_SERIAL_BUFFER_SIZE);
168-
169-
uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0);
170-
__disable_irq();
171-
172166
ring_buffer *ringBuffer = &cdc_rx_buffer;
173167
uint32_t i = ringBuffer->head;
174-
175-
// if we should be storing the received character into the location
176-
// just before the tail (meaning that the head would advance to the
177-
// current location of the tail), we're about to overflow the buffer
178-
// and so we don't write the character or advance the head.
179-
uint32_t k = 0;
180-
while (len > 0 && !ringBuffer->full) {
181-
len--;
182-
ringBuffer->buffer[i++] = buffer[k++];
168+
while (size--) {
169+
ringBuffer->buffer[i++] = *data;
170+
data++;
183171
i %= CDC_SERIAL_BUFFER_SIZE;
184-
if (i == ringBuffer->tail)
185-
ringBuffer->full = true;
186172
}
187173
ringBuffer->head = i;
188-
if (enableInterrupts) {
189-
__enable_irq();
174+
if (i == ringBuffer->tail) ringBuffer->full = true;
175+
if (availableForStore() < EPX_SIZE) {
176+
stalled = true;
177+
} else {
178+
usb.epOut(CDC_ENDPOINT_OUT);
190179
}
191180
}
192181

@@ -196,9 +185,6 @@ int Serial_::available(void)
196185
if (buffer->full) {
197186
return CDC_SERIAL_BUFFER_SIZE;
198187
}
199-
if (buffer->head == buffer->tail) {
200-
USB->DEVICE.DeviceEndpoint[CDC_ENDPOINT_OUT].EPINTENSET.reg = USB_DEVICE_EPINTENCLR_TRCPT(1);
201-
}
202188
return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE;
203189
}
204190

@@ -228,11 +214,11 @@ int Serial_::read(void)
228214
{
229215
ring_buffer *buffer = &cdc_rx_buffer;
230216

231-
// if the head isn't ahead of the tail, we don't have any characters
232-
if (buffer->head == buffer->tail && !buffer->full)
217+
// if we have enough space enable OUT endpoint to receive more data
218+
if (stalled && availableForStore() >= EPX_SIZE)
233219
{
234-
if (usb.available(CDC_ENDPOINT_OUT))
235-
accept();
220+
stalled = false;
221+
usb.epOut(CDC_ENDPOINT_OUT);
236222
}
237223
if (buffer->head == buffer->tail && !buffer->full)
238224
{

cores/arduino/USB/USBAPI.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ 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);
9596

9697
// private?
9798
uint32_t armSend(uint32_t ep, const void *data, uint32_t len);
@@ -112,14 +113,14 @@ extern USBDeviceClass USBDevice;
112113
class Serial_ : public Stream
113114
{
114115
public:
115-
Serial_(USBDeviceClass &_usb) : usb(_usb) { }
116+
Serial_(USBDeviceClass &_usb) : usb(_usb), stalled(false) { }
116117
void begin(uint32_t baud_count);
117118
void begin(unsigned long, uint8_t);
118119
void end(void);
119120

120121
virtual int available(void);
121122
virtual int availableForWrite(void);
122-
virtual void accept(void);
123+
virtual void accept(uint8_t *data, uint32_t size);
123124
virtual int peek(void);
124125
virtual int read(void);
125126
virtual void flush(void);
@@ -172,6 +173,7 @@ class Serial_ : public Stream
172173

173174
USBDeviceClass &usb;
174175
RingBuffer *_cdc_rx_buffer;
176+
bool stalled;
175177
};
176178
extern Serial_ SerialUSB;
177179

cores/arduino/USB/USBCore.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,23 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup)
247247
return true;
248248
}
249249

250+
void USBDeviceClass::epOut(uint32_t ep)
251+
{
252+
usbd.epBank0AckTransferComplete(ep);
253+
//usbd.epBank0AckTransferFailed(ep);
254+
usbd.epBank0EnableTransferComplete(ep);
255+
usbd.epBank0ResetReady(ep);
256+
}
250257

251258
void USBDeviceClass::handleEndpoint(uint8_t ep)
252259
{
253260
#if defined(CDC_ENABLED)
254-
if (ep == CDC_ENDPOINT_OUT)
261+
if (ep == CDC_ENDPOINT_OUT && usbd.epBank0IsTransferComplete(CDC_ENDPOINT_OUT))
255262
{
256-
// Handle received bytes
257-
if (available(CDC_ENDPOINT_OUT))
258-
SerialUSB.accept();
263+
// Ack Transfer complete
264+
usbd.epBank0AckTransferComplete(CDC_ENDPOINT_OUT);
265+
266+
SerialUSB.accept(udd_ep_out_cache_buffer[CDC_ENDPOINT_OUT], available(CDC_ENDPOINT_OUT));
259267
}
260268
if (ep == CDC_ENDPOINT_IN)
261269
{
@@ -438,6 +446,7 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config)
438446
// Release OUT EP
439447
usbd.epBank0SetMultiPacketSize(ep, 64);
440448
usbd.epBank0SetByteCount(ep, 0);
449+
epOut(ep);
441450
}
442451
else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0)))
443452
{

0 commit comments

Comments
 (0)