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