2 * @brief USB Configuration Descriptor definitions
\r
5 * Copyright(C) NXP Semiconductors, 2012
\r
6 * Copyright(C) Dean Camera, 2011, 2012
\r
7 * All rights reserved.
\r
10 * Software that is described herein is for illustrative purposes only
\r
11 * which provides customers with programming information regarding the
\r
12 * LPC products. This software is supplied "AS IS" without any warranties of
\r
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
\r
14 * all warranties, express or implied, including all implied warranties of
\r
15 * merchantability, fitness for a particular purpose and non-infringement of
\r
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
\r
17 * or liability for the use of the software, conveys no license or rights under any
\r
18 * patent, copyright, mask work right, or any other intellectual property rights in
\r
19 * or to any products. NXP Semiconductors reserves the right to make changes
\r
20 * in the software without notification. NXP Semiconductors also makes no
\r
21 * representation or warranty that such application will be suitable for the
\r
22 * specified use without further testing or modification.
\r
25 * Permission to use, copy, modify, and distribute this software and its
\r
26 * documentation is hereby granted, under NXP Semiconductors' and its
\r
27 * licensor's relevant copyrights in the software, without fee, provided that it
\r
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
\r
29 * copyright, permission, and disclaimer notice must appear in all copies of
\r
33 /** @ingroup Group_USB
\r
34 * @defgroup Group_ConfigDescriptorParser Configuration Descriptor Parser
\r
35 * @brief USB Configuration Descriptor definitions.
\r
37 * This section of the library gives a friendly API which can be used in host applications to easily
\r
38 * parse an attached device's configuration descriptor so that endpoint, interface and other descriptor
\r
39 * data can be extracted and used as needed.
\r
44 #ifndef __CONFIGDESCRIPTOR_H__
\r
45 #define __CONFIGDESCRIPTOR_H__
\r
48 #include "../../../Common/Common.h"
\r
49 #include "USBMode.h"
\r
50 #include "HostStandardReq.h"
\r
51 #include "StdDescriptors.h"
\r
53 /* Enable C linkage for C++ Compilers: */
\r
54 #if defined(__cplusplus)
\r
58 /* Preprocessor Checks: */
\r
59 #if !defined(__INCLUDE_FROM_USB_DRIVER)
\r
60 #error Do not include this file directly. Include lpcroot/libraries/LPCUSBlib/Drivers/USB/USB.h instead.
\r
63 /* Public Interface - May be used in end-application: */
\r
65 /** Casts a pointer to a descriptor inside the configuration descriptor into a pointer to the given
\r
70 * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header
\r
71 * USB_Descriptor_Configuration_Header_t* ConfigHeaderPtr = DESCRIPTOR_PCAST(CurrDescriptor,
\r
72 * USB_Descriptor_Configuration_Header_t);
\r
74 * // Can now access elements of the configuration header struct using the -> indirection operator
\r
77 #define DESCRIPTOR_PCAST(DescriptorPtr, Type) ((Type*)(DescriptorPtr))
\r
79 /** Casts a pointer to a descriptor inside the configuration descriptor into the given descriptor
\r
80 * type (as an actual struct instance rather than a pointer to a struct).
\r
84 * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header
\r
85 * USB_Descriptor_Configuration_Header_t ConfigHeader = DESCRIPTOR_CAST(CurrDescriptor,
\r
86 * USB_Descriptor_Configuration_Header_t);
\r
88 * // Can now access elements of the configuration header struct using the . operator
\r
91 #define DESCRIPTOR_CAST(DescriptorPtr, Type) (*DESCRIPTOR_PCAST(DescriptorPtr, Type))
\r
93 /** Returns the descriptor's type, expressed as the 8-bit type value in the header of the descriptor.
\r
94 * This value's meaning depends on the descriptor's placement in the descriptor, but standard type
\r
95 * values can be accessed in the @ref USB_DescriptorTypes_t enum.
\r
97 #define DESCRIPTOR_TYPE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Type
\r
99 /** Returns the descriptor's size, expressed as the 8-bit value indicating the number of bytes. */
\r
100 #define DESCRIPTOR_SIZE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Size
\r
102 /* Type Defines: */
\r
103 /** Type define for a Configuration Descriptor comparator function (function taking a pointer to an array
\r
104 * of type void, returning a uint8_t value).
\r
106 * \see @ref USB_GetNextDescriptorComp function for more details.
\r
108 typedef uint8_t (* ConfigComparatorPtr_t)(void*);
\r
111 /** Enum for the possible return codes of the @ref USB_Host_GetDeviceConfigDescriptor() function. */
\r
112 enum USB_Host_GetConfigDescriptor_ErrorCodes_t
\r
114 HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor. */
\r
115 HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration
\r
118 HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request. */
\r
119 HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration
\r
122 HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */
\r
123 HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated
\r
126 HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data. */
\r
129 /** Enum for return values of a descriptor comparator function. */
\r
130 enum DSearch_Return_ErrorCodes_t
\r
132 DESCRIPTOR_SEARCH_Found = 0, /**< Current descriptor matches comparator criteria. */
\r
133 DESCRIPTOR_SEARCH_Fail = 1, /**< No further descriptor could possibly match criteria, fail the search. */
\r
134 DESCRIPTOR_SEARCH_NotFound = 2, /**< Current descriptor does not match comparator criteria. */
\r
137 /** Enum for return values of @ref USB_GetNextDescriptorComp(). */
\r
138 enum DSearch_Comp_Return_ErrorCodes_t
\r
140 DESCRIPTOR_SEARCH_COMP_Found = 0, /**< Configuration descriptor now points to descriptor which matches
\r
141 * search criteria of the given comparator function. */
\r
142 DESCRIPTOR_SEARCH_COMP_Fail = 1, /**< Comparator function returned @ref DESCRIPTOR_SEARCH_Fail. */
\r
143 DESCRIPTOR_SEARCH_COMP_EndOfDescriptor = 2, /**< End of configuration descriptor reached before match found. */
\r
146 /* Function Prototypes: */
\r
147 /** @brief Retrieves the configuration descriptor data from an attached device via a standard request into a buffer,
\r
148 * including validity and size checking to prevent a buffer overflow.
\r
150 * @param corenum : USB port number
\r
151 * @param ConfigNumber : Device configuration descriptor number to fetch from the device (usually set to 1 for
\r
152 * single configuration devices).
\r
153 * @param ConfigSizePtr : Pointer to a location for storing the retrieved configuration descriptor size.
\r
154 * @param BufferPtr : Pointer to the buffer for storing the configuration descriptor data.
\r
155 * @param BufferSize : Size of the allocated buffer where the configuration descriptor is to be stored.
\r
157 * @return A value from the @ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum.
\r
159 uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t corenum,
\r
160 const uint8_t ConfigNumber,
\r
161 uint16_t* const ConfigSizePtr,
\r
162 void* const BufferPtr,
\r
163 const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(3) ATTR_NON_NULL_PTR_ARG(4);
\r
165 /** @brief Skips to the next sub-descriptor inside the configuration descriptor of the specified type value.
\r
166 * The bytes remaining value is automatically decremented.
\r
168 * @param BytesRem : Pointer to the number of bytes remaining of the configuration descriptor.
\r
169 * @param CurrConfigLoc : Pointer to the current descriptor inside the configuration descriptor.
\r
170 * @param Type : Descriptor type value to search for.
\r
173 void USB_GetNextDescriptorOfType(uint16_t* const BytesRem,
\r
174 void** const CurrConfigLoc,
\r
175 const uint8_t Type)
\r
176 ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
\r
178 /** @brief Skips to the next sub-descriptor inside the configuration descriptor of the specified type value,
\r
179 * which must come before a descriptor of the second given type value. If the BeforeType type
\r
180 * descriptor is reached first, the number of bytes remaining to process is set to zero and the
\r
181 * function exits. The bytes remaining value is automatically decremented.
\r
183 * @param BytesRem : Pointer to the number of bytes remaining of the configuration descriptor.
\r
184 * @param CurrConfigLoc : Pointer to the current descriptor inside the configuration descriptor.
\r
185 * @param Type : Descriptor type value to search for.
\r
186 * @param BeforeType : Descriptor type value which must not be reached before the given Type descriptor.
\r
189 void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem,
\r
190 void** const CurrConfigLoc,
\r
191 const uint8_t Type,
\r
192 const uint8_t BeforeType)
\r
193 ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
\r
195 /** @brief Skips to the next sub-descriptor inside the configuration descriptor of the specified type value,
\r
196 * which must come after a descriptor of the second given type value. The bytes remaining value is
\r
197 * automatically decremented.
\r
199 * @param BytesRem : Pointer to the number of bytes remaining of the configuration descriptor.
\r
200 * @param CurrConfigLoc : Pointer to the current descriptor inside the configuration descriptor.
\r
201 * @param Type : Descriptor type value to search for.
\r
202 * @param AfterType : Descriptor type value which must be reached before the given Type descriptor.
\r
205 void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem,
\r
206 void** const CurrConfigLoc,
\r
207 const uint8_t Type,
\r
208 const uint8_t AfterType)
\r
209 ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
\r
211 /** @brief Searches for the next descriptor in the given configuration descriptor using a pre-made comparator
\r
212 * function. The routine updates the position and remaining configuration descriptor bytes values
\r
213 * automatically. If a comparator routine fails a search, the descriptor pointer is retreated back
\r
214 * so that the next descriptor search invocation will start from the descriptor which first caused the
\r
215 * original search to fail. This behaviour allows for one comparator to be used immediately after another
\r
216 * has failed, starting the second search from the descriptor which failed the first.
\r
218 * Comparator functions should be standard functions which accept a pointer to the header of the current
\r
219 * descriptor inside the configuration descriptor which is being compared, and should return a value from
\r
220 * the @ref DSearch_Return_ErrorCodes_t enum as a uint8_t value.
\r
222 * @note This function is available in USB Host mode only.
\r
224 * @param BytesRem : Pointer to an int storing the remaining bytes in the configuration descriptor.
\r
225 * @param CurrConfigLoc : Pointer to the current position in the configuration descriptor.
\r
226 * @param ComparatorRoutine : Name of the comparator search function to use on the configuration descriptor.
\r
228 * @return Value of one of the members of the @ref DSearch_Comp_Return_ErrorCodes_t enum.
\r
232 * uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype
\r
234 * uint8_t EndpointSearcher(void* CurrentDescriptor)
\r
236 * if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
\r
237 * return DESCRIPTOR_SEARCH_Found;
\r
239 * return DESCRIPTOR_SEARCH_NotFound;
\r
243 * // After retrieving configuration descriptor:
\r
244 * if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) ==
\r
245 * Descriptor_Search_Comp_Found)
\r
247 * // Do something with the endpoint descriptor
\r
251 uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem,
\r
252 void** const CurrConfigLoc,
\r
253 ConfigComparatorPtr_t const ComparatorRoutine);
\r
255 /* Inline Functions: */
\r
256 /** @brief Skips over the current sub-descriptor inside the configuration descriptor, so that the pointer then
\r
257 points to the next sub-descriptor. The bytes remaining value is automatically decremented.
\r
259 * @param BytesRem : Pointer to the number of bytes remaining of the configuration descriptor.
\r
260 * @param CurrConfigLoc : Pointer to the current descriptor inside the configuration descriptor.
\r
262 static inline void USB_GetNextDescriptor(uint16_t* const BytesRem,
\r
263 void** CurrConfigLoc) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
\r
264 static inline void USB_GetNextDescriptor(uint16_t* const BytesRem,
\r
265 void** CurrConfigLoc)
\r
267 uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size;
\r
269 if (*BytesRem < CurrDescriptorSize)
\r
270 CurrDescriptorSize = *BytesRem;
\r
272 *CurrConfigLoc = (void*)((uintptr_t)*CurrConfigLoc + CurrDescriptorSize);
\r
273 *BytesRem -= CurrDescriptorSize;
\r
276 /* Disable C linkage for C++ Compilers: */
\r
277 #if defined(__cplusplus)
\r