aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino/PluggableUSB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cores/arduino/PluggableUSB.cpp')
-rw-r--r--cores/arduino/PluggableUSB.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/cores/arduino/PluggableUSB.cpp b/cores/arduino/PluggableUSB.cpp
new file mode 100644
index 0000000..c489d9f
--- /dev/null
+++ b/cores/arduino/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) */