Skip to content

Commit b454120

Browse files
committed
adapt SAM core to PluggableUSB stable API
1 parent 865ac2f commit b454120

File tree

4 files changed

+97
-68
lines changed

4 files changed

+97
-68
lines changed

hardware/arduino/sam/cores/arduino/USB/PluggableUSB.cpp

+52-43
Original file line numberDiff line numberDiff line change
@@ -19,80 +19,89 @@
1919

2020
#include "USBAPI.h"
2121
#include "USBDesc.h"
22+
#include "USBCore.h"
2223
#include "PluggableUSB.h"
2324

25+
#if defined(USBCON)
2426
#ifdef PLUGGABLE_USB_ENABLED
2527

26-
#define MAX_MODULES 6
27-
28-
static uint8_t lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT;
29-
static uint8_t lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT;
30-
3128
extern uint32_t EndPoints[];
3229

33-
//PUSBCallbacks cbs[MAX_MODULES];
34-
static uint8_t modules_count = 0;
35-
36-
static PUSBListNode* rootNode = NULL;
37-
38-
int PUSB_GetInterface(uint8_t* interfaceNum)
30+
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
3931
{
40-
int ret = 0;
41-
PUSBListNode* node = rootNode;
42-
for (uint8_t i=0; i<modules_count; i++) {
43-
ret = node->cb->getInterface(interfaceNum);
44-
node = node->next;
32+
int sent = 0;
33+
PluggableUSBModule* node;
34+
for (node = rootNode; node; node = node->next) {
35+
int res = node->getInterface(interfaceCount);
36+
if (res < 0)
37+
return -1;
38+
sent += res;
4539
}
46-
return ret;
40+
return sent;
4741
}
4842

49-
int PUSB_GetDescriptor(int8_t t)
43+
int PluggableUSB_::getDescriptor(USBSetup& setup)
5044
{
51-
int ret = 0;
52-
PUSBListNode* node = rootNode;
53-
for (uint8_t i=0; i<modules_count && ret == 0; i++) {
54-
ret = node->cb->getDescriptor(t);
55-
node = node->next;
45+
PluggableUSBModule* node;
46+
for (node = rootNode; node; node = node->next) {
47+
int ret = node->getDescriptor(setup);
48+
// ret!=0 -> request has been processed
49+
if (ret)
50+
return ret;
5651
}
57-
return ret;
52+
return 0;
5853
}
5954

60-
bool PUSB_Setup(USBSetup& setup, uint8_t j)
55+
bool PluggableUSB_::setup(USBSetup& setup)
6156
{
62-
bool ret = false;
63-
PUSBListNode* node = rootNode;
64-
for (uint8_t i=0; i<modules_count && ret == false; i++) {
65-
ret = node->cb->setup(setup, j);
66-
node = node->next;
57+
PluggableUSBModule* node;
58+
for (node = rootNode; node; node = node->next) {
59+
if (node->setup(setup)) {
60+
return true;
61+
}
6762
}
68-
return ret;
63+
return false;
6964
}
7065

71-
int8_t PUSB_AddFunction(PUSBListNode *node, uint8_t* interface)
66+
bool PluggableUSB_::plug(PluggableUSBModule *node)
7267
{
73-
if (modules_count >= MAX_MODULES) {
74-
return 0;
68+
if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) {
69+
return false;
7570
}
7671

77-
if (modules_count == 0) {
72+
if (!rootNode) {
7873
rootNode = node;
7974
} else {
80-
PUSBListNode *current = rootNode;
81-
while(current->next != NULL) {
75+
PluggableUSBModule *current = rootNode;
76+
while (current->next) {
8277
current = current->next;
8378
}
8479
current->next = node;
8580
}
8681

87-
*interface = lastIf;
88-
lastIf += node->cb->numInterfaces;
89-
for ( uint8_t i = 0; i< node->cb->numEndpoints; i++) {
90-
EndPoints[lastEp] = node->cb->endpointType[i];
82+
node->pluggedInterface = lastIf;
83+
node->pluggedEndpoint = lastEp;
84+
lastIf += node->numInterfaces;
85+
for (uint8_t i = 0; i < node->numEndpoints; i++) {
86+
EndPoints[lastEp] = node->endpointType[i];
9187
lastEp++;
9288
}
93-
modules_count++;
94-
return lastEp - node->cb->numEndpoints;
89+
return true;
9590
// restart USB layer???
9691
}
9792

93+
PluggableUSB_& PluggableUSB()
94+
{
95+
static PluggableUSB_ obj;
96+
return obj;
97+
}
98+
99+
PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT),
100+
lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT),
101+
rootNode(NULL)
102+
{
103+
// Empty
104+
}
105+
106+
#endif
98107
#endif

hardware/arduino/sam/cores/arduino/USB/PluggableUSB.h

+36-19
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,47 @@
2525

2626
#if defined(USBCON)
2727

28-
typedef struct __attribute__((packed))
29-
{
30-
bool (*setup)(USBSetup& setup, uint8_t i);
31-
int (*getInterface)(uint8_t* interfaceNum);
32-
int (*getDescriptor)(int8_t t);
33-
int8_t numEndpoints;
34-
int8_t numInterfaces;
35-
uint32_t *endpointType;
36-
} PUSBCallbacks;
37-
38-
class PUSBListNode {
28+
class PluggableUSBModule {
3929
public:
40-
PUSBListNode *next = NULL;
41-
PUSBCallbacks *cb;
42-
PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;}
43-
};
30+
PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint32_t *epType) :
31+
numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
32+
{ }
33+
34+
protected:
35+
virtual bool setup(USBSetup& setup) = 0;
36+
virtual int getInterface(uint8_t* interfaceCount) = 0;
37+
virtual int getDescriptor(USBSetup& setup) = 0;
38+
39+
uint8_t pluggedInterface;
40+
uint8_t pluggedEndpoint;
41+
42+
const uint8_t numEndpoints;
43+
const uint8_t numInterfaces;
44+
const uint32_t *endpointType;
4445

45-
int8_t PUSB_AddFunction(PUSBListNode *node, uint8_t *interface);
46+
PluggableUSBModule *next = NULL;
4647

47-
int PUSB_GetInterface(uint8_t* interfaceNum);
48+
friend class PluggableUSB_;
49+
};
50+
51+
class PluggableUSB_ {
52+
public:
53+
PluggableUSB_();
54+
bool plug(PluggableUSBModule *node);
55+
int getInterface(uint8_t* interfaceCount);
56+
int getDescriptor(USBSetup& setup);
57+
bool setup(USBSetup& setup);
4858

49-
int PUSB_GetDescriptor(int8_t t);
59+
private:
60+
uint8_t lastIf;
61+
uint8_t lastEp;
62+
PluggableUSBModule* rootNode;
63+
};
5064

51-
bool PUSB_Setup(USBSetup& setup, uint8_t i);
65+
// Replacement for global singleton.
66+
// This function prevents static-initialization-order-fiasco
67+
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
68+
PluggableUSB_& PluggableUSB();
5269

5370
#endif
5471

hardware/arduino/sam/cores/arduino/USB/USBCore.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ bool USBD_ClassInterfaceRequest(USBSetup& setup)
296296
#endif
297297

298298
#ifdef PLUGGABLE_USB_ENABLED
299-
return PUSB_Setup(setup, i);
299+
return PluggableUSB().setup(setup);
300300
#endif
301301

302302
return false;
@@ -311,7 +311,7 @@ int USBD_SendInterfaces(void)
311311
#endif
312312

313313
#ifdef PLUGGABLE_USB_ENABLED
314-
PUSB_GetInterface(&interfaces);
314+
PluggableUSB().getInterface(&interfaces);
315315
#endif
316316

317317
TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);)
@@ -327,7 +327,7 @@ int USBD_SendOtherInterfaces(void)
327327
#endif
328328

329329
#ifdef PLUGGABLE_USB_ENABLED
330-
PUSB_GetInterface(&interfaces);
330+
PluggableUSB().getInterface(&interfaces);
331331
#endif
332332

333333
TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);)
@@ -399,7 +399,7 @@ static bool USBD_SendDescriptor(USBSetup& setup)
399399
USBD_InitControl(setup.wLength);
400400

401401
#ifdef PLUGGABLE_USB_ENABLED
402-
ret = PUSB_GetDescriptor(t);
402+
ret = PluggableUSB().getDescriptor(setup);
403403
if (ret != 0) {
404404
return (ret > 0 ? true : false);
405405
}

hardware/arduino/sam/cores/arduino/USB/USBCore.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@
4646
#define REQUEST_OTHER 0x03
4747
#define REQUEST_RECIPIENT 0x1F
4848

49-
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE)
50-
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE)
49+
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
50+
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
51+
#define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
5152

5253
// Class requests
5354

@@ -91,6 +92,8 @@
9192
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
9293
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
9394

95+
#define USB_ENDPOINTS 7
96+
9497
#define USB_ENDPOINT_TYPE_MASK 0x03
9598
#define USB_ENDPOINT_TYPE_CONTROL 0x00
9699
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01

0 commit comments

Comments
 (0)