Skip to content

Commit b58e68f

Browse files
committed
[AVR] USB send ZLP when needed
See #5732 #4864 #4138 #3946
1 parent cb2c981 commit b58e68f

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

hardware/arduino/avr/cores/arduino/USBCore.cpp

+18-4
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,9 @@ int USB_Send(u8 ep, const void* d, int len)
273273
int r = len;
274274
const u8* data = (const u8*)d;
275275
u8 timeout = 250; // 250ms timeout on send? TODO
276-
while (len)
276+
bool sendZlp = false;
277+
278+
while (len || sendZlp)
277279
{
278280
u8 n = USB_SendSpace(ep);
279281
if (n == 0)
@@ -284,13 +286,16 @@ int USB_Send(u8 ep, const void* d, int len)
284286
continue;
285287
}
286288

287-
if (n > len)
289+
if (n > len) {
288290
n = len;
291+
}
292+
289293
{
290294
LockEP lock(ep);
291295
// Frame may have been released by the SOF interrupt handler
292296
if (!ReadWriteAllowed())
293297
continue;
298+
294299
len -= n;
295300
if (ep & TRANSFER_ZERO)
296301
{
@@ -307,8 +312,17 @@ int USB_Send(u8 ep, const void* d, int len)
307312
while (n--)
308313
Send8(*data++);
309314
}
310-
if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer
315+
316+
if (sendZlp) {
317+
ReleaseTX();
318+
sendZlp = false;
319+
} else if (!ReadWriteAllowed()) { // ...release if buffer is full...
311320
ReleaseTX();
321+
if (len == 0) sendZlp = true;
322+
} else if ((len == 0) && (ep & TRANSFER_RELEASE)) { // ...or if forced with TRANSFER_RELEASE
323+
// XXX: TRANSFER_RELEASE is never used can be removed?
324+
ReleaseTX();
325+
}
312326
}
313327
}
314328
TXLED1; // light the TX LED
@@ -473,7 +487,7 @@ static
473487
bool SendConfiguration(int maxlen)
474488
{
475489
// Count and measure interfaces
476-
InitControl(0);
490+
InitControl(0);
477491
u8 interfaces = SendInterfaces();
478492
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
479493

0 commit comments

Comments
 (0)