1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8 Warning: The USB Host Library API is still a beta version and may be subject to change
9 */
10 
11 #pragma once
12 
13 #include <stdint.h>
14 
15 #ifdef __cplusplus
16 extern "C"
17 {
18 #endif
19 
20 #define USB_DESC_ATTR                   __attribute__((packed))
21 
22 // ---------------------------------------------------- Chapter 9 ------------------------------------------------------
23 
24 /**
25  * @brief USB2.0 device states
26  *
27  * See Table 9-1 of USB2.0 specification for more details
28  *
29  * @note The USB_DEVICE_STATE_NOT_ATTACHED is not part of the USB2.0 specification, but is a catch all state for devices
30  *       that need to be cleaned up after a sudden disconnection or port error.
31  */
32 typedef enum {
33     USB_DEVICE_STATE_NOT_ATTACHED,              /**< The device was previously configured or suspended, but is no longer attached (either suddenly disconnected or a port error) */
34     USB_DEVICE_STATE_ATTACHED,                  /**< Device is attached to the USB, but is not powered. */
35     USB_DEVICE_STATE_POWERED,                   /**< Device is attached to the USB and powered, but has not been reset. */
36     USB_DEVICE_STATE_DEFAULT,                   /**< Device is attached to the USB and powered and has been reset, but has not been assigned a unique address. Device responds at the default address. */
37     USB_DEVICE_STATE_ADDRESS,                   /**< Device is attached to the USB, powered, has been reset, and a unique device address has been assigned. Device is not configured. */
38     USB_DEVICE_STATE_CONFIGURED,                /**< Device is attached to the USB, powered, has been reset, has a unique address, is configured, and is not suspended. The host may now use the function provided by the device. */
39     USB_DEVICE_STATE_SUSPENDED,                 /**< Device is, at minimum, attached to the USB and is powered and has not seen bus activity for 3 ms. It may also have a unique address and be configured for use. However, because the device is suspended, the host may not use the device’s function. */
40 } usb_device_state_t;
41 
42 /**
43  * @brief Descriptor types from USB2.0 specification table 9.5
44  */
45 #define USB_B_DESCRIPTOR_TYPE_DEVICE                        0x01
46 #define USB_B_DESCRIPTOR_TYPE_CONFIGURATION                 0x02
47 #define USB_B_DESCRIPTOR_TYPE_STRING                        0x03
48 #define USB_B_DESCRIPTOR_TYPE_INTERFACE                     0x04
49 #define USB_B_DESCRIPTOR_TYPE_ENDPOINT                      0x05
50 #define USB_B_DESCRIPTOR_TYPE_DEVICE_QUALIFIER              0x06
51 #define USB_B_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION     0x07
52 #define USB_B_DESCRIPTOR_TYPE_INTERFACE_POWER               0x08
53 
54 /**
55  * @brief Descriptor types from USB 2.0 ECN
56  */
57 #define USB_B_DESCRIPTOR_TYPE_OTG                           0x09
58 #define USB_B_DESCRIPTOR_TYPE_DEBUG                         0x0a
59 #define USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION         0x0b
60 
61 /**
62  * @brief Descriptor types from Wireless USB spec
63  */
64 #define USB_B_DESCRIPTOR_TYPE_SECURITY                      0x0c
65 #define USB_B_DESCRIPTOR_TYPE_KEY                           0x0d
66 #define USB_B_DESCRIPTOR_TYPE_ENCRYPTION_TYPE               0x0e
67 #define USB_B_DESCRIPTOR_TYPE_BOS                           0x0f
68 #define USB_B_DESCRIPTOR_TYPE_DEVICE_CAPABILITY             0x10
69 #define USB_B_DESCRIPTOR_TYPE_WIRELESS_ENDPOINT_COMP        0x11
70 #define USB_B_DESCRIPTOR_TYPE_WIRE_ADAPTER                  0x21
71 #define USB_B_DESCRIPTOR_TYPE_RPIPE                         0x22
72 #define USB_B_DESCRIPTOR_TYPE_CS_RADIO_CONTROL              0x23
73 
74 /**
75  * @brief Descriptor types from UAS specification
76  */
77 #define USB_B_DESCRIPTOR_TYPE_PIPE_USAGE                    0x24
78 
79 // -------------------- Setup Packet -----------------------
80 
81 /**
82  * @brief Size of a USB control transfer setup packet in bytes
83  */
84 #define USB_SETUP_PACKET_SIZE               8
85 
86 /**
87  * @brief Structure representing a USB control transfer setup packet
88  *
89  * See Table 9-2 of USB2.0 specification for more details
90  */
91 typedef union {
92     struct {
93         uint8_t bmRequestType;              /**< Characteristics of request */
94         uint8_t bRequest;                   /**< Specific request */
95         uint16_t wValue;                    /**< Word-sized field that varies according to request */
96         uint16_t wIndex;                    /**< Word-sized field that varies according to request; typically used to pass an index or offset */
97         uint16_t wLength;                   /**< Number of bytes to transfer if there is a data stage */
98     } __attribute__((packed));
99     uint8_t val[USB_SETUP_PACKET_SIZE];
100 } usb_setup_packet_t;
101 _Static_assert(sizeof(usb_setup_packet_t) == USB_SETUP_PACKET_SIZE, "Size of usb_setup_packet_t incorrect");
102 
103 /**
104  * @brief Bit masks belonging to the bmRequestType field of a setup packet
105  */
106 #define USB_BM_REQUEST_TYPE_DIR_OUT         (0X00 << 7)
107 #define USB_BM_REQUEST_TYPE_DIR_IN          (0x01 << 7)
108 #define USB_BM_REQUEST_TYPE_TYPE_STANDARD   (0x00 << 5)
109 #define USB_BM_REQUEST_TYPE_TYPE_CLASS      (0x01 << 5)
110 #define USB_BM_REQUEST_TYPE_TYPE_VENDOR     (0x02 << 5)
111 #define USB_BM_REQUEST_TYPE_TYPE_RESERVED   (0x03 << 5)
112 #define USB_BM_REQUEST_TYPE_TYPE_MASK       (0x03 << 5)
113 #define USB_BM_REQUEST_TYPE_RECIP_DEVICE    (0x00 << 0)
114 #define USB_BM_REQUEST_TYPE_RECIP_INTERFACE (0x01 << 0)
115 #define USB_BM_REQUEST_TYPE_RECIP_ENDPOINT  (0x02 << 0)
116 #define USB_BM_REQUEST_TYPE_RECIP_OTHER     (0x03 << 0)
117 #define USB_BM_REQUEST_TYPE_RECIP_MASK      (0x1f << 0)
118 
119 /**
120  * @brief Bit masks belonging to the bRequest field of a setup packet
121  */
122 #define USB_B_REQUEST_GET_STATUS            0x00
123 #define USB_B_REQUEST_CLEAR_FEATURE         0x01
124 #define USB_B_REQUEST_SET_FEATURE           0x03
125 #define USB_B_REQUEST_SET_ADDRESS           0x05
126 #define USB_B_REQUEST_GET_DESCRIPTOR        0x06
127 #define USB_B_REQUEST_SET_DESCRIPTOR        0x07
128 #define USB_B_REQUEST_GET_CONFIGURATION     0x08
129 #define USB_B_REQUEST_SET_CONFIGURATION     0x09
130 #define USB_B_REQUEST_GET_INTERFACE         0x0A
131 #define USB_B_REQUEST_SET_INTERFACE         0x0B
132 #define USB_B_REQUEST_SYNCH_FRAME           0x0C
133 
134 /**
135  * @brief Bit masks belonging to the wValue field of a setup packet
136  */
137 #define USB_W_VALUE_DT_DEVICE               0x01
138 #define USB_W_VALUE_DT_CONFIG               0x02
139 #define USB_W_VALUE_DT_STRING               0x03
140 #define USB_W_VALUE_DT_INTERFACE            0x04
141 #define USB_W_VALUE_DT_ENDPOINT             0x05
142 #define USB_W_VALUE_DT_DEVICE_QUALIFIER     0x06
143 #define USB_W_VALUE_DT_OTHER_SPEED_CONFIG   0x07
144 #define USB_W_VALUE_DT_INTERFACE_POWER      0x08
145 
146 /**
147  * @brief Initializer for a SET_ADDRESS request
148  *
149  * Sets the address of a connected device
150  */
151 #define USB_SETUP_PACKET_INIT_SET_ADDR(setup_pkt_ptr, addr) ({  \
152     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_STANDARD |USB_BM_REQUEST_TYPE_RECIP_DEVICE;   \
153     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_SET_ADDRESS;  \
154     (setup_pkt_ptr)->wValue = (addr);   \
155     (setup_pkt_ptr)->wIndex = 0;    \
156     (setup_pkt_ptr)->wLength = 0;   \
157 })
158 
159 /**
160  * @brief Initializer for a request to get a device's device descriptor
161  */
162 #define USB_SETUP_PACKET_INIT_GET_DEVICE_DESC(setup_pkt_ptr) ({  \
163     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE;   \
164     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR;   \
165     (setup_pkt_ptr)->wValue = (USB_W_VALUE_DT_DEVICE << 8); \
166     (setup_pkt_ptr)->wIndex = 0;    \
167     (setup_pkt_ptr)->wLength = 18;  \
168 })
169 
170 /**
171  * @brief Initializer for a request to get a device's current configuration number
172  */
173 #define USB_SETUP_PACKET_INIT_GET_CONFIG(setup_pkt_ptr) ({  \
174     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE;   \
175     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_GET_CONFIGURATION;    \
176     (setup_pkt_ptr)->wValue = 0;    \
177     (setup_pkt_ptr)->wIndex = 0;    \
178     (setup_pkt_ptr)->wLength = 1;   \
179 })
180 
181 /**
182  * @brief Initializer for a request to get one of the device's current configuration descriptor
183  *
184  * - desc_index indicates the configuration's index number
185  * - Number of bytes of the configuration descriptor to get
186  */
187 #define USB_SETUP_PACKET_INIT_GET_CONFIG_DESC(setup_pkt_ptr, desc_index, desc_len) ({    \
188     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE;   \
189     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR;   \
190     (setup_pkt_ptr)->wValue = (USB_W_VALUE_DT_CONFIG << 8) | ((desc_index) & 0xFF); \
191     (setup_pkt_ptr)->wIndex = 0;    \
192     (setup_pkt_ptr)->wLength = (desc_len);  \
193 })
194 
195 /**
196  * @brief Initializer for a request to set a device's current configuration number
197  */
198 #define USB_SETUP_PACKET_INIT_SET_CONFIG(setup_pkt_ptr, config_num) ({  \
199     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE;   \
200     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_SET_CONFIGURATION;    \
201     (setup_pkt_ptr)->wValue = (config_num); \
202     (setup_pkt_ptr)->wIndex = 0;    \
203     (setup_pkt_ptr)->wLength = 0;   \
204 })
205 
206 /**
207  * @brief Initializer for a request to set an interface's alternate setting
208  */
209 #define USB_SETUP_PACKET_INIT_SET_INTERFACE(setup_pkt_ptr, intf_num, alt_setting_num) ({    \
210     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_INTERFACE;  \
211     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_SET_INTERFACE; \
212     (setup_pkt_ptr)->wValue = (alt_setting_num); \
213     (setup_pkt_ptr)->wIndex = (intf_num);  \
214     (setup_pkt_ptr)->wLength = 0;   \
215 })
216 
217 /**
218  * @brief Initializer for a request to get an string descriptor
219  */
220 #define USB_SETUP_PACKET_INIT_GET_STR_DESC(setup_pkt_ptr, string_index, lang_id, desc_len) ({ \
221     (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE; \
222     (setup_pkt_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR; \
223     (setup_pkt_ptr)->wValue = (USB_W_VALUE_DT_STRING << 8) | ((string_index) & 0xFF); \
224     (setup_pkt_ptr)->wIndex = (lang_id); \
225     (setup_pkt_ptr)->wLength = (desc_len); \
226 })
227 
228 // ---------------- Standard Descriptor --------------------
229 
230 /**
231  * @brief Size of dummy USB standard descriptor
232  */
233 #define USB_STANDARD_DESC_SIZE              2
234 
235 /**
236  * @brief USB standard descriptor
237  *
238  * All USB standard descriptors start with these two bytes. Use this type when traversing over configuration descriptors
239  */
240 typedef union {
241     struct {
242         uint8_t bLength;                    /**< Size of the descriptor in bytes */
243         uint8_t bDescriptorType;            /**< Descriptor Type */
244     } USB_DESC_ATTR;
245     uint8_t val[USB_STANDARD_DESC_SIZE];
246 } usb_standard_desc_t;
247 _Static_assert(sizeof(usb_standard_desc_t) == USB_STANDARD_DESC_SIZE, "Size of usb_standard_desc_t incorrect");
248 
249 // ------------------ Device Descriptor --------------------
250 
251 /**
252  * @brief Size of a USB device descriptor in bytes
253  */
254 #define USB_DEVICE_DESC_SIZE                18
255 
256 /**
257  * @brief Structure representing a USB device descriptor
258  *
259  * See Table 9-8 of USB2.0 specification for more details
260  */
261 typedef union {
262     struct {
263         uint8_t bLength;                    /**< Size of the descriptor in bytes */
264         uint8_t bDescriptorType;            /**< DEVICE Descriptor Type */
265         uint16_t bcdUSB;                    /**< USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H) */
266         uint8_t bDeviceClass;               /**< Class code (assigned by the USB-IF) */
267         uint8_t bDeviceSubClass;            /**< Subclass code (assigned by the USB-IF) */
268         uint8_t bDeviceProtocol;            /**< Protocol code (assigned by the USB-IF) */
269         uint8_t bMaxPacketSize0;            /**< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid) */
270         uint16_t idVendor;                  /**< Vendor ID (assigned by the USB-IF) */
271         uint16_t idProduct;                 /**< Product ID (assigned by the manufacturer) */
272         uint16_t bcdDevice;                 /**< Device release number in binary-coded decimal */
273         uint8_t iManufacturer;              /**< Index of string descriptor describing manufacturer */
274         uint8_t iProduct;                   /**< Index of string descriptor describing product */
275         uint8_t iSerialNumber;              /**< Index of string descriptor describing the device’s serial number */
276         uint8_t bNumConfigurations;         /**< Number of possible configurations */
277     } USB_DESC_ATTR;
278     uint8_t val[USB_DEVICE_DESC_SIZE];
279 } usb_device_desc_t;
280 _Static_assert(sizeof(usb_device_desc_t) == USB_DEVICE_DESC_SIZE, "Size of usb_device_desc_t incorrect");
281 
282 /**
283  * @brief Possible base class values of the bDeviceClass field of a USB device descriptor
284  */
285 #define USB_CLASS_PER_INTERFACE             0x00
286 #define USB_CLASS_AUDIO                     0x01
287 #define USB_CLASS_COMM                      0x02
288 #define USB_CLASS_HID                       0x03
289 #define USB_CLASS_PHYSICAL                  0x05
290 #define USB_CLASS_STILL_IMAGE               0x06
291 #define USB_CLASS_PRINTER                   0x07
292 #define USB_CLASS_MASS_STORAGE              0x08
293 #define USB_CLASS_HUB                       0x09
294 #define USB_CLASS_CDC_DATA                  0x0a
295 #define USB_CLASS_CSCID                     0x0b
296 #define USB_CLASS_CONTENT_SEC               0x0d
297 #define USB_CLASS_VIDEO                     0x0e
298 #define USB_CLASS_WIRELESS_CONTROLLER       0xe0
299 #define USB_CLASS_PERSONAL_HEALTHCARE       0x0f
300 #define USB_CLASS_AUDIO_VIDEO               0x10
301 #define USB_CLASS_BILLBOARD                 0x11
302 #define USB_CLASS_USB_TYPE_C_BRIDGE         0x12
303 #define USB_CLASS_MISC                      0xef
304 #define USB_CLASS_APP_SPEC                  0xfe
305 #define USB_CLASS_VENDOR_SPEC               0xff
306 
307 /**
308  * @brief Vendor specific subclass code
309  */
310 #define USB_SUBCLASS_VENDOR_SPEC            0xff
311 
312 // -------------- Configuration Descriptor -----------------
313 
314 /**
315  * @brief Size of a short USB configuration descriptor in bytes
316  *
317  * @note The size of a full USB configuration includes all the interface and endpoint
318  *       descriptors of that configuration.
319  */
320 #define USB_CONFIG_DESC_SIZE        9
321 
322 /**
323  * @brief Structure representing a short USB configuration descriptor
324  *
325  * See Table 9-10 of USB2.0 specification for more details
326  *
327  * @note The full USB configuration includes all the interface and endpoint
328  *       descriptors of that configuration.
329  */
330 typedef union {
331     struct {
332         uint8_t bLength;                    /**< Size of the descriptor in bytes */
333         uint8_t bDescriptorType;            /**< CONFIGURATION Descriptor Type */
334         uint16_t wTotalLength;              /**< Total length of data returned for this configuration */
335         uint8_t bNumInterfaces;             /**< Number of interfaces supported by this configuration */
336         uint8_t bConfigurationValue;        /**< Value to use as an argument to the SetConfiguration() request to select this configuration */
337         uint8_t iConfiguration;             /**< Index of string descriptor describing this configuration */
338         uint8_t bmAttributes;               /**< Configuration characteristics */
339         uint8_t bMaxPower;                  /**< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. */
340     } USB_DESC_ATTR;
341     uint8_t val[USB_CONFIG_DESC_SIZE];
342 } usb_config_desc_t;
343 _Static_assert(sizeof(usb_config_desc_t) == USB_CONFIG_DESC_SIZE, "Size of usb_config_desc_t incorrect");
344 
345 /**
346  * @brief Bit masks belonging to the bmAttributes field of a configuration descriptor
347  */
348 #define USB_BM_ATTRIBUTES_ONE               (1 << 7)    //Must be set
349 #define USB_BM_ATTRIBUTES_SELFPOWER         (1 << 6)    //Self powered
350 #define USB_BM_ATTRIBUTES_WAKEUP            (1 << 5)    //Can wake-up
351 #define USB_BM_ATTRIBUTES_BATTERY           (1 << 4)    //Battery powered
352 
353 // ---------- Interface Association Descriptor -------------
354 
355 /**
356  * @brief Size of a USB interface association descriptor in bytes
357  */
358 #define USB_IAD_DESC_SIZE    9
359 
360 /**
361  * @brief Structure representing a USB interface association descriptor
362  */
363 typedef union {
364     struct {
365         uint8_t bLength;                    /**< Size of the descriptor in bytes */
366         uint8_t bDescriptorType;            /**< INTERFACE ASSOCIATION Descriptor Type */
367         uint8_t bFirstInterface;            /**< Interface number of the first interface that is associated with this function */
368         uint8_t bInterfaceCount;            /**< Number of contiguous interfaces that are associated with this function */
369         uint8_t bFunctionClass;             /**< Class code (assigned by USB-IF) */
370         uint8_t bFunctionSubClass;          /**< Subclass code (assigned by USB-IF) */
371         uint8_t bFunctionProtocol;          /**< Protocol code (assigned by USB-IF) */
372         uint8_t iFunction;                  /**< Index of string descriptor describing this function */
373     } USB_DESC_ATTR;
374     uint8_t val[USB_IAD_DESC_SIZE];
375 } usb_iad_desc_t;
376 _Static_assert(sizeof(usb_iad_desc_t) == USB_IAD_DESC_SIZE, "Size of usb_iad_desc_t incorrect");
377 
378 // ---------------- Interface Descriptor -------------------
379 
380 /**
381  * @brief Size of a USB interface descriptor in bytes
382  */
383 #define USB_INTF_DESC_SIZE      9
384 
385 /**
386  * @brief Structure representing a USB interface descriptor
387  *
388  * See Table 9-12 of USB2.0 specification for more details
389  */
390 typedef union {
391     struct {
392         uint8_t bLength;                    /**< Size of the descriptor in bytes */
393         uint8_t bDescriptorType;            /**< INTERFACE Descriptor Type */
394         uint8_t bInterfaceNumber;           /**< Number of this interface. */
395         uint8_t bAlternateSetting;          /**< Value used to select this alternate setting for the interface identified in the prior field */
396         uint8_t bNumEndpoints;              /**< Number of endpoints used by this interface (excluding endpoint zero). */
397         uint8_t bInterfaceClass;            /**< Class code (assigned by the USB-IF) */
398         uint8_t bInterfaceSubClass;         /**< Subclass code (assigned by the USB-IF) */
399         uint8_t bInterfaceProtocol;         /**< Protocol code (assigned by the USB) */
400         uint8_t iInterface;                 /**< Index of string descriptor describing this interface */
401     } USB_DESC_ATTR;
402     uint8_t val[USB_INTF_DESC_SIZE];
403 } usb_intf_desc_t;
404 _Static_assert(sizeof(usb_intf_desc_t) == USB_INTF_DESC_SIZE, "Size of usb_intf_desc_t incorrect");
405 
406 // ----------------- Endpoint Descriptor -------------------
407 
408 /**
409  * @brief Size of a USB endpoint descriptor in bytes
410  */
411 #define USB_EP_DESC_SIZE        7
412 
413 /**
414  * @brief Structure representing a USB endpoint descriptor
415  *
416  * See Table 9-13 of USB2.0 specification for more details
417  */
418 typedef union {
419     struct {
420         uint8_t bLength;                    /**< Size of the descriptor in bytes */
421         uint8_t bDescriptorType;            /**< ENDPOINT Descriptor Type */
422         uint8_t bEndpointAddress;           /**< The address of the endpoint on the USB device described by this descriptor */
423         uint8_t bmAttributes;               /**< This field describes the endpoint’s attributes when it is configured using the bConfigurationValue. */
424         uint16_t wMaxPacketSize;            /**< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. */
425         uint8_t bInterval;                  /**< Interval for polling Isochronous and Interrupt endpoints. Expressed in frames or microframes depending on the device operating speed (1 ms for Low-Speed and Full-Speed or 125 us for USB High-Speed and above). */
426     } USB_DESC_ATTR;
427     uint8_t val[USB_EP_DESC_SIZE];
428 } usb_ep_desc_t;
429 _Static_assert(sizeof(usb_ep_desc_t) == USB_EP_DESC_SIZE, "Size of usb_ep_desc_t incorrect");
430 
431 /**
432  * @brief Bit masks belonging to the bEndpointAddress field of an endpoint descriptor
433  */
434 #define USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK              0x0f
435 #define USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK              0x80
436 
437 /**
438  * @brief Bit masks belonging to the bmAttributes field of an endpoint descriptor
439  */
440 #define USB_BM_ATTRIBUTES_XFERTYPE_MASK                 0x03
441 #define USB_BM_ATTRIBUTES_XFER_CONTROL                  (0 << 0)
442 #define USB_BM_ATTRIBUTES_XFER_ISOC                     (1 << 0)
443 #define USB_BM_ATTRIBUTES_XFER_BULK                     (2 << 0)
444 #define USB_BM_ATTRIBUTES_XFER_INT                      (3 << 0)
445 #define USB_BM_ATTRIBUTES_SYNCTYPE_MASK                 0x0C    /* in bmAttributes */
446 #define USB_BM_ATTRIBUTES_SYNC_NONE                     (0 << 2)
447 #define USB_BM_ATTRIBUTES_SYNC_ASYNC                    (1 << 2)
448 #define USB_BM_ATTRIBUTES_SYNC_ADAPTIVE                 (2 << 2)
449 #define USB_BM_ATTRIBUTES_SYNC_SYNC                     (3 << 2)
450 #define USB_BM_ATTRIBUTES_USAGETYPE_MASK                0x30
451 #define USB_BM_ATTRIBUTES_USAGE_DATA                    (0 << 4)
452 #define USB_BM_ATTRIBUTES_USAGE_FEEDBACK                (1 << 4)
453 #define USB_BM_ATTRIBUTES_USAGE_IMPLICIT_FB             (2 << 4)
454 
455 /**
456  * @brief Macro helpers to get information about an endpoint from its descriptor
457  */
458 #define USB_EP_DESC_GET_XFERTYPE(desc_ptr) ((usb_transfer_type_t) ((desc_ptr)->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK))
459 #define USB_EP_DESC_GET_EP_NUM(desc_ptr) ((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK)
460 #define USB_EP_DESC_GET_EP_DIR(desc_ptr) (((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) ? 1 : 0)
461 #define USB_EP_DESC_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & 0x7FF)
462 
463 // ------------------ String Descriptor --------------------
464 
465 /**
466  * @brief Size of a short USB string descriptor in bytes
467  */
468 #define USB_STR_DESC_SIZE       2
469 
470 /**
471  * @brief Structure representing a USB string descriptor
472  */
473 typedef union {
474     struct {
475         uint8_t bLength;                    /**< Size of the descriptor in bytes */
476         uint8_t bDescriptorType;            /**< STRING Descriptor Type */
477         uint16_t wData[];                   /**< UTF-16LE encoded */
478     } USB_DESC_ATTR;
479     uint8_t val[USB_STR_DESC_SIZE];
480 } usb_str_desc_t;
481 _Static_assert(sizeof(usb_str_desc_t) == USB_STR_DESC_SIZE, "Size of usb_str_desc_t incorrect");
482 
483 #ifdef __cplusplus
484 }
485 #endif
486