diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp index 0ecee14a07bb4a77b261d05022759042f7cbfbfd..f3e4cd70b0f931f914e00e505c35581227ae4f7c 100644 --- a/cores/arduino/USB/CDC.cpp +++ b/cores/arduino/USB/CDC.cpp @@ -242,11 +242,11 @@ size_t Serial_::write(const uint8_t *buffer, size_t size) // TODO - ZE - check behavior on different OSes and test what happens if an // open connection isn't broken cleanly (cable is yanked out, host dies // or locks up, or host virtual serial port hangs) -// if (_usbLineInfo.lineState > 0) // Problem with Windows(R) + if (_usbLineInfo.lineState > 0) // Problem with Windows(R) { uint32_t r = usb.send(CDC_ENDPOINT_IN, buffer, size); - if (r > 0) { + if (r == 0) { return r; } else { setWriteError(); diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp index 3852e30fbc68b57b1641e357dfd8e941cf99df44..3792c85cd112946702e6ffccd93a02b38db59b8b 100644 --- a/cores/arduino/USB/USBCore.cpp +++ b/cores/arduino/USB/USBCore.cpp @@ -579,27 +579,64 @@ uint8_t USBDeviceClass::armRecv(uint32_t ep, uint32_t len) // Blocking Send of data to an endpoint uint32_t USBDeviceClass::send(uint32_t ep, const void *data, uint32_t len) { + uint32_t length = 0; + if (!_usbConfiguration) return -1; + if (len > 16384) + return -1; - //armSend(ep, data, len); + if ((unsigned int)data > 0x20000000) + { + // Buffer in RAM + usbd.epBank1SetAddress(ep, (void *)data); + usbd.epBank1SetMultiPacketSize(ep, 0); - /* memcopy could be safer in multithreaded environment */ - memcpy(&udd_ep_in_cache_buffer[ep], data, len); + usbd.epBank1SetByteCount(ep, len); - usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]); - usbd.epBank1SetByteCount(ep, len); + // Clear the transfer complete flag + usbd.epBank1AckTransferComplete(ep); - // Clear the transfer complete flag - usbd.epBank1AckTransferComplete(ep); + // RAM buffer is full, we can send data (IN) + usbd.epBank1SetReady(ep); - // RAM buffer is full, we can send data (IN) - usbd.epBank1SetReady(ep); + // Wait for transfer to complete + while (!usbd.epBank1IsTransferComplete(ep)) { + ; // need fire exit. + } + len = 0; + } + else + { + // Flash area + while (len != 0) + { + if (len >= 64) { + length = 64; + } else { + length = len; + } - // Wait for transfer to complete - while (!usbd.epBank1IsTransferComplete(ep)) { - ; // need fire exit. + /* memcopy could be safer in multi threaded environment */ + memcpy(&udd_ep_in_cache_buffer[ep], data, length); + + usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]); + usbd.epBank1SetByteCount(ep, length); + + // Clear the transfer complete flag + usbd.epBank1AckTransferComplete(ep); + + // RAM buffer is full, we can send data (IN) + usbd.epBank1SetReady(ep); + + // Wait for transfer to complete + while (!usbd.epBank1IsTransferComplete(ep)) { + ; // need fire exit. + } + len -= length; + } } + return len; }