SAMV71 Xplained Ultra Software Package 1.4

USBDescriptors.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
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 
00106         uint32_t parseRC = 0;
00107 
00108         /* Parse current descriptor */
00109         if (parseFunction) {
00110 
00111             parseRC = parseFunction((void*)descriptor, parseArg);
00112         }
00113 
00114         /* Get next descriptor */
00115         size -= USBGenericDescriptor_GetLength(descriptor);
00116         descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);
00117 
00118         if (size) {
00119             if (parseRC != 0) {
00120 
00121                 return (USBGenericDescriptor *)descriptor;
00122             }
00123         }
00124         else
00125             break;
00126     }
00127     /* No descriptors remaining */
00128     return 0;
00129 }
00130 
00131 
00132 /**
00133  *  Returns the number of an endpoint given its descriptor.
00134  *  \param endpoint Pointer to a USBEndpointDescriptor instance.
00135  *  \return Endpoint number.
00136  */
00137 uint8_t USBEndpointDescriptor_GetNumber(
00138     const USBEndpointDescriptor *endpoint)
00139 {
00140     return endpoint->bEndpointAddress & 0xF;
00141 }
00142 
00143 /**
00144  *  Returns the direction of an endpoint given its descriptor.
00145  *  \param endpoint Pointer to a USBEndpointDescriptor instance.
00146  *  \return Endpoint direction (see \ref usb_ep_dir).
00147  */
00148 uint8_t USBEndpointDescriptor_GetDirection(
00149     const USBEndpointDescriptor *endpoint)
00150 {
00151     if ((endpoint->bEndpointAddress & 0x80) != 0) {
00152 
00153         return USBEndpointDescriptor_IN;
00154     }
00155     else {
00156 
00157         return USBEndpointDescriptor_OUT;
00158     }
00159 }
00160 
00161 /**
00162  *  Returns the type of an endpoint given its descriptor.
00163  *  \param endpoint Pointer to a USBEndpointDescriptor instance.
00164  *  \return Endpoint type (see \ref usb_ep_type).
00165  */
00166 uint8_t USBEndpointDescriptor_GetType(
00167     const USBEndpointDescriptor *endpoint)
00168 {
00169     return endpoint->bmAttributes & 0x3;
00170 }
00171 
00172 /**
00173  *  Returns the maximum size of a packet (in bytes) on an endpoint given
00174  *  its descriptor.
00175  *  \param endpoint - Pointer to a USBEndpointDescriptor instance.
00176  *  \return Maximum packet size of endpoint.
00177  */
00178 uint16_t USBEndpointDescriptor_GetMaxPacketSize(
00179     const USBEndpointDescriptor *endpoint)
00180 {
00181     return endpoint->wMaxPacketSize;
00182 }
00183 
00184 /**
00185  *  Returns the polling interval on an endpoint given its descriptor.
00186  *  \param endpoint - Pointer to a USBEndpointDescriptor instance.
00187  *  \return Polling interval of endpoint.
00188  */
00189 uint8_t USBEndpointDescriptor_GetInterval(
00190     const USBEndpointDescriptor *endpoint)
00191 {
00192     return endpoint->bInterval;
00193 }
00194 
00195 
00196 
00197 /** Returns the total length of a configuration, i.e. including the
00198  *  descriptors following it.
00199  *  \param configuration Pointer to a USBConfigurationDescriptor instance.
00200  *  \return Total length (in bytes) of the configuration.
00201  */
00202 uint32_t USBConfigurationDescriptor_GetTotalLength(
00203     const USBConfigurationDescriptor *configuration)
00204 {
00205     return configuration->wTotalLength;
00206 }
00207 
00208 /** Returns the number of interfaces in a configuration.
00209  *  \param configuration Pointer to a USBConfigurationDescriptor instance.
00210  *  \return Number of interfaces in configuration.
00211  */
00212 unsigned char USBConfigurationDescriptor_GetNumInterfaces(
00213     const USBConfigurationDescriptor *configuration)
00214 {
00215     return configuration->bNumInterfaces;
00216 }
00217 
00218 /** Indicates if the device is self-powered when in a given configuration.
00219  *  \param configuration Pointer to a USBConfigurationDescriptor instance.
00220  *  \return 1 if the device is self-powered when in the given configuration;
00221  *          otherwise 0.
00222  */
00223 unsigned char USBConfigurationDescriptor_IsSelfPowered(
00224     const USBConfigurationDescriptor *configuration)
00225 {
00226     if ((configuration->bmAttributes & (1 << 6)) != 0) {
00227 
00228         return 1;
00229     }
00230     else {
00231 
00232         return 0;
00233     }
00234 }
00235 
00236 /** Parses the given Configuration descriptor (followed by relevant
00237  *  interface, endpoint and class-specific descriptors) into three arrays.
00238  *  *Each array must have its size equal or greater to the number of
00239  *  descriptors it stores plus one*. A null-value is inserted after the last
00240  *  descriptor of each type to indicate the array end.
00241  *
00242  *  Note that if the pointer to an array is null (0), nothing is stored in
00243  *  it.
00244  *  \param configuration Pointer to the start of the whole Configuration
00245  *                       descriptor.
00246  *  \param interfaces    Pointer to the Interface descriptor array.
00247  *  \param endpoints     Pointer to the Endpoint descriptor array.
00248  *  \param others        Pointer to the class-specific descriptor array.
00249  */
00250 void USBConfigurationDescriptor_Parse(
00251     const USBConfigurationDescriptor *configuration,
00252     USBInterfaceDescriptor **interfaces,
00253     USBEndpointDescriptor **endpoints,
00254     USBGenericDescriptor **others)
00255 {
00256     /* Get size of configuration to parse */
00257     int size = USBConfigurationDescriptor_GetTotalLength(configuration);
00258     size -= sizeof(USBConfigurationDescriptor);
00259 
00260     /* Start parsing descriptors */
00261     USBGenericDescriptor *descriptor = (USBGenericDescriptor *) configuration;
00262     while (size > 0) {
00263 
00264         /* Get next descriptor */
00265         descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);
00266         size -= USBGenericDescriptor_GetLength(descriptor);
00267 
00268         /* Store descriptor in corresponding array */
00269         if (USBGenericDescriptor_GetType(descriptor)
00270              == USBGenericDescriptor_INTERFACE) {
00271 
00272             if (interfaces) {
00273 
00274                 *interfaces = (USBInterfaceDescriptor *) descriptor;
00275                 interfaces++;
00276             }
00277         }
00278         else if (USBGenericDescriptor_GetType(descriptor)
00279                   == USBGenericDescriptor_ENDPOINT) {
00280 
00281             if (endpoints) {
00282 
00283                 *endpoints = (USBEndpointDescriptor *) descriptor;
00284                 endpoints++;
00285             }
00286         }
00287         else if (others) {
00288 
00289             *others = descriptor;
00290             others++;
00291         }
00292     }
00293 
00294     /* Null-terminate arrays */
00295     if (interfaces) {
00296 
00297         *interfaces = 0;
00298     }
00299     if (endpoints) {
00300 
00301         *endpoints = 0;
00302     }
00303     if (others) {
00304 
00305         *others = 0;
00306     }
00307 }
00308 
00309 /**@}*/
00310 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines