SAMV71 Xplained Ultra Software Package 1.5

USBDescriptors.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \file
00031  *
00032  *    Implements for USB descriptor methods described by the USB specification.
00033  */
00034 
00035 /** \addtogroup usb_descriptor
00036  *@{
00037  */
00038 
00039 /*------------------------------------------------------------------------------
00040  *         Headers
00041  *------------------------------------------------------------------------------*/
00042 
00043 #include "USBDescriptors.h"
00044 
00045 /*------------------------------------------------------------------------------
00046  *         Exported functions
00047  *------------------------------------------------------------------------------*/
00048 
00049 /**
00050  * Returns the length of a descriptor.
00051  * \param descriptor Pointer to a USBGenericDescriptor instance.
00052  * \return Length of descriptor in bytes.
00053  */
00054 uint32_t USBGenericDescriptor_GetLength(
00055     const USBGenericDescriptor *descriptor)
00056 {
00057     return descriptor->bLength;
00058 }
00059 
00060 /**
00061  * Returns the type of a descriptor.
00062  * \param descriptor Pointer to a USBGenericDescriptor instance.
00063  * \return Type of descriptor.
00064  */
00065 uint8_t USBGenericDescriptor_GetType(
00066     const USBGenericDescriptor *descriptor)
00067 {
00068     return descriptor->bDescriptorType;
00069 }
00070 
00071 /**
00072  * Returns a pointer to the descriptor right after the given one, when
00073  * parsing a Configuration descriptor.
00074  * \param descriptor - Pointer to a USBGenericDescriptor instance.
00075  * \return Pointer to the next descriptor.
00076  */
00077 USBGenericDescriptor *USBGenericDescriptor_GetNextDescriptor(
00078     const USBGenericDescriptor *descriptor)
00079 {
00080     return (USBGenericDescriptor *)
00081            (((char *) descriptor) + USBGenericDescriptor_GetLength(descriptor));
00082 }
00083 
00084 /** Parses the given descriptor list via customized function.
00085  *  \param descriptor    Pointer to the start of the whole descriptors list.
00086  *  \param totalLength   Total size of descriptors in bytes.
00087  *  \param parseFunction Function to parse each descriptor scanned.
00088  *                       Return 0 to continue parsing.
00089  *  \param parseArg      Argument passed to parse function.
00090  *  \return Pointer to USBGenericDescriptor instance for next descriptor.
00091  */
00092 USBGenericDescriptor *USBGenericDescriptor_Parse(
00093     const USBGenericDescriptor *descriptor,
00094     uint32_t totalLength,
00095     USBDescriptorParseFunction parseFunction,
00096     void *parseArg)
00097 {
00098     int32_t size = totalLength;
00099 
00100     if (size == 0)
00101         return 0;
00102 
00103     /* Start parsing descriptors */
00104     while (1) {
00105         uint32_t parseRC = 0;
00106 
00107         /* Parse current descriptor */
00108         if (parseFunction)
00109             parseRC = parseFunction((void *)descriptor, parseArg);
00110 
00111         /* Get next descriptor */
00112         size -= USBGenericDescriptor_GetLength(descriptor);
00113         descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);
00114 
00115         if (size) {
00116             if (parseRC != 0)
00117 
00118                 return (USBGenericDescriptor *)descriptor;
00119         } else
00120             break;
00121     }
00122 
00123     /* No descriptors remaining */
00124     return 0;
00125 }
00126 
00127 
00128 /**
00129  *  Returns the number of an endpoint given its descriptor.
00130  *  \param endpoint Pointer to a USBEndpointDescriptor instance.
00131  *  \return Endpoint number.
00132  */
00133 uint8_t USBEndpointDescriptor_GetNumber(
00134     const USBEndpointDescriptor *endpoint)
00135 {
00136     return endpoint->bEndpointAddress & 0xF;
00137 }
00138 
00139 /**
00140  *  Returns the direction of an endpoint given its descriptor.
00141  *  \param endpoint Pointer to a USBEndpointDescriptor instance.
00142  *  \return Endpoint direction (see \ref usb_ep_dir).
00143  */
00144 uint8_t USBEndpointDescriptor_GetDirection(
00145     const USBEndpointDescriptor *endpoint)
00146 {
00147     if ((endpoint->bEndpointAddress & 0x80) != 0)
00148 
00149         return USBEndpointDescriptor_IN;
00150     else
00151 
00152         return USBEndpointDescriptor_OUT;
00153 }
00154 
00155 /**
00156  *  Returns the type of an endpoint given its descriptor.
00157  *  \param endpoint Pointer to a USBEndpointDescriptor instance.
00158  *  \return Endpoint type (see \ref usb_ep_type).
00159  */
00160 uint8_t USBEndpointDescriptor_GetType(
00161     const USBEndpointDescriptor *endpoint)
00162 {
00163     return endpoint->bmAttributes & 0x3;
00164 }
00165 
00166 /**
00167  *  Returns the maximum size of a packet (in bytes) on an endpoint given
00168  *  its descriptor.
00169  *  \param endpoint - Pointer to a USBEndpointDescriptor instance.
00170  *  \return Maximum packet size of endpoint.
00171  */
00172 uint16_t USBEndpointDescriptor_GetMaxPacketSize(
00173     const USBEndpointDescriptor *endpoint)
00174 {
00175     return endpoint->wMaxPacketSize;
00176 }
00177 
00178 /**
00179  *  Returns the polling interval on an endpoint given its descriptor.
00180  *  \param endpoint - Pointer to a USBEndpointDescriptor instance.
00181  *  \return Polling interval of endpoint.
00182  */
00183 uint8_t USBEndpointDescriptor_GetInterval(
00184     const USBEndpointDescriptor *endpoint)
00185 {
00186     return endpoint->bInterval;
00187 }
00188 
00189 
00190 
00191 /** Returns the total length of a configuration, i.e. including the
00192  *  descriptors following it.
00193  *  \param configuration Pointer to a USBConfigurationDescriptor instance.
00194  *  \return Total length (in bytes) of the configuration.
00195  */
00196 uint32_t USBConfigurationDescriptor_GetTotalLength(
00197     const USBConfigurationDescriptor *configuration)
00198 {
00199     return configuration->wTotalLength;
00200 }
00201 
00202 /** Returns the number of interfaces in a configuration.
00203  *  \param configuration Pointer to a USBConfigurationDescriptor instance.
00204  *  \return Number of interfaces in configuration.
00205  */
00206 unsigned char USBConfigurationDescriptor_GetNumInterfaces(
00207     const USBConfigurationDescriptor *configuration)
00208 {
00209     return configuration->bNumInterfaces;
00210 }
00211 
00212 /** Indicates if the device is self-powered when in a given configuration.
00213  *  \param configuration Pointer to a USBConfigurationDescriptor instance.
00214  *  \return 1 if the device is self-powered when in the given configuration;
00215  *          otherwise 0.
00216  */
00217 unsigned char USBConfigurationDescriptor_IsSelfPowered(
00218     const USBConfigurationDescriptor *configuration)
00219 {
00220     if ((configuration->bmAttributes & (1 << 6)) != 0)
00221 
00222         return 1;
00223     else
00224 
00225         return 0;
00226 }
00227 
00228 /** Parses the given Configuration descriptor (followed by relevant
00229  *  interface, endpoint and class-specific descriptors) into three arrays.
00230  *  *Each array must have its size equal or greater to the number of
00231  *  descriptors it stores plus one*. A null-value is inserted after the last
00232  *  descriptor of each type to indicate the array end.
00233  *
00234  *  Note that if the pointer to an array is null (0), nothing is stored in
00235  *  it.
00236  *  \param configuration Pointer to the start of the whole Configuration
00237  *                       descriptor.
00238  *  \param interfaces    Pointer to the Interface descriptor array.
00239  *  \param endpoints     Pointer to the Endpoint descriptor array.
00240  *  \param others        Pointer to the class-specific descriptor array.
00241  */
00242 void USBConfigurationDescriptor_Parse(
00243     const USBConfigurationDescriptor *configuration,
00244     USBInterfaceDescriptor **interfaces,
00245     USBEndpointDescriptor **endpoints,
00246     USBGenericDescriptor **others)
00247 {
00248     /* Get size of configuration to parse */
00249     int size = USBConfigurationDescriptor_GetTotalLength(configuration);
00250     size -= sizeof(USBConfigurationDescriptor);
00251 
00252     /* Start parsing descriptors */
00253     USBGenericDescriptor *descriptor = (USBGenericDescriptor *) configuration;
00254 
00255     while (size > 0) {
00256         /* Get next descriptor */
00257         descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);
00258         size -= USBGenericDescriptor_GetLength(descriptor);
00259 
00260         /* Store descriptor in corresponding array */
00261         if (USBGenericDescriptor_GetType(descriptor)
00262             == USBGenericDescriptor_INTERFACE) {
00263 
00264             if (interfaces) {
00265                 *interfaces = (USBInterfaceDescriptor *) descriptor;
00266                 interfaces++;
00267             }
00268         } else if (USBGenericDescriptor_GetType(descriptor)
00269                    == USBGenericDescriptor_ENDPOINT) {
00270 
00271             if (endpoints) {
00272                 *endpoints = (USBEndpointDescriptor *) descriptor;
00273                 endpoints++;
00274             }
00275         } else if (others) {
00276             *others = descriptor;
00277             others++;
00278         }
00279     }
00280 
00281     /* Null-terminate arrays */
00282     if (interfaces)
00283         *interfaces = 0;
00284 
00285     if (endpoints)
00286         *endpoints = 0;
00287 
00288     if (others)
00289         *others = 0;
00290 }
00291 
00292 /**@}*/
00293 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines