]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/usb/common/core/USBDescriptors.c
SAMA5D3 demo: Add CDC driver code and use CDC to create a simple command console.
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / AtmelFiles / usb / common / core / USBDescriptors.c
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/usb/common/core/USBDescriptors.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/usb/common/core/USBDescriptors.c
new file mode 100644 (file)
index 0000000..110d3e0
--- /dev/null
@@ -0,0 +1,325 @@
+/* ----------------------------------------------------------------------------\r
+ *         ATMEL Microcontroller Software Support\r
+ * ----------------------------------------------------------------------------\r
+ * Copyright (c) 2010, Atmel Corporation\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the disclaimer below.\r
+ *\r
+ * Atmel's name may not be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * ----------------------------------------------------------------------------\r
+ */\r
+\r
+/** \file\r
+ *\r
+ *    Implements for USB descriptor methods described by the USB specification.\r
+ */\r
+\r
+/** \addtogroup usb_descriptor\r
+ *@{\r
+ */\r
+\r
+/*------------------------------------------------------------------------------\r
+ *         Headers\r
+ *------------------------------------------------------------------------------*/\r
+\r
+#include "USBDescriptors.h"\r
+\r
+/*------------------------------------------------------------------------------\r
+ *         Exported functions\r
+ *------------------------------------------------------------------------------*/\r
+\r
+/**\r
+ * Returns the length of a descriptor.\r
+ * \param descriptor Pointer to a USBGenericDescriptor instance.\r
+ * \return Length of descriptor in bytes.\r
+ */\r
+uint32_t USBGenericDescriptor_GetLength(\r
+    const USBGenericDescriptor *descriptor)\r
+{\r
+    return descriptor->bLength;\r
+}\r
+\r
+/**\r
+ * Returns the type of a descriptor.\r
+ * \param descriptor Pointer to a USBGenericDescriptor instance.\r
+ * \return Type of descriptor.\r
+ */\r
+uint8_t USBGenericDescriptor_GetType(\r
+    const USBGenericDescriptor *descriptor)\r
+{\r
+    return descriptor->bDescriptorType;\r
+}\r
+\r
+/**\r
+ * Returns a pointer to the descriptor right after the given one, when\r
+ * parsing a Configuration descriptor.\r
+ * \param descriptor - Pointer to a USBGenericDescriptor instance.\r
+ * \return Pointer to the next descriptor.\r
+ */\r
+USBGenericDescriptor *USBGenericDescriptor_GetNextDescriptor(\r
+    const USBGenericDescriptor *descriptor)\r
+{\r
+    return (USBGenericDescriptor *)\r
+        (((char *) descriptor) + USBGenericDescriptor_GetLength(descriptor));\r
+}\r
+\r
+/** Parses the given descriptor list via costomized function.\r
+ *  \param descriptor    Pointer to the start of the whole descriptors list.\r
+ *  \param totalLength   Total size of descriptors in bytes.\r
+ *  \param parseFunction Function to parse each descriptor scanned.\r
+ *                       Return 0 to continue parsing.\r
+ *  \param parseArg      Argument passed to parse function.\r
+ *  \return Pointer to USBGenericDescriptor instance for next descriptor.\r
+ */\r
+USBGenericDescriptor *USBGenericDescriptor_Parse(\r
+    const USBGenericDescriptor *descriptor,\r
+    uint32_t totalLength,\r
+    USBDescriptorParseFunction parseFunction,\r
+    void *parseArg)\r
+{\r
+    int32_t size = totalLength;\r
+\r
+    if (size == 0)\r
+        return 0;\r
+\r
+    /* Start parsing descriptors */\r
+    while (1) {\r
+\r
+        uint32_t parseRC = 0;\r
+\r
+        /* Parse current descriptor */\r
+        if (parseFunction) {\r
+\r
+            parseRC = parseFunction((void*)descriptor, parseArg);\r
+        }\r
+\r
+        /* Get next descriptor */\r
+        size -= USBGenericDescriptor_GetLength(descriptor);\r
+        descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);\r
+\r
+        if (size) {\r
+            if (parseRC != 0) {\r
+\r
+                return (USBGenericDescriptor *)descriptor;\r
+            }\r
+        }\r
+        else\r
+            break;\r
+    }\r
+    /* No descriptors remaining */\r
+    return 0;\r
+}\r
+\r
+\r
+/**\r
+ *  Returns the number of an endpoint given its descriptor.\r
+ *  \param endpoint Pointer to a USBEndpointDescriptor instance.\r
+ *  \return Endpoint number.\r
+ */\r
+uint8_t USBEndpointDescriptor_GetNumber(\r
+    const USBEndpointDescriptor *endpoint)\r
+{\r
+    return endpoint->bEndpointAddress & 0xF;\r
+}\r
+\r
+/**\r
+ *  Returns the direction of an endpoint given its descriptor.\r
+ *  \param endpoint Pointer to a USBEndpointDescriptor instance.\r
+ *  \return Endpoint direction (see \ref usb_ep_dir).\r
+ */\r
+uint8_t USBEndpointDescriptor_GetDirection(\r
+    const USBEndpointDescriptor *endpoint)\r
+{\r
+    if ((endpoint->bEndpointAddress & 0x80) != 0) {\r
+\r
+        return USBEndpointDescriptor_IN;\r
+    }\r
+    else {\r
+\r
+        return USBEndpointDescriptor_OUT;\r
+    }\r
+}\r
+\r
+/**\r
+ *  Returns the type of an endpoint given its descriptor.\r
+ *  \param endpoint Pointer to a USBEndpointDescriptor instance.\r
+ *  \return Endpoint type (see \ref usb_ep_type).\r
+ */\r
+uint8_t USBEndpointDescriptor_GetType(\r
+    const USBEndpointDescriptor *endpoint)\r
+{\r
+    return endpoint->bmAttributes & 0x3;\r
+}\r
+\r
+/**\r
+ *  Returns the maximum size of a packet (in bytes) on an endpoint given\r
+ *  its descriptor.\r
+ *  \param endpoint - Pointer to a USBEndpointDescriptor instance.\r
+ *  \return Maximum packet size of endpoint.\r
+ */\r
+uint16_t USBEndpointDescriptor_GetMaxPacketSize(\r
+    const USBEndpointDescriptor *endpoint)\r
+{\r
+uint16_t usTemp;\r
+uint8_t *pc1, *pc2;\r
+\r
+       pc1 = ( uint8_t * ) &( endpoint->wMaxPacketSize );\r
+       pc2 = pc1 + 1;\r
+       usTemp = ( ( *pc2 ) << 8 ) | *pc1;\r
+\r
+       return usTemp;\r
+#warning The original code below crashes when build for A5 as endpoint can be misaligned.\r
+    //_RB_return endpoint->wMaxPacketSize;\r
+}\r
+\r
+/**\r
+ *  Returns the polling interval on an endpoint given its descriptor.\r
+ *  \param endpoint - Pointer to a USBEndpointDescriptor instance.\r
+ *  \return Polling interval of endpoint.\r
+ */\r
+uint8_t USBEndpointDescriptor_GetInterval(\r
+    const USBEndpointDescriptor *endpoint)\r
+{\r
+    return endpoint->bInterval;\r
+}\r
+\r
+\r
+\r
+/** Returns the total length of a configuration, i.e. including the\r
+ *  descriptors following it.\r
+ *  \param configuration Pointer to a USBConfigurationDescriptor instance.\r
+ *  \return Total length (in bytes) of the configuration.\r
+ */\r
+volatile unsigned long ulCount = 0;\r
+uint32_t USBConfigurationDescriptor_GetTotalLength(\r
+    const USBConfigurationDescriptor *configuration)\r
+{\r
+ulCount++;\r
+if( ulCount == 5 )\r
+{\r
+       __asm volatile( "NOP" );\r
+}\r
+    return configuration->wTotalLength;\r
+}\r
+\r
+/** Returns the number of interfaces in a configuration.\r
+ *  \param configuration Pointer to a USBConfigurationDescriptor instance.\r
+ *  \return Number of interfaces in configuration.\r
+ */\r
+unsigned char USBConfigurationDescriptor_GetNumInterfaces(\r
+    const USBConfigurationDescriptor *configuration)\r
+{\r
+    return configuration->bNumInterfaces;\r
+}\r
+\r
+/** Indicates if the device is self-powered when in a given configuration.\r
+ *  \param configuration Pointer to a USBConfigurationDescriptor instance.\r
+ *  \return 1 if the device is self-powered when in the given configuration;\r
+ *          otherwise 0.\r
+ */\r
+unsigned char USBConfigurationDescriptor_IsSelfPowered(\r
+    const USBConfigurationDescriptor *configuration)\r
+{\r
+    if ((configuration->bmAttributes & (1 << 6)) != 0) {\r
+\r
+        return 1;\r
+    }\r
+    else {\r
+\r
+        return 0;\r
+    }\r
+}\r
+\r
+/** Parses the given Configuration descriptor (followed by relevant\r
+ *  interface, endpoint and class-specific descriptors) into three arrays.\r
+ *  *Each array must have its size equal or greater to the number of\r
+ *  descriptors it stores plus one*. A null-value is inserted after the last\r
+ *  descriptor of each type to indicate the array end.\r
+ *\r
+ *  Note that if the pointer to an array is null (0), nothing is stored in\r
+ *  it.\r
+ *  \param configuration Pointer to the start of the whole Configuration\r
+ *                       descriptor.\r
+ *  \param interfaces    Pointer to the Interface descriptor array.\r
+ *  \param endpoints     Pointer to the Endpoint descriptor array.\r
+ *  \param others        Pointer to the class-specific descriptor array.\r
+ */\r
+void USBConfigurationDescriptor_Parse(\r
+    const USBConfigurationDescriptor *configuration,\r
+    USBInterfaceDescriptor **interfaces,\r
+    USBEndpointDescriptor **endpoints,\r
+    USBGenericDescriptor **others)\r
+{\r
+    /* Get size of configuration to parse */\r
+    int size = USBConfigurationDescriptor_GetTotalLength(configuration);\r
+    size -= sizeof(USBConfigurationDescriptor);\r
+\r
+    /* Start parsing descriptors */\r
+    USBGenericDescriptor *descriptor = (USBGenericDescriptor *) configuration;\r
+    while (size > 0) {\r
+\r
+        /* Get next descriptor */\r
+        descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);\r
+        size -= USBGenericDescriptor_GetLength(descriptor);\r
+\r
+        /* Store descriptor in correponding array */\r
+        if (USBGenericDescriptor_GetType(descriptor)\r
+             == USBGenericDescriptor_INTERFACE) {\r
+\r
+            if (interfaces) {\r
+\r
+                *interfaces = (USBInterfaceDescriptor *) descriptor;\r
+                interfaces++;\r
+            }\r
+        }\r
+        else if (USBGenericDescriptor_GetType(descriptor)\r
+                  == USBGenericDescriptor_ENDPOINT) {\r
+\r
+            if (endpoints) {\r
+\r
+                *endpoints = (USBEndpointDescriptor *) descriptor;\r
+                endpoints++;\r
+            }\r
+        }\r
+        else if (others) {\r
+\r
+            *others = descriptor;\r
+            others++;\r
+        }\r
+    }\r
+\r
+    /* Null-terminate arrays */\r
+    if (interfaces) {\r
+\r
+        *interfaces = 0;\r
+    }\r
+    if (endpoints) {\r
+\r
+        *endpoints = 0;\r
+    }\r
+    if (others) {\r
+\r
+        *others = 0;\r
+    }\r
+}\r
+\r
+/**@}*/\r
+\r