From 3fe6272feba8bf57c21c853205299ac35972b8a6 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 29 Sep 2015 16:40:27 +0200 Subject: [PATCH 01/22] [PUSB] PUSBCallback struct has been merged into PUSBListNode This slightly simplifies PluggableUSB API. --- .../arduino/avr/cores/arduino/PluggableUSB.cpp | 16 ++++++++-------- .../arduino/avr/cores/arduino/PluggableUSB.h | 9 +++------ hardware/arduino/avr/libraries/HID/HID.cpp | 18 +++++++----------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 857a27fe9d7..9597adc948f 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -40,7 +40,7 @@ int PUSB_GetInterface(u8* interfaceNum) int ret = 0; PUSBListNode* node = rootNode; for (u8 i=0; icb->getInterface(interfaceNum); + ret = node->getInterface(interfaceNum); node = node->next; } return ret; @@ -51,7 +51,7 @@ int PUSB_GetDescriptor(int8_t t) int ret = 0; PUSBListNode* node = rootNode; for (u8 i=0; icb->getDescriptor(t); + ret = node->getDescriptor(t); node = node->next; } return ret; @@ -62,7 +62,7 @@ bool PUSB_Setup(USBSetup& setup, u8 j) bool ret = false; PUSBListNode* node = rootNode; for (u8 i=0; icb->setup(setup, j); + ret = node->setup(setup, j); node = node->next; } return ret; @@ -85,16 +85,16 @@ int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface) } *interface = lastIf; - lastIf += node->cb->numInterfaces; - for ( u8 i = 0; i< node->cb->numEndpoints; i++) { - _initEndpoints[lastEp] = node->cb->endpointType[i]; + lastIf += node->numInterfaces; + for ( u8 i = 0; i< node->numEndpoints; i++) { + _initEndpoints[lastEp] = node->endpointType[i]; lastEp++; } modules_count++; - return lastEp - node->cb->numEndpoints; + return lastEp - node->numEndpoints; // restart USB layer??? } #endif -#endif /* if defined(USBCON) */ \ No newline at end of file +#endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 33108db91a0..9210d7c6d00 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -25,21 +25,18 @@ #if defined(USBCON) -typedef struct __attribute__((packed)) -{ +class PUSBListNode { +public: + PUSBListNode() { } 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 *next = NULL; - PUSBCallbacks *cb; - PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;} }; int8_t PUSB_AddFunction(PUSBListNode *node, u8 *interface); diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 42e0ee5d202..24e6f5c60c3 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -133,19 +133,15 @@ bool HID_Setup(USBSetup& setup, uint8_t i) HID_::HID_(void) { static uint8_t endpointType[1]; - endpointType[0] = EP_TYPE_INTERRUPT_IN; - static PUSBCallbacks cb = { - .setup = &HID_Setup, - .getInterface = &HID_GetInterface, - .getDescriptor = &HID_GetDescriptor, - .numEndpoints = 1, - .numInterfaces = 1, - .endpointType = endpointType, - }; - - static PUSBListNode node(&cb); + static PUSBListNode node; + node.setup = &HID_Setup, + node.getInterface = &HID_GetInterface, + node.getDescriptor = &HID_GetDescriptor, + node.numEndpoints = 1, + node.numInterfaces = 1, + node.endpointType = endpointType, HID_ENDPOINT_INT = PUSB_AddFunction(&node, &HID_INTERFACE); } From 5aeff8ec25ed5dfc16bcfcf52e3ddfac4cb9aa8c Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 29 Sep 2015 16:46:11 +0200 Subject: [PATCH 02/22] [PUSB] Global functions PUSB_* are now methods of PluggableUSB class --- .../arduino/avr/cores/arduino/PluggableUSB.cpp | 8 ++++---- hardware/arduino/avr/cores/arduino/PluggableUSB.h | 14 ++++++++------ hardware/arduino/avr/cores/arduino/USBCore.cpp | 6 +++--- hardware/arduino/avr/libraries/HID/HID.cpp | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 9597adc948f..9dc334e812a 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -35,7 +35,7 @@ static u8 modules_count = 0; static PUSBListNode* rootNode = NULL; -int PUSB_GetInterface(u8* interfaceNum) +int PluggableUSB_::getInterface(u8* interfaceNum) { int ret = 0; PUSBListNode* node = rootNode; @@ -46,7 +46,7 @@ int PUSB_GetInterface(u8* interfaceNum) return ret; } -int PUSB_GetDescriptor(int8_t t) +int PluggableUSB_::getDescriptor(int8_t t) { int ret = 0; PUSBListNode* node = rootNode; @@ -57,7 +57,7 @@ int PUSB_GetDescriptor(int8_t t) return ret; } -bool PUSB_Setup(USBSetup& setup, u8 j) +bool PluggableUSB_::setup(USBSetup& setup, u8 j) { bool ret = false; PUSBListNode* node = rootNode; @@ -68,7 +68,7 @@ bool PUSB_Setup(USBSetup& setup, u8 j) return ret; } -int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface) +int8_t PluggableUSB_::addFunction(PUSBListNode *node, u8* interface) { if (modules_count >= MAX_MODULES) { return 0; diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 9210d7c6d00..dcd9e25994b 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -39,13 +39,15 @@ class PUSBListNode { PUSBListNode *next = NULL; }; -int8_t PUSB_AddFunction(PUSBListNode *node, u8 *interface); - -int PUSB_GetInterface(u8* interfaceNum); - -int PUSB_GetDescriptor(int8_t t); +class PluggableUSB_ { +public: + static int8_t addFunction(PUSBListNode *node, u8 *interface); + static int getInterface(u8* interfaceNum); + static int getDescriptor(int8_t t); + static bool setup(USBSetup& setup, u8 i); +}; -bool PUSB_Setup(USBSetup& setup, u8 i); +extern PluggableUSB_ PluggableUSB; #endif diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index 733a178c909..f96ff27abc8 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -367,7 +367,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; } @@ -445,7 +445,7 @@ static u8 SendInterfaces() CDC_GetInterface(&interfaces); #ifdef PLUGGABLE_USB_ENABLED - PUSB_GetInterface(&interfaces); + PluggableUSB.getInterface(&interfaces); #endif return interfaces; @@ -481,7 +481,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); } diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 24e6f5c60c3..ec284242604 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -143,7 +143,7 @@ HID_::HID_(void) node.numInterfaces = 1, node.endpointType = endpointType, - HID_ENDPOINT_INT = PUSB_AddFunction(&node, &HID_INTERFACE); + HID_ENDPOINT_INT = PluggableUSB.addFunction(&node, &HID_INTERFACE); } int HID_::begin(void) From 5e14b1fe37ac74d892b326e57a06a43a3c0b8727 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 29 Sep 2015 17:10:48 +0200 Subject: [PATCH 03/22] [HID] Now HID extends directly PluggableUSBListNode This avoid duplicate instatiation of callback and save a considerable amount of flash. --- hardware/arduino/avr/libraries/HID/HID.cpp | 22 ++++++++++------------ hardware/arduino/avr/libraries/HID/HID.h | 3 ++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index ec284242604..06587114a19 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -36,6 +36,8 @@ HIDDescriptor _hidInterface; static HIDDescriptorListNode* rootNode = NULL; static uint16_t sizeof_hidReportDescriptor = 0; static uint8_t modules_count = 0; +static uint8_t epType[] = { EP_TYPE_INTERRUPT_IN }; + //================================================================================ //================================================================================ // Driver @@ -132,18 +134,14 @@ bool HID_Setup(USBSetup& setup, uint8_t i) HID_::HID_(void) { - static uint8_t endpointType[1]; - endpointType[0] = EP_TYPE_INTERRUPT_IN; - - static PUSBListNode node; - node.setup = &HID_Setup, - node.getInterface = &HID_GetInterface, - node.getDescriptor = &HID_GetDescriptor, - node.numEndpoints = 1, - node.numInterfaces = 1, - node.endpointType = endpointType, - - HID_ENDPOINT_INT = PluggableUSB.addFunction(&node, &HID_INTERFACE); + setup = &HID_Setup; + getInterface = &HID_GetInterface; + getDescriptor = &HID_GetDescriptor; + numEndpoints = 1; + numInterfaces = 1; + endpointType = epType; + + HID_ENDPOINT_INT = PluggableUSB.addFunction(this, &HID_INTERFACE); } int HID_::begin(void) diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index 47ac3b9679a..b7ad457c810 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -24,6 +24,7 @@ #include #include +#include "PluggableUSB.h" #if defined(USBCON) @@ -53,7 +54,7 @@ class HIDDescriptorListNode { uint16_t length; }; -class HID_ +class HID_ : public PUSBListNode { public: HID_(void); From 8f259c8a80d528b5cd4375998904357127188c16 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 29 Sep 2015 17:59:54 +0200 Subject: [PATCH 04/22] [PUSB] Selected interface and endpoint are now part of PUSBListNode The method int8_t PluggableUSB::addFunction(PUSBListNode *, uint8_t *) has been changed to bool PluggableUSB::plug(PUSBListNode *node) since both EP and Interfaces are now saved directly into node --- .../arduino/avr/cores/arduino/PluggableUSB.cpp | 11 ++++++----- .../arduino/avr/cores/arduino/PluggableUSB.h | 11 ++++++++++- hardware/arduino/avr/libraries/HID/HID.cpp | 16 ++++++---------- hardware/arduino/avr/libraries/HID/HID.h | 2 -- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 9dc334e812a..b27146b5fe2 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -68,10 +68,10 @@ bool PluggableUSB_::setup(USBSetup& setup, u8 j) return ret; } -int8_t PluggableUSB_::addFunction(PUSBListNode *node, u8* interface) +bool PluggableUSB_::plug(PUSBListNode *node) { if (modules_count >= MAX_MODULES) { - return 0; + return false; } if (modules_count == 0) { @@ -84,14 +84,15 @@ int8_t PluggableUSB_::addFunction(PUSBListNode *node, u8* interface) current->next = node; } - *interface = lastIf; + node->pluggedInterface = lastIf; + node->pluggedEndpoint = lastEp; lastIf += node->numInterfaces; - for ( u8 i = 0; i< node->numEndpoints; i++) { + for (uint8_t i=0; inumEndpoints; i++) { _initEndpoints[lastEp] = node->endpointType[i]; lastEp++; } modules_count++; - return lastEp - node->numEndpoints; + return true; // restart USB layer??? } diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index dcd9e25994b..275a444a3ea 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -35,13 +35,22 @@ class PUSBListNode { int8_t numInterfaces; uint8_t *endpointType; + inline uint8_t interface() const { return pluggedInterface; } + inline int8_t endpoint() const { return pluggedEndpoint; } + +protected: + uint8_t pluggedInterface; + int8_t pluggedEndpoint; + public: PUSBListNode *next = NULL; + + friend class PluggableUSB_; }; class PluggableUSB_ { public: - static int8_t addFunction(PUSBListNode *node, u8 *interface); + static bool plug(PUSBListNode *node); static int getInterface(u8* interfaceNum); static int getDescriptor(int8_t t); static bool setup(USBSetup& setup, u8 i); diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 06587114a19..7e4d9916210 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -23,14 +23,10 @@ HID_ HID; -static uint8_t HID_ENDPOINT_INT; - //================================================================================ //================================================================================ // HID Interface -static uint8_t HID_INTERFACE; - HIDDescriptor _hidInterface; static HIDDescriptorListNode* rootNode = NULL; @@ -50,9 +46,9 @@ int HID_GetInterface(uint8_t* interfaceNum) interfaceNum[0] += 1; // uses 1 _hidInterface = { - D_INTERFACE(HID_INTERFACE,1,3,0,0), + D_INTERFACE(HID.interface(), 1, 3, 0, 0), D_HIDREPORT(sizeof_hidReportDescriptor), - D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,USB_EP_SIZE,0x01) + D_ENDPOINT(USB_ENDPOINT_IN(HID.endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) }; return USB_SendControl(0,&_hidInterface,sizeof(_hidInterface)); } @@ -89,13 +85,13 @@ void HID_::AppendDescriptor(HIDDescriptorListNode *node) void HID_::SendReport(u8 id, const void* data, int len) { - USB_Send(HID_TX, &id, 1); - USB_Send(HID_TX | TRANSFER_RELEASE,data,len); + USB_Send(HID.endpoint(), &id, 1); + USB_Send(HID.endpoint() | TRANSFER_RELEASE,data,len); } bool HID_Setup(USBSetup& setup, uint8_t i) { - if (HID_INTERFACE != i) { + if (HID.interface() != i) { return false; } else { uint8_t r = setup.bRequest; @@ -141,7 +137,7 @@ HID_::HID_(void) numInterfaces = 1; endpointType = epType; - HID_ENDPOINT_INT = PluggableUSB.addFunction(this, &HID_INTERFACE); + PluggableUSB.plug(this); } int HID_::begin(void) diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index b7ad457c810..d0fe265b583 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -83,8 +83,6 @@ typedef struct EndpointDescriptor in; } HIDDescriptor; -#define HID_TX HID_ENDPOINT_INT - #define D_HIDREPORT(_descriptorLength) \ { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength & 0xFF, _descriptorLength >> 8 } From 6ffd7e39ba7e0bddfa8a44c41ca477096eb3052a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 14:51:11 +0200 Subject: [PATCH 05/22] [PUSB] replaced u8 with uint8_t --- .../arduino/avr/cores/arduino/PluggableUSB.cpp | 18 +++++++++--------- .../arduino/avr/cores/arduino/PluggableUSB.h | 8 ++++---- hardware/arduino/avr/libraries/HID/HID.cpp | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index b27146b5fe2..2c7221de284 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -25,21 +25,21 @@ #define MAX_MODULES 6 -static u8 lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT; -static u8 lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT; +static uint8_t lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT; +static uint8_t lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT; -extern u8 _initEndpoints[]; +extern uint8_t _initEndpoints[]; //PUSBCallbacks cbs[MAX_MODULES]; -static u8 modules_count = 0; +static uint8_t modules_count = 0; static PUSBListNode* rootNode = NULL; -int PluggableUSB_::getInterface(u8* interfaceNum) +int PluggableUSB_::getInterface(uint8_t* interfaceNum) { int ret = 0; PUSBListNode* node = rootNode; - for (u8 i=0; igetInterface(interfaceNum); node = node->next; } @@ -50,18 +50,18 @@ int PluggableUSB_::getDescriptor(int8_t t) { int ret = 0; PUSBListNode* node = rootNode; - for (u8 i=0; igetDescriptor(t); node = node->next; } return ret; } -bool PluggableUSB_::setup(USBSetup& setup, u8 j) +bool PluggableUSB_::setup(USBSetup& setup, uint8_t j) { bool ret = false; PUSBListNode* node = rootNode; - for (u8 i=0; isetup(setup, j); node = node->next; } diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 275a444a3ea..d4a109633c0 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -28,8 +28,8 @@ class PUSBListNode { public: PUSBListNode() { } - bool (*setup)(USBSetup& setup, u8 i); - int (*getInterface)(u8* interfaceNum); + bool (*setup)(USBSetup& setup, uint8_t i); + int (*getInterface)(uint8_t* interfaceNum); int (*getDescriptor)(int8_t t); int8_t numEndpoints; int8_t numInterfaces; @@ -51,9 +51,9 @@ class PUSBListNode { class PluggableUSB_ { public: static bool plug(PUSBListNode *node); - static int getInterface(u8* interfaceNum); + static int getInterface(uint8_t* interfaceNum); static int getDescriptor(int8_t t); - static bool setup(USBSetup& setup, u8 i); + static bool setup(USBSetup& setup, uint8_t i); }; extern PluggableUSB_ PluggableUSB; diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 7e4d9916210..e36601f3d0d 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -83,7 +83,7 @@ void HID_::AppendDescriptor(HIDDescriptorListNode *node) sizeof_hidReportDescriptor += (uint16_t)node->length; } -void HID_::SendReport(u8 id, const void* data, int len) +void HID_::SendReport(uint8_t id, const void* data, int len) { USB_Send(HID.endpoint(), &id, 1); USB_Send(HID.endpoint() | TRANSFER_RELEASE,data,len); From 2ac2a27173b43b9594af2a888da2fde8f9cde74e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 16:19:21 +0200 Subject: [PATCH 06/22] [PUSB] Moved static members inside HID_ class This commit prepares for the next refactoring --- hardware/arduino/avr/libraries/HID/HID.cpp | 38 +++++++-------- hardware/arduino/avr/libraries/HID/HID.h | 57 +++++++++++++--------- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index e36601f3d0d..118d0c5f45b 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -27,33 +27,33 @@ HID_ HID; //================================================================================ // HID Interface -HIDDescriptor _hidInterface; +HIDDescriptor HID_::hidInterface; -static HIDDescriptorListNode* rootNode = NULL; -static uint16_t sizeof_hidReportDescriptor = 0; -static uint8_t modules_count = 0; -static uint8_t epType[] = { EP_TYPE_INTERRUPT_IN }; +HIDDescriptorListNode* HID_::rootNode = NULL; +uint16_t HID_::sizeof_hidReportDescriptor = 0; +uint8_t HID_::modules_count = 0; +uint8_t HID_::epType[] = { EP_TYPE_INTERRUPT_IN }; //================================================================================ //================================================================================ // Driver -uint8_t _hid_protocol = 1; -uint8_t _hid_idle = 1; +uint8_t HID_::protocol = 1; +uint8_t HID_::idle = 1; -int HID_GetInterface(uint8_t* interfaceNum) +int HID_::GetInterface(uint8_t* interfaceNum) { interfaceNum[0] += 1; // uses 1 - _hidInterface = + hidInterface = { D_INTERFACE(HID.interface(), 1, 3, 0, 0), D_HIDREPORT(sizeof_hidReportDescriptor), D_ENDPOINT(USB_ENDPOINT_IN(HID.endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) }; - return USB_SendControl(0,&_hidInterface,sizeof(_hidInterface)); + return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); } -int HID_GetDescriptor(int8_t t) +int HID_::GetDescriptor(int8_t t) { if (HID_REPORT_DESCRIPTOR_TYPE == t) { HIDDescriptorListNode* current = rootNode; @@ -89,7 +89,7 @@ void HID_::SendReport(uint8_t id, const void* data, int len) USB_Send(HID.endpoint() | TRANSFER_RELEASE,data,len); } -bool HID_Setup(USBSetup& setup, uint8_t i) +bool HID_::Setup(USBSetup& setup, uint8_t i) { if (HID.interface() != i) { return false; @@ -100,12 +100,12 @@ bool HID_Setup(USBSetup& setup, uint8_t i) { if (HID_GET_REPORT == r) { - //HID_GetReport(); + //HID_GetReport(); return true; } if (HID_GET_PROTOCOL == r) { - //Send8(_hid_protocol); // TODO + //Send8(protocol); // TODO return true; } } @@ -114,13 +114,13 @@ bool HID_Setup(USBSetup& setup, uint8_t i) { if (HID_SET_PROTOCOL == r) { - _hid_protocol = setup.wValueL; + protocol = setup.wValueL; return true; } if (HID_SET_IDLE == r) { - _hid_idle = setup.wValueL; + idle = setup.wValueL; return true; } } @@ -130,9 +130,9 @@ bool HID_Setup(USBSetup& setup, uint8_t i) HID_::HID_(void) { - setup = &HID_Setup; - getInterface = &HID_GetInterface; - getDescriptor = &HID_GetDescriptor; + setup = HID_::Setup; + getInterface = HID_::GetInterface; + getDescriptor = HID_::GetDescriptor; numEndpoints = 1; numInterfaces = 1; endpointType = epType; diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index d0fe265b583..cb1125efd1b 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -30,10 +30,8 @@ #define _USING_HID -//================================================================================ -//================================================================================ -// HID 'Driver' - +// HID 'Driver' +// ------------ #define HID_GET_REPORT 0x01 #define HID_GET_IDLE 0x02 #define HID_GET_PROTOCOL 0x03 @@ -45,24 +43,6 @@ #define HID_REPORT_DESCRIPTOR_TYPE 0x22 #define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 -class HIDDescriptorListNode { -public: - HIDDescriptorListNode *next = NULL; - HIDDescriptorListNode(const void *d, const uint16_t l) : data(d), length(l) { } - - const void* data; - uint16_t length; -}; - -class HID_ : public PUSBListNode -{ -public: - HID_(void); - int begin(void); - void SendReport(uint8_t id, const void* data, int len); - void AppendDescriptor(HIDDescriptorListNode* node); -}; - typedef struct { uint8_t len; // 9 @@ -83,6 +63,39 @@ typedef struct EndpointDescriptor in; } HIDDescriptor; +class HIDDescriptorListNode { +public: + HIDDescriptorListNode *next = NULL; + HIDDescriptorListNode(const void *d, const uint16_t l) : data(d), length(l) { } + + const void* data; + uint16_t length; +}; + +class HID_ : public PUSBListNode +{ +public: + HID_(void); + int begin(void); + void SendReport(uint8_t id, const void* data, int len); + void AppendDescriptor(HIDDescriptorListNode* node); + +private: + static int GetInterface(uint8_t* interfaceNum); + static int GetDescriptor(int8_t t); + static bool Setup(USBSetup& setup, uint8_t i); + + static HIDDescriptor hidInterface; + + static HIDDescriptorListNode* rootNode; + static uint16_t sizeof_hidReportDescriptor; + static uint8_t modules_count; + static uint8_t epType[]; + + static uint8_t protocol; + static uint8_t idle; +}; + #define D_HIDREPORT(_descriptorLength) \ { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength & 0xFF, _descriptorLength >> 8 } From 0dfa815ce4ea76b7e558e389fb229de0dfa1cfe5 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 16:35:43 +0200 Subject: [PATCH 07/22] [PUSB] callbacks are now pure virtual methods This change allows the compiler to handle callbacks resolution. Callbacks now must be implemented on the class that extends PUSBListNode and this is forced by compiler by means of pure virtual methods. Also the calls to HID.interface() and HID.endpoint() can now be simplified to interface() and endpoint() respectively since the methods are no more static. --- .../arduino/avr/cores/arduino/PluggableUSB.h | 7 ++++--- hardware/arduino/avr/libraries/HID/HID.cpp | 19 ++++++++----------- hardware/arduino/avr/libraries/HID/HID.h | 10 ++++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index d4a109633c0..c08bc9992ac 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -28,9 +28,6 @@ class PUSBListNode { public: PUSBListNode() { } - bool (*setup)(USBSetup& setup, uint8_t i); - int (*getInterface)(uint8_t* interfaceNum); - int (*getDescriptor)(int8_t t); int8_t numEndpoints; int8_t numInterfaces; uint8_t *endpointType; @@ -39,6 +36,10 @@ class PUSBListNode { inline int8_t endpoint() const { return pluggedEndpoint; } protected: + virtual bool setup(USBSetup& setup, uint8_t i) = 0; + virtual int getInterface(uint8_t* interfaceNum) = 0; + virtual int getDescriptor(int8_t t) = 0; + uint8_t pluggedInterface; int8_t pluggedEndpoint; diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 118d0c5f45b..5685957269a 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -41,19 +41,19 @@ uint8_t HID_::epType[] = { EP_TYPE_INTERRUPT_IN }; uint8_t HID_::protocol = 1; uint8_t HID_::idle = 1; -int HID_::GetInterface(uint8_t* interfaceNum) +int HID_::getInterface(uint8_t* interfaceNum) { interfaceNum[0] += 1; // uses 1 hidInterface = { - D_INTERFACE(HID.interface(), 1, 3, 0, 0), + D_INTERFACE(interface(), 1, 3, 0, 0), D_HIDREPORT(sizeof_hidReportDescriptor), - D_ENDPOINT(USB_ENDPOINT_IN(HID.endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) + D_ENDPOINT(USB_ENDPOINT_IN(endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) }; return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); } -int HID_::GetDescriptor(int8_t t) +int HID_::getDescriptor(int8_t t) { if (HID_REPORT_DESCRIPTOR_TYPE == t) { HIDDescriptorListNode* current = rootNode; @@ -85,13 +85,13 @@ void HID_::AppendDescriptor(HIDDescriptorListNode *node) void HID_::SendReport(uint8_t id, const void* data, int len) { - USB_Send(HID.endpoint(), &id, 1); - USB_Send(HID.endpoint() | TRANSFER_RELEASE,data,len); + USB_Send(endpoint(), &id, 1); + USB_Send(endpoint() | TRANSFER_RELEASE,data,len); } -bool HID_::Setup(USBSetup& setup, uint8_t i) +bool HID_::setup(USBSetup& setup, uint8_t i) { - if (HID.interface() != i) { + if (interface() != i) { return false; } else { uint8_t r = setup.bRequest; @@ -130,9 +130,6 @@ bool HID_::Setup(USBSetup& setup, uint8_t i) HID_::HID_(void) { - setup = HID_::Setup; - getInterface = HID_::GetInterface; - getDescriptor = HID_::GetDescriptor; numEndpoints = 1; numInterfaces = 1; endpointType = epType; diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index cb1125efd1b..1c8e2fcfe31 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -80,11 +80,13 @@ class HID_ : public PUSBListNode void SendReport(uint8_t id, const void* data, int len); void AppendDescriptor(HIDDescriptorListNode* node); -private: - static int GetInterface(uint8_t* interfaceNum); - static int GetDescriptor(int8_t t); - static bool Setup(USBSetup& setup, uint8_t i); +protected: + // Implementation of the PUSBListNode + int getInterface(uint8_t* interfaceNum); + int getDescriptor(int8_t t); + bool setup(USBSetup& setup, uint8_t i); +private: static HIDDescriptor hidInterface; static HIDDescriptorListNode* rootNode; From 0369b8ec333482b63b16ba47608f5cca75ac974f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 16:48:11 +0200 Subject: [PATCH 08/22] [PUSB] The latest fields are now set via constructor --- hardware/arduino/avr/cores/arduino/PluggableUSB.h | 11 +++++++---- hardware/arduino/avr/libraries/HID/HID.cpp | 7 ++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index c08bc9992ac..0f776c080dc 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -27,10 +27,9 @@ class PUSBListNode { public: - PUSBListNode() { } - int8_t numEndpoints; - int8_t numInterfaces; - uint8_t *endpointType; + 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; } @@ -43,6 +42,10 @@ class PUSBListNode { uint8_t pluggedInterface; int8_t pluggedEndpoint; + const int8_t numEndpoints; + const int8_t numInterfaces; + const uint8_t *endpointType; + public: PUSBListNode *next = NULL; diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 5685957269a..d358f451258 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -128,12 +128,9 @@ bool HID_::setup(USBSetup& setup, uint8_t i) } } -HID_::HID_(void) +HID_::HID_(void) : PUSBListNode(1, 1, epType) { - numEndpoints = 1; - numInterfaces = 1; - endpointType = epType; - + // XXX: Shall this be done in PUSBListNode(...) constructor? PluggableUSB.plug(this); } From 2d70691dbe714f2e1b10edaa5ec577bfff5efff5 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 17:13:54 +0200 Subject: [PATCH 09/22] [HID] Removed static fields in HID class There is still the epType[] array to be handled in some way. --- hardware/arduino/avr/libraries/HID/HID.cpp | 26 ++++++---------------- hardware/arduino/avr/libraries/HID/HID.h | 13 +++++------ 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index d358f451258..10cd5a6a8f5 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -23,24 +23,6 @@ HID_ HID; -//================================================================================ -//================================================================================ -// HID Interface - -HIDDescriptor HID_::hidInterface; - -HIDDescriptorListNode* HID_::rootNode = NULL; -uint16_t HID_::sizeof_hidReportDescriptor = 0; -uint8_t HID_::modules_count = 0; -uint8_t HID_::epType[] = { EP_TYPE_INTERRUPT_IN }; - -//================================================================================ -//================================================================================ -// Driver - -uint8_t HID_::protocol = 1; -uint8_t HID_::idle = 1; - int HID_::getInterface(uint8_t* interfaceNum) { interfaceNum[0] += 1; // uses 1 @@ -128,7 +110,13 @@ bool HID_::setup(USBSetup& setup, uint8_t i) } } -HID_::HID_(void) : PUSBListNode(1, 1, epType) +// XXX: I've found no way to pass literal value directly in +// the PUSBListNode constructor +static uint8_t epTypeDef[] = { EP_TYPE_INTERRUPT_IN }; + +HID_::HID_(void) : PUSBListNode(1, 1, epTypeDef), + rootNode(NULL), sizeof_hidReportDescriptor(0), + modules_count(0), protocol(1), idle(1) { // XXX: Shall this be done in PUSBListNode(...) constructor? PluggableUSB.plug(this); diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index 1c8e2fcfe31..bff51bb1153 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -87,15 +87,14 @@ class HID_ : public PUSBListNode bool setup(USBSetup& setup, uint8_t i); private: - static HIDDescriptor hidInterface; + HIDDescriptor hidInterface; - static HIDDescriptorListNode* rootNode; - static uint16_t sizeof_hidReportDescriptor; - static uint8_t modules_count; - static uint8_t epType[]; + HIDDescriptorListNode* rootNode; + uint16_t sizeof_hidReportDescriptor; + uint8_t modules_count; - static uint8_t protocol; - static uint8_t idle; + uint8_t protocol; + uint8_t idle; }; #define D_HIDREPORT(_descriptorLength) \ From 9acbbe63c0ab001de8d375a3573bf5ff3e43f507 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 18:45:09 +0200 Subject: [PATCH 10/22] [PUSB] epType array is now part of HID class --- hardware/arduino/avr/libraries/HID/HID.cpp | 8 ++------ hardware/arduino/avr/libraries/HID/HID.h | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 10cd5a6a8f5..a8714157d42 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -110,15 +110,11 @@ bool HID_::setup(USBSetup& setup, uint8_t i) } } -// XXX: I've found no way to pass literal value directly in -// the PUSBListNode constructor -static uint8_t epTypeDef[] = { EP_TYPE_INTERRUPT_IN }; - -HID_::HID_(void) : PUSBListNode(1, 1, epTypeDef), +HID_::HID_(void) : PUSBListNode(1, 1, epType), rootNode(NULL), sizeof_hidReportDescriptor(0), modules_count(0), protocol(1), idle(1) { - // XXX: Shall this be done in PUSBListNode(...) constructor? + epType[0] = EP_TYPE_INTERRUPT_IN; PluggableUSB.plug(this); } diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index bff51bb1153..9e6e67542f9 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -88,6 +88,7 @@ class HID_ : public PUSBListNode private: HIDDescriptor hidInterface; + uint8_t epType[1]; HIDDescriptorListNode* rootNode; uint16_t sizeof_hidReportDescriptor; From 183ec1c83f87e80a788cda915597abfe713eb74d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 19:04:01 +0200 Subject: [PATCH 11/22] [PUSB] No more static fields in PluggableUSB class --- .../avr/cores/arduino/PluggableUSB.cpp | 25 +++++++++++-------- .../arduino/avr/cores/arduino/PluggableUSB.h | 15 ++++++++--- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 2c7221de284..a8c69d4e274 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -25,21 +25,17 @@ #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 uint8_t _initEndpoints[]; //PUSBCallbacks cbs[MAX_MODULES]; -static uint8_t modules_count = 0; -static PUSBListNode* rootNode = NULL; +PluggableUSB_ PluggableUSB; int PluggableUSB_::getInterface(uint8_t* interfaceNum) { int ret = 0; PUSBListNode* node = rootNode; - for (uint8_t i=0; igetInterface(interfaceNum); node = node->next; } @@ -50,7 +46,7 @@ int PluggableUSB_::getDescriptor(int8_t t) { int ret = 0; PUSBListNode* node = rootNode; - for (uint8_t i=0; igetDescriptor(t); node = node->next; } @@ -61,7 +57,7 @@ bool PluggableUSB_::setup(USBSetup& setup, uint8_t j) { bool ret = false; PUSBListNode* node = rootNode; - for (uint8_t i=0; isetup(setup, j); node = node->next; } @@ -70,11 +66,11 @@ bool PluggableUSB_::setup(USBSetup& setup, uint8_t j) bool PluggableUSB_::plug(PUSBListNode *node) { - if (modules_count >= MAX_MODULES) { + if (modulesCount >= MAX_MODULES) { return false; } - if (modules_count == 0) { + if (modulesCount == 0) { rootNode = node; } else { PUSBListNode *current = rootNode; @@ -91,11 +87,18 @@ bool PluggableUSB_::plug(PUSBListNode *node) _initEndpoints[lastEp] = node->endpointType[i]; lastEp++; } - modules_count++; + modulesCount++; return true; // restart USB layer??? } +PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), + lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), + modulesCount(0), rootNode(NULL) +{ + // Empty +} + #endif #endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 0f776c080dc..93ee15ce5a7 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -54,10 +54,17 @@ class PUSBListNode { class PluggableUSB_ { public: - static bool plug(PUSBListNode *node); - static int getInterface(uint8_t* interfaceNum); - static int getDescriptor(int8_t t); - static bool setup(USBSetup& setup, uint8_t i); + PluggableUSB_(); + bool plug(PUSBListNode *node); + int getInterface(uint8_t* interfaceNum); + int getDescriptor(int8_t t); + bool setup(USBSetup& setup, uint8_t i); + +private: + uint8_t lastIf; + uint8_t lastEp; + uint8_t modulesCount; + PUSBListNode* rootNode; }; extern PluggableUSB_ PluggableUSB; From e823ef0c16a0977f0fbe6c0e9ac0a4b59f303a4b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 19:30:23 +0200 Subject: [PATCH 12/22] [PUSB] Fixed check for available endpoints The check for available slot in PluggableUSB is done on the endpoint and not on the number of plugged modules. The modulesCount field is no longer useful and it has been removed. --- .../avr/cores/arduino/PluggableUSB.cpp | 45 +++++++++---------- .../arduino/avr/cores/arduino/PluggableUSB.h | 1 - 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index a8c69d4e274..5a53eb17072 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -23,58 +23,56 @@ #if defined(USBCON) #ifdef PLUGGABLE_USB_ENABLED -#define MAX_MODULES 6 +// TODO: set correct value for different CPUs +#define MAX_EP 6 extern uint8_t _initEndpoints[]; -//PUSBCallbacks cbs[MAX_MODULES]; - PluggableUSB_ PluggableUSB; int PluggableUSB_::getInterface(uint8_t* interfaceNum) { int ret = 0; - PUSBListNode* node = rootNode; - for (uint8_t i=0; inext) { ret = node->getInterface(interfaceNum); - node = node->next; } return ret; } int PluggableUSB_::getDescriptor(int8_t t) { - int ret = 0; - PUSBListNode* node = rootNode; - for (uint8_t i=0; igetDescriptor(t); - node = node->next; + PUSBListNode* node; + for (node = rootNode; node; node = node->next) { + int ret = node->getDescriptor(t); + if (ret) + return ret; } - return ret; + return 0; } bool PluggableUSB_::setup(USBSetup& setup, uint8_t j) { - bool ret = false; - PUSBListNode* node = rootNode; - for (uint8_t i=0; isetup(setup, j); - node = node->next; + PUSBListNode* node; + for (node = rootNode; node; node = node->next) { + if (node->setup(setup, j)) { + return true; + } } - return ret; + return false; } bool PluggableUSB_::plug(PUSBListNode *node) { - if (modulesCount >= MAX_MODULES) { + if ((lastEp + node->numEndpoints) >= MAX_EP) { return false; } - if (modulesCount == 0) { + if (!rootNode) { rootNode = node; } else { PUSBListNode *current = rootNode; - while(current->next != NULL) { + while (current->next) { current = current->next; } current->next = node; @@ -83,18 +81,17 @@ bool PluggableUSB_::plug(PUSBListNode *node) node->pluggedInterface = lastIf; node->pluggedEndpoint = lastEp; lastIf += node->numInterfaces; - for (uint8_t i=0; inumEndpoints; i++) { + for (uint8_t i = 0; i < node->numEndpoints; i++) { _initEndpoints[lastEp] = node->endpointType[i]; lastEp++; } - modulesCount++; return true; // restart USB layer??? } PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), - modulesCount(0), rootNode(NULL) + rootNode(NULL) { // Empty } diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 93ee15ce5a7..824440a9c3e 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -63,7 +63,6 @@ class PluggableUSB_ { private: uint8_t lastIf; uint8_t lastEp; - uint8_t modulesCount; PUSBListNode* rootNode; }; From d1f0c6953af72f4d82e45bc38ebfbd5f2b48cb46 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 20:52:00 +0200 Subject: [PATCH 13/22] [PUSB] Fixed the correct number of endpoints --- .../arduino/avr/cores/arduino/PluggableUSB.cpp | 5 +---- hardware/arduino/avr/cores/arduino/USBCore.cpp | 17 ++++++----------- hardware/arduino/avr/cores/arduino/USBDesc.h | 5 +++++ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 5a53eb17072..50fd79825c2 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -23,9 +23,6 @@ #if defined(USBCON) #ifdef PLUGGABLE_USB_ENABLED -// TODO: set correct value for different CPUs -#define MAX_EP 6 - extern uint8_t _initEndpoints[]; PluggableUSB_ PluggableUSB; @@ -64,7 +61,7 @@ bool PluggableUSB_::setup(USBSetup& setup, uint8_t j) bool PluggableUSB_::plug(PUSBListNode *node) { - if ((lastEp + node->numEndpoints) >= MAX_EP) { + if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) { return false; } diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index f96ff27abc8..ebdce361fa7 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -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 diff --git a/hardware/arduino/avr/cores/arduino/USBDesc.h b/hardware/arduino/avr/cores/arduino/USBDesc.h index 1962727ca66..528a7fd51b5 100644 --- a/hardware/arduino/avr/cores/arduino/USBDesc.h +++ b/hardware/arduino/avr/cores/arduino/USBDesc.h @@ -18,6 +18,11 @@ #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 From 1851fcc23c75e148dc6e165194c7295373146388 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 30 Sep 2015 20:53:05 +0200 Subject: [PATCH 14/22] [USB] Fixed some compiler warnings --- hardware/arduino/avr/cores/arduino/USBCore.h | 6 +++--- hardware/arduino/avr/libraries/HID/HID.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/USBCore.h b/hardware/arduino/avr/cores/arduino/USBCore.h index eaeecef82ce..806fa6028ce 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.h +++ b/hardware/arduino/avr/cores/arduino/USBCore.h @@ -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 @@ -277,4 +277,4 @@ typedef struct #define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } -#endif \ No newline at end of file +#endif diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index 9e6e67542f9..f951229f871 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -98,8 +98,7 @@ class HID_ : public PUSBListNode uint8_t idle; }; -#define D_HIDREPORT(_descriptorLength) \ - { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength & 0xFF, _descriptorLength >> 8 } +#define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) } #define WEAK __attribute__ ((weak)) From 8a5ad75c501027c15e645f50bb533f3c64109354 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 1 Oct 2015 12:35:24 +0200 Subject: [PATCH 15/22] [PUSB] Fixed checks on return values --- .../avr/cores/arduino/PluggableUSB.cpp | 14 ++++++++----- hardware/arduino/avr/libraries/HID/HID.cpp | 20 +++++++++++-------- hardware/arduino/avr/libraries/HID/HID.h | 4 ++-- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 50fd79825c2..acc62765279 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -29,19 +29,23 @@ PluggableUSB_ PluggableUSB; int PluggableUSB_::getInterface(uint8_t* interfaceNum) { - int ret = 0; + int sent = 0; PUSBListNode* node; for (node = rootNode; node; node = node->next) { - ret = node->getInterface(interfaceNum); + int res = node->getInterface(interfaceNum); + if (res == -1) + return -1; + sent += res; } - return ret; + return sent; } -int PluggableUSB_::getDescriptor(int8_t t) +int PluggableUSB_::getDescriptor(int8_t type) { PUSBListNode* node; for (node = rootNode; node; node = node->next) { - int ret = node->getDescriptor(t); + int ret = node->getDescriptor(type); + // ret!=0 -> request has been processed if (ret) return ret; } diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index a8714157d42..a109574299a 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -35,19 +35,23 @@ int HID_::getInterface(uint8_t* interfaceNum) return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); } -int HID_::getDescriptor(int8_t t) +int HID_::getDescriptor(int8_t type) { - if (HID_REPORT_DESCRIPTOR_TYPE == t) { + if (HID_REPORT_DESCRIPTOR_TYPE == type) { HIDDescriptorListNode* current = rootNode; int total = 0; - while(current != NULL) { - total += USB_SendControl(TRANSFER_PGM,current->data,current->length); + while (current != NULL) { + int res = USB_SendControl(TRANSFER_PGM, current->data, current->length); + if (res == -1) + return -1; + total += res; current = current->next; } return total; - } else { - return 0; } + + // Ignored + return 0; } void HID_::AppendDescriptor(HIDDescriptorListNode *node) @@ -71,9 +75,9 @@ void HID_::SendReport(uint8_t id, const void* data, int len) USB_Send(endpoint() | TRANSFER_RELEASE,data,len); } -bool HID_::setup(USBSetup& setup, uint8_t i) +bool HID_::setup(USBSetup& setup, uint8_t interfaceNum) { - if (interface() != i) { + if (interface() != interfaceNum) { return false; } else { uint8_t r = setup.bRequest; diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index f951229f871..ed08cf0512d 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -83,8 +83,8 @@ class HID_ : public PUSBListNode protected: // Implementation of the PUSBListNode int getInterface(uint8_t* interfaceNum); - int getDescriptor(int8_t t); - bool setup(USBSetup& setup, uint8_t i); + int getDescriptor(int8_t type); + bool setup(USBSetup& setup, uint8_t interfaceNum); private: HIDDescriptor hidInterface; From 81aa7df09353ff8f6152a6906516a3ed357d9793 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 1 Oct 2015 12:39:57 +0200 Subject: [PATCH 16/22] [HID] removed unused modules_count field --- hardware/arduino/avr/libraries/HID/HID.cpp | 5 ++--- hardware/arduino/avr/libraries/HID/HID.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index a109574299a..3a439f07352 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -56,7 +56,7 @@ int HID_::getDescriptor(int8_t type) void HID_::AppendDescriptor(HIDDescriptorListNode *node) { - if (modules_count == 0) { + if (!rootNode) { rootNode = node; } else { HIDDescriptorListNode *current = rootNode; @@ -65,7 +65,6 @@ void HID_::AppendDescriptor(HIDDescriptorListNode *node) } current->next = node; } - modules_count++; sizeof_hidReportDescriptor += (uint16_t)node->length; } @@ -116,7 +115,7 @@ bool HID_::setup(USBSetup& setup, uint8_t interfaceNum) HID_::HID_(void) : PUSBListNode(1, 1, epType), rootNode(NULL), sizeof_hidReportDescriptor(0), - modules_count(0), protocol(1), idle(1) + protocol(1), idle(1) { epType[0] = EP_TYPE_INTERRUPT_IN; PluggableUSB.plug(this); diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index ed08cf0512d..c6f9ab51864 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -92,7 +92,6 @@ class HID_ : public PUSBListNode HIDDescriptorListNode* rootNode; uint16_t sizeof_hidReportDescriptor; - uint8_t modules_count; uint8_t protocol; uint8_t idle; From 214b260a82235c87649cce12cbf4f9b30c629e77 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 1 Oct 2015 12:50:18 +0200 Subject: [PATCH 17/22] [HID] Code cleanup (no semantic changes) --- hardware/arduino/avr/cores/arduino/USBDesc.h | 34 +++--- hardware/arduino/avr/libraries/HID/HID.cpp | 113 +++++++++---------- hardware/arduino/avr/libraries/HID/HID.h | 35 +++--- 3 files changed, 86 insertions(+), 96 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/USBDesc.h b/hardware/arduino/avr/cores/arduino/USBDesc.h index 528a7fd51b5..4b9cf6636ec 100644 --- a/hardware/arduino/avr/cores/arduino/USBDesc.h +++ b/hardware/arduino/avr/cores/arduino/USBDesc.h @@ -1,20 +1,20 @@ - - -/* 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 diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 3a439f07352..574af6ba387 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -1,20 +1,20 @@ -/* Copyright (c) 2015, Arduino LLC -** -** Original code (pre-library): 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) 2015, Arduino LLC + Original code (pre-library): 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. + */ #include "PluggableUSB.h" #include "HID.h" @@ -25,11 +25,10 @@ HID_ HID; int HID_::getInterface(uint8_t* interfaceNum) { - interfaceNum[0] += 1; // uses 1 - hidInterface = - { + *interfaceNum += 1; // uses 1 + hidInterface = { D_INTERFACE(interface(), 1, 3, 0, 0), - D_HIDREPORT(sizeof_hidReportDescriptor), + D_HIDREPORT(descriptorSize), D_ENDPOINT(USB_ENDPOINT_IN(endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) }; return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); @@ -38,14 +37,13 @@ int HID_::getInterface(uint8_t* interfaceNum) int HID_::getDescriptor(int8_t type) { if (HID_REPORT_DESCRIPTOR_TYPE == type) { - HIDDescriptorListNode* current = rootNode; int total = 0; - while (current != NULL) { - int res = USB_SendControl(TRANSFER_PGM, current->data, current->length); + HIDDescriptorListNode* node; + for (node = rootNode; node; node = node->next) { + int res = USB_SendControl(TRANSFER_PGM, node->data, node->length); if (res == -1) return -1; total += res; - current = current->next; } return total; } @@ -60,61 +58,58 @@ void HID_::AppendDescriptor(HIDDescriptorListNode *node) rootNode = node; } else { HIDDescriptorListNode *current = rootNode; - while(current->next != NULL) { + while (current->next) { current = current->next; } current->next = node; } - sizeof_hidReportDescriptor += (uint16_t)node->length; + descriptorSize += node->length; } void HID_::SendReport(uint8_t id, const void* data, int len) { USB_Send(endpoint(), &id, 1); - USB_Send(endpoint() | TRANSFER_RELEASE,data,len); + USB_Send(endpoint() | TRANSFER_RELEASE, data, len); } bool HID_::setup(USBSetup& setup, uint8_t interfaceNum) { if (interface() != interfaceNum) { return false; - } else { - uint8_t r = setup.bRequest; - uint8_t requestType = setup.bmRequestType; - if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) - { - if (HID_GET_REPORT == r) - { - //HID_GetReport(); - return true; - } - if (HID_GET_PROTOCOL == r) - { - //Send8(protocol); // TODO - return true; - } + } + + uint8_t request = setup.bRequest; + uint8_t requestType = setup.bmRequestType; + + if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) + { + if (request == HID_GET_REPORT) { + // TODO: HID_GetReport(); + return true; } - - if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) - { - if (HID_SET_PROTOCOL == r) - { - protocol = setup.wValueL; - return true; - } - - if (HID_SET_IDLE == r) - { - idle = setup.wValueL; - return true; - } + if (request == HID_GET_PROTOCOL) { + // TODO: Send8(protocol); + return true; + } + } + + if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE) + { + if (request == HID_SET_PROTOCOL) { + protocol = setup.wValueL; + return true; + } + if (request == HID_SET_IDLE) { + idle = setup.wValueL; + return true; } - return false; } + + return false; } HID_::HID_(void) : PUSBListNode(1, 1, epType), - rootNode(NULL), sizeof_hidReportDescriptor(0), + rootNode(NULL), descriptorSize(0), protocol(1), idle(1) { epType[0] = EP_TYPE_INTERRUPT_IN; diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index c6f9ab51864..d31d9c5ac22 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -1,23 +1,20 @@ /* - HID.h - Copyright (c) 2015, Arduino LLC Original code (pre-library): Copyright (c) 2011, Peter Barrett - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + 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. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + 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. + */ #ifndef HID_h #define HID_h @@ -91,7 +88,7 @@ class HID_ : public PUSBListNode uint8_t epType[1]; HIDDescriptorListNode* rootNode; - uint16_t sizeof_hidReportDescriptor; + uint16_t descriptorSize; uint8_t protocol; uint8_t idle; @@ -99,8 +96,6 @@ class HID_ : public PUSBListNode #define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) } -#define WEAK __attribute__ ((weak)) - -#endif +#endif // USBCON -#endif +#endif // HID_h From d13aadc7d54c352e36bac3bbc40a1bd95f3d66e4 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 1 Oct 2015 12:53:24 +0200 Subject: [PATCH 18/22] [HID] removed HIDDescriptor field The field is now built on-the-fly on the stack and sent over USB. This change increase Flash usage and decrease SRAM usage: before: 6114 / 241 after: 6152 / 216 (removed HIDDescriptor field) delta: +38 / -25 SRAM is a much more scarse resource and this change free up to about 10% of the "base" usage. --- hardware/arduino/avr/libraries/HID/HID.cpp | 2 +- hardware/arduino/avr/libraries/HID/HID.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 574af6ba387..b7aab6ceedc 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -26,7 +26,7 @@ HID_ HID; int HID_::getInterface(uint8_t* interfaceNum) { *interfaceNum += 1; // uses 1 - hidInterface = { + HIDDescriptor hidInterface = { D_INTERFACE(interface(), 1, 3, 0, 0), D_HIDREPORT(descriptorSize), D_ENDPOINT(USB_ENDPOINT_IN(endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index d31d9c5ac22..2cd0f4a0e93 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -84,7 +84,6 @@ class HID_ : public PUSBListNode bool setup(USBSetup& setup, uint8_t interfaceNum); private: - HIDDescriptor hidInterface; uint8_t epType[1]; HIDDescriptorListNode* rootNode; From 65b8430fece7a708be740089864835a862678cff Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 1 Oct 2015 17:35:26 +0200 Subject: [PATCH 19/22] [PUSB] Fix static initialization order fiasco For details see: https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use --- hardware/arduino/avr/cores/arduino/PluggableUSB.cpp | 8 ++++++-- hardware/arduino/avr/cores/arduino/PluggableUSB.h | 5 ++++- hardware/arduino/avr/cores/arduino/USBCore.cpp | 6 +++--- hardware/arduino/avr/libraries/HID/HID.cpp | 8 ++++++-- hardware/arduino/avr/libraries/HID/HID.h | 5 +++++ libraries/Keyboard/src/Keyboard.cpp | 4 ++-- libraries/Keyboard/src/Keyboard.h | 1 - libraries/Mouse/src/Mouse.cpp | 4 ++-- libraries/Mouse/src/Mouse.h | 1 - 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index acc62765279..582379a84ef 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -25,8 +25,6 @@ extern uint8_t _initEndpoints[]; -PluggableUSB_ PluggableUSB; - int PluggableUSB_::getInterface(uint8_t* interfaceNum) { int sent = 0; @@ -90,6 +88,12 @@ bool PluggableUSB_::plug(PUSBListNode *node) // 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) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 824440a9c3e..b0668f40e1f 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -66,7 +66,10 @@ class PluggableUSB_ { PUSBListNode* rootNode; }; -extern PluggableUSB_ PluggableUSB; +// 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 diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index ebdce361fa7..5db9f521a99 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -362,7 +362,7 @@ bool ClassInterfaceRequest(USBSetup& setup) return CDC_Setup(setup); #ifdef PLUGGABLE_USB_ENABLED - return PluggableUSB.setup(setup, i); + return PluggableUSB().setup(setup, i); #endif return false; } @@ -440,7 +440,7 @@ static u8 SendInterfaces() CDC_GetInterface(&interfaces); #ifdef PLUGGABLE_USB_ENABLED - PluggableUSB.getInterface(&interfaces); + PluggableUSB().getInterface(&interfaces); #endif return interfaces; @@ -476,7 +476,7 @@ bool SendDescriptor(USBSetup& setup) InitControl(setup.wLength); #ifdef PLUGGABLE_USB_ENABLED - ret = PluggableUSB.getDescriptor(t); + ret = PluggableUSB().getDescriptor(t); if (ret != 0) { return (ret > 0 ? true : false); } diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index b7aab6ceedc..ff8e67b2ddc 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -21,7 +21,11 @@ #if defined(USBCON) -HID_ HID; +HID_& HID() +{ + static HID_ obj; + return obj; +} int HID_::getInterface(uint8_t* interfaceNum) { @@ -113,7 +117,7 @@ HID_::HID_(void) : PUSBListNode(1, 1, epType), protocol(1), idle(1) { epType[0] = EP_TYPE_INTERRUPT_IN; - PluggableUSB.plug(this); + PluggableUSB().plug(this); } int HID_::begin(void) diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index 2cd0f4a0e93..a7f5c682fe9 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -93,6 +93,11 @@ class HID_ : public PUSBListNode uint8_t idle; }; +// Replacement for global singleton. +// This function prevents static-initialization-order-fiasco +// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use +HID_& HID(); + #define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) } #endif // USBCON diff --git a/libraries/Keyboard/src/Keyboard.cpp b/libraries/Keyboard/src/Keyboard.cpp index 2663e6e6280..d899e92e422 100644 --- a/libraries/Keyboard/src/Keyboard.cpp +++ b/libraries/Keyboard/src/Keyboard.cpp @@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = { Keyboard_::Keyboard_(void) { static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor)); - HID.AppendDescriptor(&node); + HID().AppendDescriptor(&node); } void Keyboard_::begin(void) @@ -76,7 +76,7 @@ void Keyboard_::end(void) void Keyboard_::sendReport(KeyReport* keys) { - HID.SendReport(2,keys,sizeof(KeyReport)); + HID().SendReport(2,keys,sizeof(KeyReport)); } extern diff --git a/libraries/Keyboard/src/Keyboard.h b/libraries/Keyboard/src/Keyboard.h index 1c728ae9e4c..8f173f31c35 100644 --- a/libraries/Keyboard/src/Keyboard.h +++ b/libraries/Keyboard/src/Keyboard.h @@ -94,7 +94,6 @@ class Keyboard_ : public Print void releaseAll(void); }; extern Keyboard_ Keyboard; -extern HID_ HID; #endif #endif diff --git a/libraries/Mouse/src/Mouse.cpp b/libraries/Mouse/src/Mouse.cpp index 0cb5b2908fb..64d02bc86c6 100644 --- a/libraries/Mouse/src/Mouse.cpp +++ b/libraries/Mouse/src/Mouse.cpp @@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = { Mouse_::Mouse_(void) : _buttons(0) { static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor)); - HID.AppendDescriptor(&node); + HID().AppendDescriptor(&node); } void Mouse_::begin(void) @@ -89,7 +89,7 @@ void Mouse_::move(signed char x, signed char y, signed char wheel) m[1] = x; m[2] = y; m[3] = wheel; - HID.SendReport(1,m,4); + HID().SendReport(1,m,4); } void Mouse_::buttons(uint8_t b) diff --git a/libraries/Mouse/src/Mouse.h b/libraries/Mouse/src/Mouse.h index 3ab57a5eb1c..2672b5c932a 100644 --- a/libraries/Mouse/src/Mouse.h +++ b/libraries/Mouse/src/Mouse.h @@ -55,7 +55,6 @@ class Mouse_ bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default }; extern Mouse_ Mouse; -extern HID_ HID; #endif #endif \ No newline at end of file From 7fdb0efc985c009f521595188d0d1649765b3cfd Mon Sep 17 00:00:00 2001 From: NicoHood Date: Sat, 3 Oct 2015 07:56:48 +0200 Subject: [PATCH 20/22] Removed not needed public statement for root node --- hardware/arduino/avr/cores/arduino/PluggableUSB.h | 1 - 1 file changed, 1 deletion(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index b0668f40e1f..40a898ec09d 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -46,7 +46,6 @@ class PUSBListNode { const int8_t numInterfaces; const uint8_t *endpointType; -public: PUSBListNode *next = NULL; friend class PluggableUSB_; From 8bc21f7e36c740bb55b7d16cbeae46559b952854 Mon Sep 17 00:00:00 2001 From: NicoHood Date: Sat, 3 Oct 2015 08:16:40 +0200 Subject: [PATCH 21/22] Small return value error check correction --- hardware/arduino/avr/cores/arduino/PluggableUSB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 582379a84ef..7125775d842 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -31,7 +31,7 @@ int PluggableUSB_::getInterface(uint8_t* interfaceNum) PUSBListNode* node; for (node = rootNode; node; node = node->next) { int res = node->getInterface(interfaceNum); - if (res == -1) + if (res < 0) return -1; sent += res; } From 5b1b0330b212f772537582bd048109cde6e30777 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 7 Oct 2015 13:21:21 +0200 Subject: [PATCH 22/22] [PUSB] renamed some parameters --- hardware/arduino/avr/cores/arduino/PluggableUSB.cpp | 8 ++++---- hardware/arduino/avr/cores/arduino/PluggableUSB.h | 10 +++++----- hardware/arduino/avr/libraries/HID/HID.cpp | 4 ++-- hardware/arduino/avr/libraries/HID/HID.h | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 7125775d842..95d40791c13 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -25,12 +25,12 @@ extern uint8_t _initEndpoints[]; -int PluggableUSB_::getInterface(uint8_t* interfaceNum) +int PluggableUSB_::getInterface(uint8_t* interfaceCount) { int sent = 0; PUSBListNode* node; for (node = rootNode; node; node = node->next) { - int res = node->getInterface(interfaceNum); + int res = node->getInterface(interfaceCount); if (res < 0) return -1; sent += res; @@ -50,11 +50,11 @@ int PluggableUSB_::getDescriptor(int8_t type) return 0; } -bool PluggableUSB_::setup(USBSetup& setup, uint8_t j) +bool PluggableUSB_::setup(USBSetup& setup, uint8_t interfaceNum) { PUSBListNode* node; for (node = rootNode; node; node = node->next) { - if (node->setup(setup, j)) { + if (node->setup(setup, interfaceNum)) { return true; } } diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 40a898ec09d..433e23efd09 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -35,8 +35,8 @@ class PUSBListNode { inline int8_t endpoint() const { return pluggedEndpoint; } protected: - virtual bool setup(USBSetup& setup, uint8_t i) = 0; - virtual int getInterface(uint8_t* interfaceNum) = 0; + 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; @@ -55,9 +55,9 @@ class PluggableUSB_ { public: PluggableUSB_(); bool plug(PUSBListNode *node); - int getInterface(uint8_t* interfaceNum); - int getDescriptor(int8_t t); - bool setup(USBSetup& setup, uint8_t i); + int getInterface(uint8_t* interfaceCount); + int getDescriptor(int8_t type); + bool setup(USBSetup& setup, uint8_t interfaceNum); private: uint8_t lastIf; diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index ff8e67b2ddc..b6b9ceadc1a 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -27,9 +27,9 @@ HID_& HID() return obj; } -int HID_::getInterface(uint8_t* interfaceNum) +int HID_::getInterface(uint8_t* interfaceCount) { - *interfaceNum += 1; // uses 1 + *interfaceCount += 1; // uses 1 HIDDescriptor hidInterface = { D_INTERFACE(interface(), 1, 3, 0, 0), D_HIDREPORT(descriptorSize), diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index a7f5c682fe9..e54e45e1957 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -79,7 +79,7 @@ class HID_ : public PUSBListNode protected: // Implementation of the PUSBListNode - int getInterface(uint8_t* interfaceNum); + int getInterface(uint8_t* interfaceCount); int getDescriptor(int8_t type); bool setup(USBSetup& setup, uint8_t interfaceNum);