diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index 3c6610cd6f6..a14e437e3f8 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -191,6 +191,8 @@ static inline u8 FrameNumber() //================================================================== //================================================================== +bool _sendZlp[USB_ENDPOINTS]; + u8 USBGetConfiguration(void) { return _usbConfiguration; @@ -204,7 +206,7 @@ class LockEP LockEP(u8 ep) : _sreg(SREG) { cli(); - SetEP(ep & 7); + SetEP(ep & USB_ENDPOINTS_MASK); } ~LockEP() { @@ -300,8 +302,15 @@ int USB_Send(u8 ep, const void* d, int len) while (n--) Send8(*data++); } - if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer + _sendZlp[ep & USB_ENDPOINTS_MASK] = !ReadWriteAllowed() && (len == 0) && !(ep & TRANSFER_RELEASE); + + if (!ReadWriteAllowed()) // Release full buffer + ReleaseTX(); + + if ((len == 0) && (ep & TRANSFER_RELEASE)) { + while(!ReadWriteAllowed()); ReleaseTX(); + } } } TXLED1; // light the TX LED @@ -625,8 +634,15 @@ ISR(USB_COM_vect) void USB_Flush(u8 ep) { SetEP(ep); - if (FifoByteCount()) + + // wait for write access if a ZLP is needed + if (_sendZlp[ep]) + while(!ReadWriteAllowed()); + + if (FifoByteCount() || _sendZlp[ep]) ReleaseTX(); + + _sendZlp[ep] = false; } static inline void USB_ClockDisable() diff --git a/hardware/arduino/avr/cores/arduino/USBDesc.h b/hardware/arduino/avr/cores/arduino/USBDesc.h index c0dce079ebc..17371155fcd 100644 --- a/hardware/arduino/avr/cores/arduino/USBDesc.h +++ b/hardware/arduino/avr/cores/arduino/USBDesc.h @@ -23,6 +23,7 @@ #else #define USB_ENDPOINTS 5 // AtMegaxxU2 #endif +#define USB_ENDPOINTS_MASK 7 #define ISERIAL_MAX_LEN 20