Skip to content

[PluggableHID] 2nd round of API improvement (WIP) #3896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Oct 7, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3fe6272
[PUSB] PUSBCallback struct has been merged into PUSBListNode
cmaglie Sep 29, 2015
5aeff8e
[PUSB] Global functions PUSB_* are now methods of PluggableUSB class
cmaglie Sep 29, 2015
5e14b1f
[HID] Now HID extends directly PluggableUSBListNode
cmaglie Sep 29, 2015
8f259c8
[PUSB] Selected interface and endpoint are now part of PUSBListNode
cmaglie Sep 29, 2015
6ffd7e3
[PUSB] replaced u8 with uint8_t
cmaglie Sep 30, 2015
2ac2a27
[PUSB] Moved static members inside HID_ class
cmaglie Sep 30, 2015
0dfa815
[PUSB] callbacks are now pure virtual methods
cmaglie Sep 30, 2015
0369b8e
[PUSB] The latest fields are now set via constructor
cmaglie Sep 30, 2015
2d70691
[HID] Removed static fields in HID class
cmaglie Sep 30, 2015
9acbbe6
[PUSB] epType array is now part of HID class
cmaglie Sep 30, 2015
183ec1c
[PUSB] No more static fields in PluggableUSB class
cmaglie Sep 30, 2015
e823ef0
[PUSB] Fixed check for available endpoints
cmaglie Sep 30, 2015
d1f0c69
[PUSB] Fixed the correct number of endpoints
cmaglie Sep 30, 2015
1851fcc
[USB] Fixed some compiler warnings
cmaglie Sep 30, 2015
8a5ad75
[PUSB] Fixed checks on return values
cmaglie Oct 1, 2015
81aa7df
[HID] removed unused modules_count field
cmaglie Oct 1, 2015
214b260
[HID] Code cleanup (no semantic changes)
cmaglie Oct 1, 2015
d13aadc
[HID] removed HIDDescriptor field
cmaglie Oct 1, 2015
65b8430
[PUSB] Fix static initialization order fiasco
facchinm Oct 1, 2015
7fdb0ef
Removed not needed public statement for root node
NicoHood Oct 3, 2015
8bc21f7
Small return value error check correction
NicoHood Oct 3, 2015
5b1b033
[PUSB] renamed some parameters
cmaglie Oct 7, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 50 additions & 44 deletions hardware/arduino/avr/cores/arduino/PluggableUSB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,78 +23,84 @@
#if defined(USBCON)
#ifdef PLUGGABLE_USB_ENABLED

#define MAX_MODULES 6
extern uint8_t _initEndpoints[];

static u8 lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT;
static u8 lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT;

extern u8 _initEndpoints[];

//PUSBCallbacks cbs[MAX_MODULES];
static u8 modules_count = 0;

static PUSBListNode* rootNode = NULL;

int PUSB_GetInterface(u8* interfaceNum)
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
{
int ret = 0;
PUSBListNode* node = rootNode;
for (u8 i=0; i<modules_count; i++) {
ret = node->cb->getInterface(interfaceNum);
node = node->next;
int sent = 0;
PUSBListNode* 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(int8_t type)
{
int ret = 0;
PUSBListNode* node = rootNode;
for (u8 i=0; i<modules_count && ret == 0; i++) {
ret = node->cb->getDescriptor(t);
node = node->next;
PUSBListNode* node;
for (node = rootNode; node; node = node->next) {
int ret = node->getDescriptor(type);
// ret!=0 -> request has been processed
if (ret)
return ret;
}
return ret;
return 0;
}

bool PUSB_Setup(USBSetup& setup, u8 j)
bool PluggableUSB_::setup(USBSetup& setup, uint8_t interfaceNum)
{
bool ret = false;
PUSBListNode* node = rootNode;
for (u8 i=0; i<modules_count && ret == false; i++) {
ret = node->cb->setup(setup, j);
node = node->next;
PUSBListNode* node;
for (node = rootNode; node; node = node->next) {
if (node->setup(setup, interfaceNum)) {
return true;
}
}
return ret;
return false;
}

int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface)
bool PluggableUSB_::plug(PUSBListNode *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) {
while (current->next) {
current = current->next;
}
current->next = node;
}

*interface = lastIf;
lastIf += node->cb->numInterfaces;
for ( u8 i = 0; i< node->cb->numEndpoints; i++) {
_initEndpoints[lastEp] = node->cb->endpointType[i];
node->pluggedInterface = lastIf;
node->pluggedEndpoint = lastEp;
lastIf += node->numInterfaces;
for (uint8_t i = 0; i < node->numEndpoints; i++) {
_initEndpoints[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 /* if defined(USBCON) */
#endif /* if defined(USBCON) */
54 changes: 37 additions & 17 deletions hardware/arduino/avr/cores/arduino/PluggableUSB.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,50 @@

#if defined(USBCON)

typedef struct __attribute__((packed))
{
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(int8_t numEps, int8_t numIfs, uint8_t *epType) :
numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
{ }

inline uint8_t interface() const { return pluggedInterface; }
inline int8_t endpoint() const { return pluggedEndpoint; }

protected:
virtual bool setup(USBSetup& setup, uint8_t interfaceNum) = 0;
virtual int getInterface(uint8_t* interfaceCount) = 0;
virtual int getDescriptor(int8_t t) = 0;

uint8_t pluggedInterface;
int8_t pluggedEndpoint;

const int8_t numEndpoints;
const int8_t numInterfaces;
const uint8_t *endpointType;

PUSBListNode *next = NULL;
PUSBCallbacks *cb;
PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;}
};

int8_t PUSB_AddFunction(PUSBListNode *node, u8 *interface);
friend class PluggableUSB_;
};

int PUSB_GetInterface(u8* interfaceNum);
class PluggableUSB_ {
public:
PluggableUSB_();
bool plug(PUSBListNode *node);
int getInterface(uint8_t* interfaceCount);
int getDescriptor(int8_t type);
bool setup(USBSetup& setup, uint8_t interfaceNum);

int PUSB_GetDescriptor(int8_t t);
private:
uint8_t lastIf;
uint8_t lastEp;
PUSBListNode* rootNode;
};

bool PUSB_Setup(USBSetup& setup, u8 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

Expand Down
23 changes: 9 additions & 14 deletions hardware/arduino/avr/cores/arduino/USBCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,20 +308,15 @@ int USB_Send(u8 ep, const void* d, int len)
return r;
}

u8 _initEndpoints[] =
u8 _initEndpoints[USB_ENDPOINTS] =
{
0,
0, // Control Endpoint

EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN

#ifdef PLUGGABLE_USB_ENABLED
//allocate 3 endpoints and remove const so they can be changed by the user
0,
0,
0,
#endif
// Following endpoints are automatically initialized to 0
};

#define EP_SINGLE_64 0x32 // EP0
Expand Down Expand Up @@ -367,7 +362,7 @@ bool ClassInterfaceRequest(USBSetup& setup)
return CDC_Setup(setup);

#ifdef PLUGGABLE_USB_ENABLED
return PUSB_Setup(setup, i);
return PluggableUSB().setup(setup, i);
#endif
return false;
}
Expand Down Expand Up @@ -445,7 +440,7 @@ static u8 SendInterfaces()
CDC_GetInterface(&interfaces);

#ifdef PLUGGABLE_USB_ENABLED
PUSB_GetInterface(&interfaces);
PluggableUSB().getInterface(&interfaces);
#endif

return interfaces;
Expand Down Expand Up @@ -481,7 +476,7 @@ bool SendDescriptor(USBSetup& setup)

InitControl(setup.wLength);
#ifdef PLUGGABLE_USB_ENABLED
ret = PUSB_GetDescriptor(t);
ret = PluggableUSB().getDescriptor(t);
if (ret != 0) {
return (ret > 0 ? true : false);
}
Expand Down
6 changes: 3 additions & 3 deletions hardware/arduino/avr/cores/arduino/USBCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@

// bEndpointAddress in Endpoint Descriptor
#define USB_ENDPOINT_DIRECTION_MASK 0x80
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
#define USB_ENDPOINT_OUT(addr) (lowByte((addr) | 0x00))
#define USB_ENDPOINT_IN(addr) (lowByte((addr) | 0x80))

#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
Expand Down Expand Up @@ -277,4 +277,4 @@ typedef struct
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }


#endif
#endif
39 changes: 22 additions & 17 deletions hardware/arduino/avr/cores/arduino/USBDesc.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@


/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
** SOFTWARE.
*/
/*
Copyright (c) 2011, Peter Barrett
Copyright (c) 2015, Arduino LLC

Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
*/

#define PLUGGABLE_USB_ENABLED

#if defined(EPRST6)
#define USB_ENDPOINTS 7 // AtMegaxxU4
#else
#define USB_ENDPOINTS 5 // AtMegaxxU2
#endif

#define CDC_INTERFACE_COUNT 2
#define CDC_ENPOINT_COUNT 3
Expand Down
Loading