Commit 3b076597 authored by Cristian Maglie's avatar Cristian Maglie Committed by Cristian Maglie

[AVR] USB send ZLP when needed

See #5732 #4864 #4138 #3946
parent f27e8fe1
...@@ -273,7 +273,9 @@ int USB_Send(u8 ep, const void* d, int len) ...@@ -273,7 +273,9 @@ int USB_Send(u8 ep, const void* d, int len)
int r = len; int r = len;
const u8* data = (const u8*)d; const u8* data = (const u8*)d;
u8 timeout = 250; // 250ms timeout on send? TODO u8 timeout = 250; // 250ms timeout on send? TODO
while (len) bool sendZlp = false;
while (len || sendZlp)
{ {
u8 n = USB_SendSpace(ep); u8 n = USB_SendSpace(ep);
if (n == 0) if (n == 0)
...@@ -284,13 +286,16 @@ int USB_Send(u8 ep, const void* d, int len) ...@@ -284,13 +286,16 @@ int USB_Send(u8 ep, const void* d, int len)
continue; continue;
} }
if (n > len) if (n > len) {
n = len; n = len;
}
{ {
LockEP lock(ep); LockEP lock(ep);
// Frame may have been released by the SOF interrupt handler // Frame may have been released by the SOF interrupt handler
if (!ReadWriteAllowed()) if (!ReadWriteAllowed())
continue; continue;
len -= n; len -= n;
if (ep & TRANSFER_ZERO) if (ep & TRANSFER_ZERO)
{ {
...@@ -307,8 +312,17 @@ int USB_Send(u8 ep, const void* d, int len) ...@@ -307,8 +312,17 @@ int USB_Send(u8 ep, const void* d, int len)
while (n--) while (n--)
Send8(*data++); Send8(*data++);
} }
if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer
if (sendZlp) {
ReleaseTX();
sendZlp = false;
} else if (!ReadWriteAllowed()) { // ...release if buffer is full...
ReleaseTX(); ReleaseTX();
if (len == 0) sendZlp = true;
} else if ((len == 0) && (ep & TRANSFER_RELEASE)) { // ...or if forced with TRANSFER_RELEASE
// XXX: TRANSFER_RELEASE is never used can be removed?
ReleaseTX();
}
} }
} }
TXLED1; // light the TX LED TXLED1; // light the TX LED
...@@ -473,7 +487,7 @@ static ...@@ -473,7 +487,7 @@ static
bool SendConfiguration(int maxlen) bool SendConfiguration(int maxlen)
{ {
// Count and measure interfaces // Count and measure interfaces
InitControl(0); InitControl(0);
u8 interfaces = SendInterfaces(); u8 interfaces = SendInterfaces();
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment