From 3ba1a352968ed74503a26c3ba3616141eddfec57 Mon Sep 17 00:00:00 2001 From: Cristian Maglie <c.maglie@arduino.cc> Date: Wed, 20 Jul 2016 16:58:30 +0200 Subject: [PATCH] Moved EPHandler in USBDevice headers The reference to the upper USBDevice class is passed on the EPHandler constructor. --- cores/arduino/USB/SAMD21_USBDevice.h | 146 ++++++++++++++++++++++++++- cores/arduino/USB/USBCore.cpp | 142 +------------------------- 2 files changed, 145 insertions(+), 143 deletions(-) diff --git a/cores/arduino/USB/SAMD21_USBDevice.h b/cores/arduino/USB/SAMD21_USBDevice.h index 203a1c78..9cf9c0b2 100644 --- a/cores/arduino/USB/SAMD21_USBDevice.h +++ b/cores/arduino/USB/SAMD21_USBDevice.h @@ -62,8 +62,8 @@ public: // USB Interrupts inline bool isEndOfResetInterrupt() { return usb.INTFLAG.bit.EORST; } inline void ackEndOfResetInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; } - inline void enableEndOfResetInterrupt() { usb.INTENSET.bit.EORST = 1; } - inline void disableEndOfResetInterrupt() { usb.INTENCLR.bit.EORST = 1; } + inline void enableEndOfResetInterrupt() { usb.INTENSET.bit.EORST = 1; } + inline void disableEndOfResetInterrupt() { usb.INTENCLR.bit.EORST = 1; } inline bool isStartOfFrameInterrupt() { return usb.INTFLAG.bit.SOF; } inline void ackStartOfFrameInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; } @@ -195,3 +195,145 @@ void USBDevice_SAMD21G18x::calibrate() { usb.PADCAL.bit.TRIM = pad_trim; } +class EPHandler { +public: + virtual void handleEndpoint() = 0; + virtual uint32_t recv(void *_data, uint32_t len) = 0; + virtual uint32_t available() const = 0; +}; + +class DoubleBufferedEPOutHandler : public EPHandler { +public: + DoubleBufferedEPOutHandler(USBDevice_SAMD21G18x &usbDev, uint32_t endPoint, uint32_t bufferSize) : + usbd(usbDev), + ep(endPoint), size(bufferSize), + current(0), incoming(0), + first0(0), last0(0), ready0(false), + first1(0), last1(0), ready1(false), + notify(false) + { + data0 = reinterpret_cast<uint8_t *>(malloc(size)); + data1 = reinterpret_cast<uint8_t *>(malloc(size)); + + usbd.epBank0SetSize(ep, 64); + usbd.epBank0SetType(ep, 3); // BULK OUT + + release(); + } + + // Read one byte from the buffer, if the buffer is empty -1 is returned + int read() { + if (current == 0) { + if (!ready0) { + return -1; + } + if (first0 == last0) { + first0 = 0; + last0 = 0; + ready0 = false; + if (notify) { + release(); + } + current = 1; + return -1; + } + return data0[first0++]; + } else { + if (!ready1) { + return -1; + } + if (first1 == last1) { + first1 = 0; + last1 = 0; + ready1 = false; + if (notify) { + release(); + } + current = 0; + return -1; + } + return data1[first1++]; + } + } + + virtual void handleEndpoint() + { + if (usbd.epBank0IsTransferComplete(ep)) + { + // Ack Transfer complete + usbd.epBank0AckTransferComplete(ep); + + // Update counters and swap banks + if (incoming == 0) { + last0 = usbd.epBank0ByteCount(ep); + ready0 = true; + incoming = 1; + } else { + last1 = usbd.epBank0ByteCount(ep); + ready1 = true; + incoming = 0; + } + release(); + } + } + + virtual uint32_t recv(void *_data, uint32_t len) + { + uint8_t *data = reinterpret_cast<uint8_t *>(_data); + uint32_t i; + for (i=0; i<len; i++) { + int c = read(); + if (c == -1) break; + data[i] = c; + } + return i; + } + + // Returns how many bytes are stored in the buffers + virtual uint32_t available() const { + return (last0 - first0) + (last1 - first1); + } + + void release() { + if (incoming == 0) { + if (ready0) { + notify = true; + return; + } + usbd.epBank0SetAddress(ep, data0); + } else { + if (ready1) { + notify = true; + return; + } + usbd.epBank0SetAddress(ep, data1); + } + usbd.epBank0AckTransferComplete(ep); + //usbd.epBank0AckTransferFailed(ep); + usbd.epBank0EnableTransferComplete(ep); + + // Release OUT EP + usbd.epBank0SetMultiPacketSize(ep, size); + usbd.epBank0SetByteCount(ep, 0); + usbd.epBank0ResetReady(ep); + notify = false; + } + +private: + USBDevice_SAMD21G18x &usbd; + + const uint32_t ep; + const uint32_t size; + uint32_t current, incoming; + + uint8_t *data0; + uint32_t first0, last0; + bool ready0; + + uint8_t *data1; + uint32_t first1, last1; + bool ready1; + + bool notify; +}; + diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp index d4352488..bd11d39b 100644 --- a/cores/arduino/USB/USBCore.cpp +++ b/cores/arduino/USB/USBCore.cpp @@ -46,146 +46,6 @@ extern "C" void UDD_Handler(void) { USBDevice.ISRHandler(); } -class EPHandler { -public: - virtual void handleEndpoint() = 0; - virtual uint32_t recv(void *_data, uint32_t len) = 0; - virtual uint32_t available() const = 0; -}; - -class DoubleBufferedEPOutHandler : public EPHandler { -public: - DoubleBufferedEPOutHandler(uint32_t endPoint, uint32_t bufferSize) : - ep(endPoint), size(bufferSize), - current(0), incoming(0), - first0(0), last0(0), ready0(false), - first1(0), last1(0), ready1(false), - notify(false) - { - data0 = reinterpret_cast<uint8_t *>(malloc(size)); - data1 = reinterpret_cast<uint8_t *>(malloc(size)); - - usbd.epBank0SetSize(ep, 64); - usbd.epBank0SetType(ep, 3); // BULK OUT - - release(); - } - - // Read one byte from the buffer, if the buffer is empty -1 is returned - int read() { - if (current == 0) { - if (!ready0) { - return -1; - } - if (first0 == last0) { - first0 = 0; - last0 = 0; - ready0 = false; - if (notify) { - release(); - } - current = 1; - return -1; - } - return data0[first0++]; - } else { - if (!ready1) { - return -1; - } - if (first1 == last1) { - first1 = 0; - last1 = 0; - ready1 = false; - if (notify) { - release(); - } - current = 0; - return -1; - } - return data1[first1++]; - } - } - - virtual void handleEndpoint() - { - if (usbd.epBank0IsTransferComplete(ep)) - { - // Ack Transfer complete - usbd.epBank0AckTransferComplete(ep); - - // Update counters and swap banks - if (incoming == 0) { - last0 = usbd.epBank0ByteCount(ep); - ready0 = true; - incoming = 1; - } else { - last1 = usbd.epBank0ByteCount(ep); - ready1 = true; - incoming = 0; - } - release(); - } - } - - virtual uint32_t recv(void *_data, uint32_t len) - { - uint8_t *data = reinterpret_cast<uint8_t *>(_data); - uint32_t i; - for (i=0; i<len; i++) { - int c = read(); - if (c == -1) break; - data[i] = c; - } - return i; - } - - // Returns how many bytes are stored in the buffers - virtual uint32_t available() const { - return (last0 - first0) + (last1 - first1); - } - - void release() { - if (incoming == 0) { - if (ready0) { - notify = true; - return; - } - usbd.epBank0SetAddress(ep, data0); - } else { - if (ready1) { - notify = true; - return; - } - usbd.epBank0SetAddress(ep, data1); - } - usbd.epBank0AckTransferComplete(ep); - //usbd.epBank0AckTransferFailed(ep); - usbd.epBank0EnableTransferComplete(ep); - - // Release OUT EP - usbd.epBank0SetMultiPacketSize(ep, size); - usbd.epBank0SetByteCount(ep, 0); - usbd.epBank0ResetReady(ep); - notify = false; - } - -private: - const uint32_t ep; - const uint32_t size; - uint32_t current, incoming; - - uint8_t *data0; - uint32_t first0, last0; - bool ready0; - - uint8_t *data1; - uint32_t first1, last1; - bool ready1; - - bool notify; -}; - - const uint16_t STRING_LANGUAGE[2] = { (3<<8) | (2+2), 0x0409 // English @@ -564,7 +424,7 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config) } else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0))) { - epHandlers[ep] = new DoubleBufferedEPOutHandler(ep, 64); + epHandlers[ep] = new DoubleBufferedEPOutHandler(usbd, ep, 64); } else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0))) { -- GitLab