Skip to content

Commit f87866e

Browse files
committed
USB: properly handle IRQ clash in DoubleBuffer endpoint
1 parent 4e9cbc0 commit f87866e

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

cores/arduino/USB/SAMD21_USBDevice.h

+28-24
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,14 @@ class DoubleBufferedEPOutHandler : public EPHandler {
276276
virtual ~DoubleBufferedEPOutHandler() {
277277
}
278278

279-
uint32_t _recv(uint32_t len)
279+
uint32_t _recv()
280280
{
281281
uint32_t i = 0;
282+
uint32_t len = 0;
283+
284+
synchronized {
285+
len = _rx_buffer.availableForStore();
286+
}
282287

283288
// R/W: current, first0/1, ready0/1, notify
284289
// R : last0/1, data0/1
@@ -329,33 +334,32 @@ class DoubleBufferedEPOutHandler : public EPHandler {
329334
}
330335

331336
virtual uint32_t recv(void *_data, uint32_t len) {
332-
_recv(_rx_buffer.availableForStore());
337+
_recv();
333338
uint32_t i = 0;
334339
uint8_t *data = reinterpret_cast<uint8_t *>(_data);
335-
for (; i < len; i++) {
336-
if (!_rx_buffer.available()) {
337-
break;
340+
synchronized {
341+
for (; i < len && _rx_buffer.available(); i++) {
342+
data[i] = _rx_buffer.read_char();
338343
}
339-
data[i] = _rx_buffer.read_char();
340344
}
341345
return i;
342346
}
343347

344-
virtual uint32_t _available() const {
345-
if (current == 0) {
346-
bool ready = false;
347-
synchronized {
348-
ready = ready0;
349-
}
350-
return ready ? (last0 - first0) : 0;
351-
} else {
352-
bool ready = false;
353-
synchronized {
354-
ready = ready1;
355-
}
356-
return ready ? (last1 - first1) : 0;
357-
}
358-
}
348+
virtual uint32_t _available() const {
349+
if (current == 0) {
350+
bool ready = ready0;
351+
synchronized {
352+
ready = ready0;
353+
}
354+
return ready ? (last0 - first0) : 0;
355+
} else {
356+
bool ready = false;
357+
synchronized {
358+
ready = ready1;
359+
}
360+
return ready ? (last1 - first1) : 0;
361+
}
362+
}
359363

360364
virtual void handleEndpoint()
361365
{
@@ -396,12 +400,12 @@ class DoubleBufferedEPOutHandler : public EPHandler {
396400

397401
// Returns how many bytes are stored in the buffers
398402
virtual uint32_t available() {
399-
_recv(_rx_buffer.availableForStore());
403+
_recv();
400404
return _rx_buffer.available();
401405
}
402406

403407
virtual int peek() {
404-
_recv(_rx_buffer.availableForStore());
408+
_recv();
405409
return _rx_buffer.peek();
406410
}
407411

@@ -415,7 +419,7 @@ class DoubleBufferedEPOutHandler : public EPHandler {
415419
RingBuffer _rx_buffer;
416420

417421
const uint32_t ep;
418-
uint32_t current, incoming;
422+
volatile uint32_t current, incoming;
419423

420424
__attribute__((__aligned__(4))) volatile uint8_t data0[size];
421425
uint32_t first0;

0 commit comments

Comments
 (0)