diff options
Diffstat (limited to 'cores/xinput/PluggableUSB.cpp')
-rw-r--r-- | cores/xinput/PluggableUSB.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/cores/xinput/PluggableUSB.cpp b/cores/xinput/PluggableUSB.cpp new file mode 100644 index 0000000..c489d9f --- /dev/null +++ b/cores/xinput/PluggableUSB.cpp @@ -0,0 +1,115 @@ +/* + PluggableUSB.cpp + Copyright (c) 2015 Arduino LLC + + 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. + + 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 +*/ + +#include "USBAPI.h" +#include "PluggableUSB.h" + +#if defined(USBCON) +#ifdef PLUGGABLE_USB_ENABLED + +extern uint8_t _initEndpoints[]; + +int PluggableUSB_::getInterface(uint8_t* interfaceCount) +{ + int sent = 0; + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + int res = node->getInterface(interfaceCount); + if (res < 0) + return -1; + sent += res; + } + return sent; +} + +int PluggableUSB_::getDescriptor(USBSetup& setup) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + int ret = node->getDescriptor(setup); + // ret!=0 -> request has been processed + if (ret) + return ret; + } + return 0; +} + +void PluggableUSB_::getShortName(char *iSerialNum) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + iSerialNum += node->getShortName(iSerialNum); + } + *iSerialNum = 0; +} + +bool PluggableUSB_::setup(USBSetup& setup) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + if (node->setup(setup)) { + return true; + } + } + return false; +} + +bool PluggableUSB_::plug(PluggableUSBModule *node) +{ + if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) { + return false; + } + + if (!rootNode) { + rootNode = node; + } else { + PluggableUSBModule *current = rootNode; + while (current->next) { + current = current->next; + } + current->next = node; + } + + node->pluggedInterface = lastIf; + node->pluggedEndpoint = lastEp; + lastIf += node->numInterfaces; + for (uint8_t i = 0; i < node->numEndpoints; i++) { + _initEndpoints[lastEp] = node->endpointType[i]; + lastEp++; + } + 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) */ |