Skip to content
Snippets Groups Projects
Commit 3ba1a352 authored by Cristian Maglie's avatar Cristian Maglie
Browse files

Moved EPHandler in USBDevice headers

The reference to the upper USBDevice class is passed on
the EPHandler constructor.
parent 7d377539
No related branches found
No related tags found
No related merge requests found
......@@ -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;
};
......@@ -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)))
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment