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