diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 857a27fe9d7..544178661dc 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -17,59 +17,117 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "USBAPI.h" #include "PluggableUSB.h" #if defined(USBCON) #ifdef PLUGGABLE_USB_ENABLED -#define MAX_MODULES 6 +#include "USBDevice.h" -static u8 lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT; -static u8 lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT; +PUSB_ PUSB; -extern u8 _initEndpoints[]; - -//PUSBCallbacks cbs[MAX_MODULES]; -static u8 modules_count = 0; +PUSB_::PUSB_(void) : +numModules(0), lastInterface(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), +lastEndpoint(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), rootDevice(NULL) +{ -static PUSBListNode* rootNode = NULL; +} -int PUSB_GetInterface(u8* interfaceNum) +int PUSB_::PUSB_GetInterface(u8* interfaceNum) { int ret = 0; - PUSBListNode* node = rootNode; - for (u8 i=0; icb->getInterface(interfaceNum); - node = node->next; + CUSBDevice* device = rootDevice; + for (u8 i=0; i < numModules; i++) { + ret = device->getInterface(interfaceNum); + device = device->next; } return ret; } -int PUSB_GetDescriptor(int8_t t) +int PUSB_::PUSB_GetDescriptor(int8_t t) { int ret = 0; - PUSBListNode* node = rootNode; - for (u8 i=0; icb->getDescriptor(t); - node = node->next; + CUSBDevice* device = rootDevice; + for (u8 i=0; i < numModules; i++) { + ret = device->getDescriptor(t); + if(ret) + break; + device = device->next; } return ret; } -bool PUSB_Setup(USBSetup& setup, u8 j) +bool PUSB_::PUSB_Setup(USBSetup& setup, u8 j) { bool ret = false; - PUSBListNode* node = rootNode; - for (u8 i=0; icb->setup(setup, j); - node = node->next; + CUSBDevice* device = rootDevice; + for (u8 i=0; i < numModules; i++) { + ret = device->setup(setup, j); + if(ret) + break; + device = device->next; } return ret; } +void PUSB_::PUSB_AddFunction(CUSBDevice* device) +{ + // All modules already used + // TODO check endpoint count rather than moduls? + if (numModules >= MAX_MODULES) { + return; + } + + // Add a new module + if (numModules == 0) { + rootDevice = device; + } + else { + CUSBDevice *current = rootDevice; + while(current->next != NULL) { + current = current->next; + } + current->next = device; + } + numModules++; + + // Save new interface count position + device->firstInterface = lastInterface; + lastInterface += device->numInterfaces; + + // Configure endpoints and count position + device->firstEndpoint = lastEndpoint; + // TODO check max enpoints + for (u8 i = 0; i < device->numEndpoints; i++) { + _initEndpoints[lastEndpoint] = device->endpointType[i]; + lastEndpoint++; + } + + // TODO restart USB layer??? +} + + +// TODO remove wrappers +int PUSB_GetInterface(u8* interfaceNum) +{ + return PUSB.PUSB_GetInterface(interfaceNum); +} + +int PUSB_GetDescriptor(int8_t t) +{ + return PUSB.PUSB_GetDescriptor(t); +} + +bool PUSB_Setup(USBSetup& setup, u8 j) +{ + return PUSB.PUSB_Setup(setup, j); +} +/* int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface) { + // TODO not implemented, incompatible with "old" API + return 0; + if (modules_count >= MAX_MODULES) { return 0; } @@ -93,8 +151,9 @@ int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface) modules_count++; return lastEp - node->cb->numEndpoints; // restart USB layer??? -} + +}*/ #endif -#endif /* if defined(USBCON) */ \ No newline at end of file +#endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 23013eb7844..380b6bbe8ba 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -17,41 +17,49 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef PUSB_h -#define PUSB_h +// Include Guard +#pragma once #include "USBAPI.h" -#include #if defined(USBCON) -typedef struct __attribute__((packed)) +// TODO different for u2 series +#define MAX_MODULES 6 + +// TODO where defined?? +extern u8 _initEndpoints[]; + +class CUSBDevice; + +class PUSB_ { - bool (*setup)(USBSetup& setup, u8 i); - int (*getInterface)(u8* interfaceNum); - int (*getDescriptor)(int8_t t); - int8_t numEndpoints; - int8_t numInterfaces; - uint8_t *endpointType; -} PUSBCallbacks; - -class PUSBListNode { public: - PUSBListNode *next = NULL; - PUSBCallbacks *cb; - PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;} + PUSB_(void); + + // Called from USB-Core.cpp + // Needs to be public + int PUSB_GetInterface(u8* interfaceNum); + int PUSB_GetDescriptor(int8_t t); + bool PUSB_Setup(USBSetup& setup, u8 i); + + // Only access this class via the USBDevice +private: + friend CUSBDevice; + void PUSB_AddFunction(CUSBDevice* device); + + // Variables used to calculate endpoints etc + uint8_t numModules; + u8 lastInterface; + u8 lastEndpoint; + CUSBDevice* rootDevice; }; -int8_t PUSB_AddFunction(PUSBListNode *node, u8 *interface); - +// TODO remove old wrappers int PUSB_GetInterface(u8* interfaceNum); int PUSB_GetDescriptor(int8_t t); bool PUSB_Setup(USBSetup& setup, u8 i); -void PUSB_Begin(); - -#endif - #endif diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index 733a178c909..7d02c83fd10 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -310,7 +310,7 @@ int USB_Send(u8 ep, const void* d, int len) u8 _initEndpoints[] = { - 0, + 0, // Control EP EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT diff --git a/hardware/arduino/avr/cores/arduino/USBDevice.cpp b/hardware/arduino/avr/cores/arduino/USBDevice.cpp new file mode 100644 index 00000000000..174e13b694f --- /dev/null +++ b/hardware/arduino/avr/cores/arduino/USBDevice.cpp @@ -0,0 +1,17 @@ + +#include "USBDevice.h" +#include "PluggableUSB.h" + +#if defined(USBCON) +#ifdef PLUGGABLE_USB_ENABLED + +CUSBDevice::CUSBDevice(const int8_t numEP, const int8_t numIF, const uint8_t* epType) : +numEndpoints(numEP), numInterfaces(numIF), firstEndpoint(-1), firstInterface(-1), endpointType(epType) +{ + PUSB.PUSB_AddFunction(this); +} + + +#endif + +#endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/cores/arduino/USBDevice.h b/hardware/arduino/avr/cores/arduino/USBDevice.h new file mode 100644 index 00000000000..8df4ec888fb --- /dev/null +++ b/hardware/arduino/avr/cores/arduino/USBDevice.h @@ -0,0 +1,38 @@ +// Include guard +#pragma once + +#define USBDEVICE_INCLUDED + +#include +#include + +//http://stackoverflow.com/questions/1837165/can-two-classes-see-each-other-using-c + +class PUSB_; +extern PUSB_ PUSB; + +// Important note: USBDevice is somehow reserved, do not use the name. +class CUSBDevice +{ +public: + CUSBDevice(const int8_t numEP, const int8_t numIF, const uint8_t* epType); + + // Needs to be public for static PUSB_ function access + // Inherit this device private and everything should be fine +//private: + CUSBDevice* next = NULL; + + virtual bool setup(USBSetup& setup, u8 i) = 0; + virtual int getInterface(u8* interfaceNum) = 0; + virtual int getDescriptor(int8_t t) = 0; + + const int8_t numEndpoints; + const int8_t numInterfaces; + int8_t firstEndpoint; + int8_t firstInterface; + const uint8_t *endpointType; + + +protected: + +};