1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-20 14:54:31 +01:00

adapt SAM core to PluggableUSB stable API

This commit is contained in:
Martino Facchin 2015-10-12 14:41:05 +02:00
parent 865ac2f245
commit b4541209cb
4 changed files with 97 additions and 68 deletions

View File

@ -19,80 +19,89 @@
#include "USBAPI.h" #include "USBAPI.h"
#include "USBDesc.h" #include "USBDesc.h"
#include "USBCore.h"
#include "PluggableUSB.h" #include "PluggableUSB.h"
#if defined(USBCON)
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
#define MAX_MODULES 6
static uint8_t lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT;
static uint8_t lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT;
extern uint32_t EndPoints[]; extern uint32_t EndPoints[];
//PUSBCallbacks cbs[MAX_MODULES]; int PluggableUSB_::getInterface(uint8_t* interfaceCount)
static uint8_t modules_count = 0;
static PUSBListNode* rootNode = NULL;
int PUSB_GetInterface(uint8_t* interfaceNum)
{ {
int ret = 0; int sent = 0;
PUSBListNode* node = rootNode; PluggableUSBModule* node;
for (uint8_t i=0; i<modules_count; i++) { for (node = rootNode; node; node = node->next) {
ret = node->cb->getInterface(interfaceNum); int res = node->getInterface(interfaceCount);
node = node->next; if (res < 0)
return -1;
sent += res;
} }
return ret; return sent;
} }
int PUSB_GetDescriptor(int8_t t) int PluggableUSB_::getDescriptor(USBSetup& setup)
{ {
int ret = 0; PluggableUSBModule* node;
PUSBListNode* node = rootNode; for (node = rootNode; node; node = node->next) {
for (uint8_t i=0; i<modules_count && ret == 0; i++) { int ret = node->getDescriptor(setup);
ret = node->cb->getDescriptor(t); // ret!=0 -> request has been processed
node = node->next; if (ret)
return ret;
} }
return ret; return 0;
} }
bool PUSB_Setup(USBSetup& setup, uint8_t j) bool PluggableUSB_::setup(USBSetup& setup)
{ {
bool ret = false; PluggableUSBModule* node;
PUSBListNode* node = rootNode; for (node = rootNode; node; node = node->next) {
for (uint8_t i=0; i<modules_count && ret == false; i++) { if (node->setup(setup)) {
ret = node->cb->setup(setup, j); return true;
node = node->next; }
} }
return ret; return false;
} }
int8_t PUSB_AddFunction(PUSBListNode *node, uint8_t* interface) bool PluggableUSB_::plug(PluggableUSBModule *node)
{ {
if (modules_count >= MAX_MODULES) { if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) {
return 0; return false;
} }
if (modules_count == 0) { if (!rootNode) {
rootNode = node; rootNode = node;
} else { } else {
PUSBListNode *current = rootNode; PluggableUSBModule *current = rootNode;
while(current->next != NULL) { while (current->next) {
current = current->next; current = current->next;
} }
current->next = node; current->next = node;
} }
*interface = lastIf; node->pluggedInterface = lastIf;
lastIf += node->cb->numInterfaces; node->pluggedEndpoint = lastEp;
for ( uint8_t i = 0; i< node->cb->numEndpoints; i++) { lastIf += node->numInterfaces;
EndPoints[lastEp] = node->cb->endpointType[i]; for (uint8_t i = 0; i < node->numEndpoints; i++) {
EndPoints[lastEp] = node->endpointType[i];
lastEp++; lastEp++;
} }
modules_count++; return true;
return lastEp - node->cb->numEndpoints;
// restart USB layer??? // restart USB layer???
} }
PluggableUSB_& PluggableUSB()
{
static PluggableUSB_ obj;
return obj;
}
PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT),
lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT),
rootNode(NULL)
{
// Empty
}
#endif
#endif #endif

View File

@ -25,30 +25,47 @@
#if defined(USBCON) #if defined(USBCON)
typedef struct __attribute__((packed)) class PluggableUSBModule {
{
bool (*setup)(USBSetup& setup, uint8_t i);
int (*getInterface)(uint8_t* interfaceNum);
int (*getDescriptor)(int8_t t);
int8_t numEndpoints;
int8_t numInterfaces;
uint32_t *endpointType;
} PUSBCallbacks;
class PUSBListNode {
public: public:
PUSBListNode *next = NULL; PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint32_t *epType) :
PUSBCallbacks *cb; numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;} { }
protected:
virtual bool setup(USBSetup& setup) = 0;
virtual int getInterface(uint8_t* interfaceCount) = 0;
virtual int getDescriptor(USBSetup& setup) = 0;
uint8_t pluggedInterface;
uint8_t pluggedEndpoint;
const uint8_t numEndpoints;
const uint8_t numInterfaces;
const uint32_t *endpointType;
PluggableUSBModule *next = NULL;
friend class PluggableUSB_;
}; };
int8_t PUSB_AddFunction(PUSBListNode *node, uint8_t *interface); class PluggableUSB_ {
public:
PluggableUSB_();
bool plug(PluggableUSBModule *node);
int getInterface(uint8_t* interfaceCount);
int getDescriptor(USBSetup& setup);
bool setup(USBSetup& setup);
int PUSB_GetInterface(uint8_t* interfaceNum); private:
uint8_t lastIf;
uint8_t lastEp;
PluggableUSBModule* rootNode;
};
int PUSB_GetDescriptor(int8_t t); // Replacement for global singleton.
// This function prevents static-initialization-order-fiasco
bool PUSB_Setup(USBSetup& setup, uint8_t i); // https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
PluggableUSB_& PluggableUSB();
#endif #endif

View File

@ -296,7 +296,7 @@ bool USBD_ClassInterfaceRequest(USBSetup& setup)
#endif #endif
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
return PUSB_Setup(setup, i); return PluggableUSB().setup(setup);
#endif #endif
return false; return false;
@ -311,7 +311,7 @@ int USBD_SendInterfaces(void)
#endif #endif
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
PUSB_GetInterface(&interfaces); PluggableUSB().getInterface(&interfaces);
#endif #endif
TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);) TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);)
@ -327,7 +327,7 @@ int USBD_SendOtherInterfaces(void)
#endif #endif
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
PUSB_GetInterface(&interfaces); PluggableUSB().getInterface(&interfaces);
#endif #endif
TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);) TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);)
@ -399,7 +399,7 @@ static bool USBD_SendDescriptor(USBSetup& setup)
USBD_InitControl(setup.wLength); USBD_InitControl(setup.wLength);
#ifdef PLUGGABLE_USB_ENABLED #ifdef PLUGGABLE_USB_ENABLED
ret = PUSB_GetDescriptor(t); ret = PluggableUSB().getDescriptor(setup);
if (ret != 0) { if (ret != 0) {
return (ret > 0 ? true : false); return (ret > 0 ? true : false);
} }

View File

@ -46,8 +46,9 @@
#define REQUEST_OTHER 0x03 #define REQUEST_OTHER 0x03
#define REQUEST_RECIPIENT 0x1F #define REQUEST_RECIPIENT 0x1F
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE) #define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE) #define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
#define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
// Class requests // Class requests
@ -91,6 +92,8 @@
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) #define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) #define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
#define USB_ENDPOINTS 7
#define USB_ENDPOINT_TYPE_MASK 0x03 #define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00 #define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01