]> git.sur5r.net Git - freertos/blob
045d3a9273e71d4a679751ede27e5698c69c5192
[freertos] /
1 /*\r
2  * @brief USB Configuration Descriptor definitions\r
3  *\r
4  * @note\r
5  * Copyright(C) NXP Semiconductors, 2012\r
6  * Copyright(C) Dean Camera, 2011, 2012\r
7  * All rights reserved.\r
8  *\r
9  * @par\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
23  *\r
24  * @par\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
30  * this code.\r
31  */\r
32 \r
33 /** @ingroup Group_USB\r
34  *  @defgroup Group_ConfigDescriptorParser Configuration Descriptor Parser\r
35  *  @brief USB Configuration Descriptor definitions.\r
36  *\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
40  *\r
41  *  @{\r
42  */\r
43 \r
44 #ifndef __CONFIGDESCRIPTOR_H__\r
45 #define __CONFIGDESCRIPTOR_H__\r
46 \r
47         /* Includes: */\r
48                 #include "../../../Common/Common.h"\r
49                 #include "USBMode.h"            \r
50                 #include "HostStandardReq.h"\r
51                 #include "StdDescriptors.h"\r
52 \r
53         /* Enable C linkage for C++ Compilers: */\r
54                 #if defined(__cplusplus)\r
55                         extern "C" {\r
56                 #endif\r
57 \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
61                 #endif\r
62 \r
63         /* Public Interface - May be used in end-application: */\r
64                 /* Macros: */\r
65                         /** Casts a pointer to a descriptor inside the configuration descriptor into a pointer to the given\r
66                          *  descriptor type.\r
67                          *\r
68                          *  Usage Example:\r
69                          *  \code\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
73                          *\r
74                          *  // Can now access elements of the configuration header struct using the -> indirection operator\r
75                          *  \endcode\r
76                          */\r
77                         #define DESCRIPTOR_PCAST(DescriptorPtr, Type) ((Type*)(DescriptorPtr))\r
78 \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
81                          *\r
82                          *  Usage Example:\r
83                          *  \code\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
87                          *\r
88                          *  // Can now access elements of the configuration header struct using the . operator\r
89                          *  \endcode\r
90                          */\r
91                         #define DESCRIPTOR_CAST(DescriptorPtr, Type)  (*DESCRIPTOR_PCAST(DescriptorPtr, Type))\r
92 \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
96                          */\r
97                         #define DESCRIPTOR_TYPE(DescriptorPtr)    DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Type\r
98 \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
101 \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
105                          *\r
106                          *  \see @ref USB_GetNextDescriptorComp function for more details.\r
107                          */\r
108                         typedef uint8_t (* ConfigComparatorPtr_t)(void*);\r
109 \r
110                 /* Enums: */\r
111                         /** Enum for the possible return codes of the @ref USB_Host_GetDeviceConfigDescriptor() function. */\r
112                         enum USB_Host_GetConfigDescriptor_ErrorCodes_t\r
113                         {\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
116                                                                         * descriptor.\r
117                                                                         */\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
120                                                                         * descriptor.\r
121                                                                         */\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
124                                                                         * buffer.\r
125                                                                         */\r
126                                 HOST_GETCONFIG_InvalidData      = 6, /**< The device returned invalid configuration descriptor data. */\r
127                         };\r
128 \r
129                         /** Enum for return values of a descriptor comparator function. */\r
130                         enum DSearch_Return_ErrorCodes_t\r
131                         {\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
135                         };\r
136 \r
137                         /** Enum for return values of @ref USB_GetNextDescriptorComp(). */\r
138                         enum DSearch_Comp_Return_ErrorCodes_t\r
139                         {\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
144                         };\r
145 \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
149                          *\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
156                          *\r
157                          *  @return A value from the @ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum.\r
158                          */\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
164 \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
167                          *\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
171                          *      @return Nothing\r
172                          */\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
177 \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
182                          *\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
187                          * @return      Nothing\r
188                          */\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
194 \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
198                          *\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
203                          * @return      Nothing\r
204                          */\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
210 \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
217                          *\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
221                          *\r
222                          *  @note This function is available in USB Host mode only.\r
223                          *\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
227                          *\r
228                          *  @return Value of one of the members of the @ref DSearch_Comp_Return_ErrorCodes_t enum.\r
229                          *\r
230                          *  Usage Example:\r
231                          *  \code\r
232                          *  uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype\r
233                          *\r
234                          *  uint8_t EndpointSearcher(void* CurrentDescriptor)\r
235                          *  {\r
236                          *     if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)\r
237                          *         return DESCRIPTOR_SEARCH_Found;\r
238                          *     else\r
239                          *         return DESCRIPTOR_SEARCH_NotFound;\r
240                          *  }\r
241                          *\r
242                          *  //...\r
243                          *  // After retrieving configuration descriptor:\r
244                          *  if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) ==\r
245                          *      Descriptor_Search_Comp_Found)\r
246                          *  {\r
247                          *      // Do something with the endpoint descriptor\r
248                          *  }\r
249                          *  \endcode\r
250                          */\r
251                         uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem,\r
252                                                           void** const CurrConfigLoc,\r
253                                                           ConfigComparatorPtr_t const ComparatorRoutine);\r
254 \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
258                          *\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
261                          */\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
266                         {\r
267                                 uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size;\r
268                                 \r
269                                 if (*BytesRem < CurrDescriptorSize)\r
270                                   CurrDescriptorSize = *BytesRem;\r
271 \r
272                                 *CurrConfigLoc  = (void*)((uintptr_t)*CurrConfigLoc + CurrDescriptorSize);\r
273                                 *BytesRem      -= CurrDescriptorSize;\r
274                         }\r
275 \r
276         /* Disable C linkage for C++ Compilers: */\r
277                 #if defined(__cplusplus)\r
278                         }\r
279                 #endif\r
280 \r
281 #endif\r
282 \r
283 /** @} */\r
284 \r