1 /* ----------------------------------------------------------------------------
\r
2 * ATMEL Microcontroller Software Support
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2010, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
32 * Implements for USB descriptor methods described by the USB specification.
\r
35 /** \addtogroup usb_descriptor
\r
39 /*------------------------------------------------------------------------------
\r
41 *------------------------------------------------------------------------------*/
\r
43 #include "USBDescriptors.h"
\r
45 /*------------------------------------------------------------------------------
\r
46 * Exported functions
\r
47 *------------------------------------------------------------------------------*/
\r
50 * Returns the length of a descriptor.
\r
51 * \param descriptor Pointer to a USBGenericDescriptor instance.
\r
52 * \return Length of descriptor in bytes.
\r
54 uint32_t USBGenericDescriptor_GetLength(
\r
55 const USBGenericDescriptor *descriptor)
\r
57 return descriptor->bLength;
\r
61 * Returns the type of a descriptor.
\r
62 * \param descriptor Pointer to a USBGenericDescriptor instance.
\r
63 * \return Type of descriptor.
\r
65 uint8_t USBGenericDescriptor_GetType(
\r
66 const USBGenericDescriptor *descriptor)
\r
68 return descriptor->bDescriptorType;
\r
72 * Returns a pointer to the descriptor right after the given one, when
\r
73 * parsing a Configuration descriptor.
\r
74 * \param descriptor - Pointer to a USBGenericDescriptor instance.
\r
75 * \return Pointer to the next descriptor.
\r
77 USBGenericDescriptor *USBGenericDescriptor_GetNextDescriptor(
\r
78 const USBGenericDescriptor *descriptor)
\r
80 return (USBGenericDescriptor *)
\r
81 (((char *) descriptor) + USBGenericDescriptor_GetLength(descriptor));
\r
84 /** Parses the given descriptor list via costomized function.
\r
85 * \param descriptor Pointer to the start of the whole descriptors list.
\r
86 * \param totalLength Total size of descriptors in bytes.
\r
87 * \param parseFunction Function to parse each descriptor scanned.
\r
88 * Return 0 to continue parsing.
\r
89 * \param parseArg Argument passed to parse function.
\r
90 * \return Pointer to USBGenericDescriptor instance for next descriptor.
\r
92 USBGenericDescriptor *USBGenericDescriptor_Parse(
\r
93 const USBGenericDescriptor *descriptor,
\r
94 uint32_t totalLength,
\r
95 USBDescriptorParseFunction parseFunction,
\r
98 int32_t size = totalLength;
\r
103 /* Start parsing descriptors */
\r
106 uint32_t parseRC = 0;
\r
108 /* Parse current descriptor */
\r
109 if (parseFunction) {
\r
111 parseRC = parseFunction((void*)descriptor, parseArg);
\r
114 /* Get next descriptor */
\r
115 size -= USBGenericDescriptor_GetLength(descriptor);
\r
116 descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);
\r
119 if (parseRC != 0) {
\r
121 return (USBGenericDescriptor *)descriptor;
\r
127 /* No descriptors remaining */
\r
133 * Returns the number of an endpoint given its descriptor.
\r
134 * \param endpoint Pointer to a USBEndpointDescriptor instance.
\r
135 * \return Endpoint number.
\r
137 uint8_t USBEndpointDescriptor_GetNumber(
\r
138 const USBEndpointDescriptor *endpoint)
\r
140 return endpoint->bEndpointAddress & 0xF;
\r
144 * Returns the direction of an endpoint given its descriptor.
\r
145 * \param endpoint Pointer to a USBEndpointDescriptor instance.
\r
146 * \return Endpoint direction (see \ref usb_ep_dir).
\r
148 uint8_t USBEndpointDescriptor_GetDirection(
\r
149 const USBEndpointDescriptor *endpoint)
\r
151 if ((endpoint->bEndpointAddress & 0x80) != 0) {
\r
153 return USBEndpointDescriptor_IN;
\r
157 return USBEndpointDescriptor_OUT;
\r
162 * Returns the type of an endpoint given its descriptor.
\r
163 * \param endpoint Pointer to a USBEndpointDescriptor instance.
\r
164 * \return Endpoint type (see \ref usb_ep_type).
\r
166 uint8_t USBEndpointDescriptor_GetType(
\r
167 const USBEndpointDescriptor *endpoint)
\r
169 return endpoint->bmAttributes & 0x3;
\r
173 * Returns the maximum size of a packet (in bytes) on an endpoint given
\r
175 * \param endpoint - Pointer to a USBEndpointDescriptor instance.
\r
176 * \return Maximum packet size of endpoint.
\r
178 uint16_t USBEndpointDescriptor_GetMaxPacketSize(
\r
179 const USBEndpointDescriptor *endpoint)
\r
182 uint8_t *pc1, *pc2;
\r
184 pc1 = ( uint8_t * ) &( endpoint->wMaxPacketSize );
\r
186 usTemp = ( ( *pc2 ) << 8 ) | *pc1;
\r
189 #warning The original code below crashes when build for A5 as endpoint can be misaligned.
\r
190 //_RB_return endpoint->wMaxPacketSize;
\r
194 * Returns the polling interval on an endpoint given its descriptor.
\r
195 * \param endpoint - Pointer to a USBEndpointDescriptor instance.
\r
196 * \return Polling interval of endpoint.
\r
198 uint8_t USBEndpointDescriptor_GetInterval(
\r
199 const USBEndpointDescriptor *endpoint)
\r
201 return endpoint->bInterval;
\r
206 /** Returns the total length of a configuration, i.e. including the
\r
207 * descriptors following it.
\r
208 * \param configuration Pointer to a USBConfigurationDescriptor instance.
\r
209 * \return Total length (in bytes) of the configuration.
\r
211 volatile unsigned long ulCount = 0;
\r
212 uint32_t USBConfigurationDescriptor_GetTotalLength(
\r
213 const USBConfigurationDescriptor *configuration)
\r
218 __asm volatile( "NOP" );
\r
220 return configuration->wTotalLength;
\r
223 /** Returns the number of interfaces in a configuration.
\r
224 * \param configuration Pointer to a USBConfigurationDescriptor instance.
\r
225 * \return Number of interfaces in configuration.
\r
227 unsigned char USBConfigurationDescriptor_GetNumInterfaces(
\r
228 const USBConfigurationDescriptor *configuration)
\r
230 return configuration->bNumInterfaces;
\r
233 /** Indicates if the device is self-powered when in a given configuration.
\r
234 * \param configuration Pointer to a USBConfigurationDescriptor instance.
\r
235 * \return 1 if the device is self-powered when in the given configuration;
\r
238 unsigned char USBConfigurationDescriptor_IsSelfPowered(
\r
239 const USBConfigurationDescriptor *configuration)
\r
241 if ((configuration->bmAttributes & (1 << 6)) != 0) {
\r
251 /** Parses the given Configuration descriptor (followed by relevant
\r
252 * interface, endpoint and class-specific descriptors) into three arrays.
\r
253 * *Each array must have its size equal or greater to the number of
\r
254 * descriptors it stores plus one*. A null-value is inserted after the last
\r
255 * descriptor of each type to indicate the array end.
\r
257 * Note that if the pointer to an array is null (0), nothing is stored in
\r
259 * \param configuration Pointer to the start of the whole Configuration
\r
261 * \param interfaces Pointer to the Interface descriptor array.
\r
262 * \param endpoints Pointer to the Endpoint descriptor array.
\r
263 * \param others Pointer to the class-specific descriptor array.
\r
265 void USBConfigurationDescriptor_Parse(
\r
266 const USBConfigurationDescriptor *configuration,
\r
267 USBInterfaceDescriptor **interfaces,
\r
268 USBEndpointDescriptor **endpoints,
\r
269 USBGenericDescriptor **others)
\r
271 /* Get size of configuration to parse */
\r
272 int size = USBConfigurationDescriptor_GetTotalLength(configuration);
\r
273 size -= sizeof(USBConfigurationDescriptor);
\r
275 /* Start parsing descriptors */
\r
276 USBGenericDescriptor *descriptor = (USBGenericDescriptor *) configuration;
\r
279 /* Get next descriptor */
\r
280 descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor);
\r
281 size -= USBGenericDescriptor_GetLength(descriptor);
\r
283 /* Store descriptor in correponding array */
\r
284 if (USBGenericDescriptor_GetType(descriptor)
\r
285 == USBGenericDescriptor_INTERFACE) {
\r
289 *interfaces = (USBInterfaceDescriptor *) descriptor;
\r
293 else if (USBGenericDescriptor_GetType(descriptor)
\r
294 == USBGenericDescriptor_ENDPOINT) {
\r
298 *endpoints = (USBEndpointDescriptor *) descriptor;
\r
304 *others = descriptor;
\r
309 /* Null-terminate arrays */
\r