Skip to content

Commit 02945cc

Browse files
committed
[PluggableUSB] port to stable API
1 parent 87bbaaa commit 02945cc

File tree

7 files changed

+266
-247
lines changed

7 files changed

+266
-247
lines changed

Diff for: 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

Diff for: cores/arduino/USB/PluggableUSB.h

+35-26
Original file line numberDiff line numberDiff line change
@@ -25,38 +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-
typedef struct
39-
{
40-
uint8_t interface;
41-
uint8_t firstEndpoint;
42-
} PUSBReturn;
43-
44-
class PUSBListNode {
28+
class PluggableUSBModule {
4529
public:
46-
PUSBListNode *next = NULL;
47-
PUSBCallbacks *cb;
48-
PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;}
49-
};
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;
5041

51-
int8_t PUSB_AddFunction(PUSBListNode *node, uint8_t *interface);
42+
const uint8_t numEndpoints;
43+
const uint8_t numInterfaces;
44+
const uint32_t *endpointType;
5245

53-
int PUSB_GetInterface(uint8_t* interfaceNum);
46+
PluggableUSBModule *next = NULL;
5447

55-
int PUSB_GetDescriptor(int8_t t);
48+
friend class PluggableUSB_;
49+
};
5650

57-
bool PUSB_Setup(USBSetup& setup, uint8_t i);
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);
58+
59+
private:
60+
uint8_t lastIf;
61+
uint8_t lastEp;
62+
PluggableUSBModule* rootNode;
63+
};
5864

59-
void PUSB_Begin();
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();
6069

6170
#endif
6271

Diff for: cores/arduino/USB/USBAPI.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class USBDeviceClass {
7878
bool sendStringDescriptor(const uint8_t *string, uint8_t maxlen);
7979
void initControl(int end);
8080
uint8_t SendInterfaces(uint32_t* total);
81+
void packMessages(bool val);
8182

8283
// Generic EndPoint API
8384
void initEndpoints(void);
@@ -100,8 +101,6 @@ class USBDeviceClass {
100101
void ISRHandler();
101102

102103
private:
103-
void packMessages(bool val);
104-
105104
bool initialized;
106105
};
107106

Diff for: cores/arduino/USB/USBCore.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ volatile uint32_t _usbConfiguration = 0;
7575
volatile uint32_t _usbSetInterface = 0;
7676

7777
static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0")))
78-
uint8_t udd_ep_out_cache_buffer[6][64];
78+
uint8_t udd_ep_out_cache_buffer[7][64];
7979

8080
static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0")))
81-
uint8_t udd_ep_in_cache_buffer[6][64];
81+
uint8_t udd_ep_in_cache_buffer[7][64];
8282

8383
//==================================================================
8484

@@ -129,7 +129,7 @@ uint8_t USBDeviceClass::SendInterfaces(uint32_t* total)
129129
#endif
130130

131131
#ifdef PLUGGABLE_USB_ENABLED
132-
total[0] += PUSB_GetInterface(&interfaces);
132+
total[0] += PluggableUSB().getInterface(&interfaces);
133133
#endif
134134

135135
return interfaces;
@@ -180,7 +180,7 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup)
180180
}
181181

182182
#ifdef PLUGGABLE_USB_ENABLED
183-
ret = PUSB_GetDescriptor(t);
183+
ret = PluggableUSB().getDescriptor(setup);
184184
if (ret != 0) {
185185
return (ret > 0 ? true : false);
186186
}
@@ -360,7 +360,7 @@ bool USBDeviceClass::handleClassInterfaceSetup(USBSetup& setup)
360360
#endif
361361

362362
#if defined(PLUGGABLE_USB_ENABLED)
363-
bool ret = PUSB_Setup(setup, i);
363+
bool ret = PluggableUSB().setup(setup);
364364
if ( ret == false) {
365365
sendZlp(0);
366366
}

Diff for: cores/arduino/USB/USBCore.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
3737
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
3838

39+
#define USB_ENDPOINTS 7
40+
3941
#define USB_ENDPOINT_TYPE_MASK 0x03
4042
#define USB_ENDPOINT_TYPE_CONTROL 0x00
4143
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
@@ -58,9 +60,9 @@
5860
#define REQUEST_OTHER 0x03
5961
#define REQUEST_RECIPIENT 0x1F
6062

61-
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE)
62-
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE)
63-
63+
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
64+
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
65+
#define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
6466
// Class requests
6567

6668
#define CDC_SET_LINE_CODING 0x20

0 commit comments

Comments
 (0)