1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-17 11:54:33 +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 "USBDesc.h"
#include "USBCore.h"
#include "PluggableUSB.h"
#if defined(USBCON)
#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[];
//PUSBCallbacks cbs[MAX_MODULES];
static uint8_t modules_count = 0;
static PUSBListNode* rootNode = NULL;
int PUSB_GetInterface(uint8_t* interfaceNum)
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
{
int ret = 0;
PUSBListNode* node = rootNode;
for (uint8_t i=0; i<modules_count; i++) {
ret = node->cb->getInterface(interfaceNum);
node = node->next;
int sent = 0;
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
int res = node->getInterface(interfaceCount);
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;
PUSBListNode* node = rootNode;
for (uint8_t i=0; i<modules_count && ret == 0; i++) {
ret = node->cb->getDescriptor(t);
node = node->next;
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
int ret = node->getDescriptor(setup);
// ret!=0 -> request has been processed
if (ret)
return ret;
}
return ret;
return 0;
}
bool PUSB_Setup(USBSetup& setup, uint8_t j)
bool PluggableUSB_::setup(USBSetup& setup)
{
bool ret = false;
PUSBListNode* node = rootNode;
for (uint8_t i=0; i<modules_count && ret == false; i++) {
ret = node->cb->setup(setup, j);
node = node->next;
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
if (node->setup(setup)) {
return true;
}
}
return ret;
return false;
}
int8_t PUSB_AddFunction(PUSBListNode *node, uint8_t* interface)
bool PluggableUSB_::plug(PluggableUSBModule *node)
{
if (modules_count >= MAX_MODULES) {
return 0;
if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) {
return false;
}
if (modules_count == 0) {
if (!rootNode) {
rootNode = node;
} else {
PUSBListNode *current = rootNode;
while(current->next != NULL) {
PluggableUSBModule *current = rootNode;
while (current->next) {
current = current->next;
}
current->next = node;
}
*interface = lastIf;
lastIf += node->cb->numInterfaces;
for ( uint8_t i = 0; i< node->cb->numEndpoints; i++) {
EndPoints[lastEp] = node->cb->endpointType[i];
node->pluggedInterface = lastIf;
node->pluggedEndpoint = lastEp;
lastIf += node->numInterfaces;
for (uint8_t i = 0; i < node->numEndpoints; i++) {
EndPoints[lastEp] = node->endpointType[i];
lastEp++;
}
modules_count++;
return lastEp - node->cb->numEndpoints;
return true;
// 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

View File

@ -25,30 +25,47 @@
#if defined(USBCON)
typedef struct __attribute__((packed))
{
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 {
class PluggableUSBModule {
public:
PUSBListNode *next = NULL;
PUSBCallbacks *cb;
PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;}
PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint32_t *epType) :
numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
{ }
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);
bool PUSB_Setup(USBSetup& setup, uint8_t i);
// Replacement for global singleton.
// This function prevents static-initialization-order-fiasco
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
PluggableUSB_& PluggableUSB();
#endif

View File

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

View File

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