1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief New experimental USB device stack APIs and structures
10 *
11 * This file contains the USB device stack APIs and structures.
12 */
13
14 #ifndef ZEPHYR_INCLUDE_USBD_H_
15 #define ZEPHYR_INCLUDE_USBD_H_
16
17 #include <zephyr/device.h>
18 #include <zephyr/usb/bos.h>
19 #include <zephyr/usb/usb_ch9.h>
20 #include <zephyr/usb/usbd_msg.h>
21 #include <zephyr/drivers/usb/udc_buf.h>
22 #include <zephyr/sys/byteorder.h>
23 #include <zephyr/sys/slist.h>
24 #include <zephyr/logging/log.h>
25 #include <zephyr/sys/iterable_sections.h>
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 /**
32 * @brief New USB device stack core API
33 * @defgroup usbd_api USB device core API
34 * @ingroup usb
35 * @since 3.3
36 * @version 0.1.0
37 * @{
38 */
39
40 /*
41 * The USB Unicode bString is encoded in UTF16LE, which means it takes up
42 * twice the amount of bytes than the same string encoded in ASCII7.
43 * Use this macro to determine the length of the bString array.
44 *
45 * bString length without null character:
46 * bString_length = (sizeof(initializer_string) - 1) * 2
47 * or:
48 * bString_length = sizeof(initializer_string) * 2 - 2
49 */
50 #define USB_BSTRING_LENGTH(s) (sizeof(s) * 2 - 2)
51
52 /*
53 * The length of the string descriptor (bLength) is calculated from the
54 * size of the two octets bLength and bDescriptorType plus the
55 * length of the UTF16LE string:
56 *
57 * bLength = 2 + bString_length
58 * bLength = 2 + sizeof(initializer_string) * 2 - 2
59 * bLength = sizeof(initializer_string) * 2
60 * Use this macro to determine the bLength of the string descriptor.
61 */
62 #define USB_STRING_DESCRIPTOR_LENGTH(s) (sizeof(s) * 2)
63
64 struct usbd_context;
65
66 /** Used internally to keep descriptors in order
67 * @cond INTERNAL_HIDDEN
68 */
69 enum usbd_str_desc_utype {
70 USBD_DUT_STRING_LANG,
71 USBD_DUT_STRING_MANUFACTURER,
72 USBD_DUT_STRING_PRODUCT,
73 USBD_DUT_STRING_SERIAL_NUMBER,
74 USBD_DUT_STRING_CONFIG,
75 USBD_DUT_STRING_INTERFACE,
76 };
77
78 enum usbd_bos_desc_utype {
79 USBD_DUT_BOS_NONE,
80 USBD_DUT_BOS_VREQ,
81 };
82 /** @endcond */
83
84 /**
85 * USBD string descriptor data
86 */
87 struct usbd_str_desc_data {
88 /** Descriptor index, required for string descriptors */
89 uint8_t idx;
90 /** Descriptor usage type (not bDescriptorType) */
91 enum usbd_str_desc_utype utype : 8;
92 /** The string descriptor is in ASCII7 format */
93 unsigned int ascii7 : 1;
94 /** Device stack obtains SerialNumber using the HWINFO API */
95 unsigned int use_hwinfo : 1;
96 };
97
98 /**
99 * USBD vendor request node
100 *
101 * Vendor request node is identified by the vendor code and is used to register
102 * callbacks to handle the vendor request with the receiving device.
103 * When the device stack receives a request with type Vendor and recipient
104 * Device, and bRequest value equal to the vendor request code, it will call
105 * the vendor callbacks depending on the direction of the request.
106 *
107 * Example callback code fragment:
108 *
109 * @code{.c}
110 * static int foo_to_host_cb(const struct usbd_context *const ctx,
111 * const struct usb_setup_packet *const setup,
112 * struct net_buf *const buf)
113 * {
114 * if (setup->wIndex == WEBUSB_REQ_GET_URL) {
115 * uint8_t index = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
116 *
117 * if (index != SAMPLE_WEBUSB_LANDING_PAGE) {
118 * return -ENOTSUP;
119 * }
120 *
121 * net_buf_add_mem(buf, &webusb_origin_url,
122 * MIN(net_buf_tailroom(buf), sizeof(webusb_origin_url)));
123 *
124 * return 0;
125 * }
126 *
127 * return -ENOTSUP;
128 * }
129 * @endcode
130 */
131 struct usbd_vreq_node {
132 /** Node information for the dlist */
133 sys_dnode_t node;
134 /** Vendor code (bRequest value) */
135 const uint8_t code;
136 /** Vendor request callback for device-to-host direction */
137 int (*to_host)(const struct usbd_context *const ctx,
138 const struct usb_setup_packet *const setup,
139 struct net_buf *const buf);
140 /** Vendor request callback for host-to-device direction */
141 int (*to_dev)(const struct usbd_context *const ctx,
142 const struct usb_setup_packet *const setup,
143 const struct net_buf *const buf);
144 };
145
146 /**
147 * USBD BOS Device Capability descriptor data
148 */
149 struct usbd_bos_desc_data {
150 /** Descriptor usage type (not bDescriptorType) */
151 enum usbd_bos_desc_utype utype : 8;
152 union {
153 struct usbd_vreq_node *const vreq_nd;
154 };
155 };
156
157 /**
158 * Descriptor node
159 *
160 * Descriptor node is used to manage descriptors that are not
161 * directly part of a structure, such as string or BOS capability descriptors.
162 */
163 struct usbd_desc_node {
164 /** slist node struct */
165 sys_dnode_t node;
166 union {
167 struct usbd_str_desc_data str;
168 struct usbd_bos_desc_data bos;
169 };
170 /** Opaque pointer to a descriptor payload */
171 const void *const ptr;
172 /** Descriptor size in bytes */
173 uint8_t bLength;
174 /** Descriptor type */
175 uint8_t bDescriptorType;
176 };
177
178 /**
179 * Device configuration node
180 *
181 * Configuration node is used to manage device configurations,
182 * at least one configuration is required. It does not have an index,
183 * instead bConfigurationValue of the descriptor is used for
184 * identification.
185 */
186 struct usbd_config_node {
187 /** slist node struct */
188 sys_snode_t node;
189 /** Pointer to configuration descriptor */
190 void *desc;
191 /** Optional pointer to string descriptor node */
192 struct usbd_desc_node *str_desc_nd;
193 /** List of registered classes (functions) */
194 sys_slist_t class_list;
195 };
196
197 /* TODO: Kconfig option USBD_NUMOF_INTERFACES_MAX? */
198 #define USBD_NUMOF_INTERFACES_MAX 16U
199
200 /**
201 * USB device support middle layer runtime state
202 *
203 * Part of USB device states without suspended and powered
204 * states, as it is better to track them separately.
205 */
206 enum usbd_ch9_state {
207 USBD_STATE_DEFAULT = 0,
208 USBD_STATE_ADDRESS,
209 USBD_STATE_CONFIGURED,
210 };
211
212
213 /**
214 * USB device support middle layer runtime data
215 */
216 struct usbd_ch9_data {
217 /** Setup packet, up-to-date for the respective control request */
218 struct usb_setup_packet setup;
219 /** Control type, internally used for stage verification */
220 int ctrl_type;
221 /** Protocol state of the USB device stack */
222 enum usbd_ch9_state state;
223 /** Halted endpoints bitmap */
224 uint32_t ep_halt;
225 /** USB device stack selected configuration */
226 uint8_t configuration;
227 /** Post status stage work required, e.g. set new device address */
228 bool post_status;
229 /** Array to track interfaces alternate settings */
230 uint8_t alternate[USBD_NUMOF_INTERFACES_MAX];
231 };
232
233 /**
234 * @brief USB device speed
235 */
236 enum usbd_speed {
237 /** Device supports or is connected to a full speed bus */
238 USBD_SPEED_FS,
239 /** Device supports or is connected to a high speed bus */
240 USBD_SPEED_HS,
241 /** Device supports or is connected to a super speed bus */
242 USBD_SPEED_SS,
243 };
244
245 /**
246 * USB device support status
247 */
248 struct usbd_status {
249 /** USB device support is initialized */
250 unsigned int initialized : 1;
251 /** USB device support is enabled */
252 unsigned int enabled : 1;
253 /** USB device is suspended */
254 unsigned int suspended : 1;
255 /** USB remote wake-up feature is enabled */
256 unsigned int rwup : 1;
257 /** USB device speed */
258 enum usbd_speed speed : 2;
259 };
260
261 /**
262 * @brief Callback type definition for USB device message delivery
263 *
264 * The implementation uses the system workqueue, and a callback provided and
265 * registered by the application. The application callback is called in the
266 * context of the system workqueue. Notification messages are stored in a queue
267 * and delivered to the callback in sequence.
268 *
269 * @param[in] ctx Pointer to USB device support context
270 * @param[in] msg Pointer to USB device message
271 */
272 typedef void (*usbd_msg_cb_t)(struct usbd_context *const ctx,
273 const struct usbd_msg *const msg);
274
275 /**
276 * USB device support runtime context
277 *
278 * Main structure that organizes all descriptors, configuration,
279 * and interfaces. An UDC device must be assigned to this structure.
280 */
281 struct usbd_context {
282 /** Name of the USB device */
283 const char *name;
284 /** Access mutex */
285 struct k_mutex mutex;
286 /** Pointer to UDC device */
287 const struct device *dev;
288 /** Notification message recipient callback */
289 usbd_msg_cb_t msg_cb;
290 /** Middle layer runtime data */
291 struct usbd_ch9_data ch9_data;
292 /** slist to manage descriptors like string, BOS */
293 sys_dlist_t descriptors;
294 /** slist to manage Full-Speed device configurations */
295 sys_slist_t fs_configs;
296 /** slist to manage High-Speed device configurations */
297 sys_slist_t hs_configs;
298 /** dlist to manage vendor requests with recipient device */
299 sys_dlist_t vreqs;
300 /** Status of the USB device support */
301 struct usbd_status status;
302 /** Pointer to Full-Speed device descriptor */
303 void *fs_desc;
304 /** Pointer to High-Speed device descriptor */
305 void *hs_desc;
306 };
307
308 /**
309 * @brief Vendor Requests Table
310 */
311 struct usbd_cctx_vendor_req {
312 /** Array of vendor requests supported by the class */
313 const uint8_t *reqs;
314 /** Length of the array */
315 uint8_t len;
316 };
317
318 /** USB Class instance registered flag */
319 #define USBD_CCTX_REGISTERED 0
320
321 struct usbd_class_data;
322
323 /**
324 * @brief USB device support class instance API
325 */
326 struct usbd_class_api {
327 /** Feature halt state update handler */
328 void (*feature_halt)(struct usbd_class_data *const c_data,
329 uint8_t ep, bool halted);
330
331 /** Configuration update handler */
332 void (*update)(struct usbd_class_data *const c_data,
333 uint8_t iface, uint8_t alternate);
334
335 /** USB control request handler to device */
336 int (*control_to_dev)(struct usbd_class_data *const c_data,
337 const struct usb_setup_packet *const setup,
338 const struct net_buf *const buf);
339
340 /** USB control request handler to host */
341 int (*control_to_host)(struct usbd_class_data *const c_data,
342 const struct usb_setup_packet *const setup,
343 struct net_buf *const buf);
344
345 /** Endpoint request completion event handler */
346 int (*request)(struct usbd_class_data *const c_data,
347 struct net_buf *buf, int err);
348
349 /** USB power management handler suspended */
350 void (*suspended)(struct usbd_class_data *const c_data);
351
352 /** USB power management handler resumed */
353 void (*resumed)(struct usbd_class_data *const c_data);
354
355 /** Start of Frame */
356 void (*sof)(struct usbd_class_data *const c_data);
357
358 /** Class associated configuration is selected */
359 void (*enable)(struct usbd_class_data *const c_data);
360
361 /** Class associated configuration is disabled */
362 void (*disable)(struct usbd_class_data *const c_data);
363
364 /** Initialization of the class implementation */
365 int (*init)(struct usbd_class_data *const c_data);
366
367 /** Shutdown of the class implementation */
368 void (*shutdown)(struct usbd_class_data *const c_data);
369
370 /** Get function descriptor based on speed parameter */
371 void *(*get_desc)(struct usbd_class_data *const c_data,
372 const enum usbd_speed speed);
373 };
374
375 /**
376 * @brief USB device support class data
377 */
378 struct usbd_class_data {
379 /** Name of the USB device class instance */
380 const char *name;
381 /** Pointer to USB device stack context structure */
382 struct usbd_context *uds_ctx;
383 /** Pointer to device support class API */
384 const struct usbd_class_api *api;
385 /** Supported vendor request table, can be NULL */
386 const struct usbd_cctx_vendor_req *v_reqs;
387 /** Pointer to private data */
388 void *priv;
389 };
390
391 /**
392 * @cond INTERNAL_HIDDEN
393 *
394 * Variables necessary for per speed class management. For each speed (Full,
395 * High) there is separate `struct usbd_class_node` pointing to the same
396 * `struct usbd_class_data` (because the class can only operate at one speed
397 * at a time).
398 */
399 struct usbd_class_node {
400 /** Node information for the slist. */
401 sys_snode_t node;
402 /** Pointer to public class node instance. */
403 struct usbd_class_data *const c_data;
404 /** Bitmap of all endpoints assigned to the instance.
405 * The IN endpoints are mapped in the upper halfword.
406 */
407 uint32_t ep_assigned;
408 /** Bitmap of the enabled endpoints of the instance.
409 * The IN endpoints are mapped in the upper halfword.
410 */
411 uint32_t ep_active;
412 /** Bitmap of the bInterfaceNumbers of the class instance */
413 uint32_t iface_bm;
414 /** Variable to store the state of the class instance */
415 atomic_t state;
416 };
417
418 /** @endcond */
419
420 /**
421 * @brief Get the USB device runtime context under which the class is registered
422 *
423 * The class implementation must use this function and not access the members
424 * of the struct directly.
425 *
426 * @param[in] c_data Pointer to USB device class data
427 *
428 * @return Pointer to USB device runtime context
429 */
usbd_class_get_ctx(const struct usbd_class_data * const c_data)430 static inline struct usbd_context *usbd_class_get_ctx(const struct usbd_class_data *const c_data)
431 {
432 return c_data->uds_ctx;
433 }
434
435 /**
436 * @brief Get class implementation private data
437 *
438 * The class implementation must use this function and not access the members
439 * of the struct directly.
440 *
441 * @param[in] c_data Pointer to USB device class data
442 *
443 * @return Pointer to class implementation private data
444 */
usbd_class_get_private(const struct usbd_class_data * const c_data)445 static inline void *usbd_class_get_private(const struct usbd_class_data *const c_data)
446 {
447 return c_data->priv;
448 }
449
450 /**
451 * @brief Define USB device context structure
452 *
453 * Macro defines a USB device structure needed by the stack to manage its
454 * properties and runtime data. The @p vid and @p pid parameters can also be
455 * changed using usbd_device_set_vid() and usbd_device_set_pid().
456 *
457 * Example of use:
458 *
459 * @code{.c}
460 * USBD_DEVICE_DEFINE(sample_usbd,
461 * DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
462 * YOUR_VID, YOUR_PID);
463 * @endcode
464 *
465 * @param device_name USB device context name
466 * @param udc_dev Pointer to UDC device structure
467 * @param vid Vendor ID
468 * @param pid Product ID
469 */
470 #define USBD_DEVICE_DEFINE(device_name, udc_dev, vid, pid) \
471 static struct usb_device_descriptor \
472 fs_desc_##device_name = { \
473 .bLength = sizeof(struct usb_device_descriptor), \
474 .bDescriptorType = USB_DESC_DEVICE, \
475 .bcdUSB = sys_cpu_to_le16(USB_SRN_2_0), \
476 .bDeviceClass = USB_BCC_MISCELLANEOUS, \
477 .bDeviceSubClass = 2, \
478 .bDeviceProtocol = 1, \
479 .bMaxPacketSize0 = USB_CONTROL_EP_MPS, \
480 .idVendor = vid, \
481 .idProduct = pid, \
482 .bcdDevice = sys_cpu_to_le16(USB_BCD_DRN), \
483 .iManufacturer = 0, \
484 .iProduct = 0, \
485 .iSerialNumber = 0, \
486 .bNumConfigurations = 0, \
487 }; \
488 static struct usb_device_descriptor \
489 hs_desc_##device_name = { \
490 .bLength = sizeof(struct usb_device_descriptor), \
491 .bDescriptorType = USB_DESC_DEVICE, \
492 .bcdUSB = sys_cpu_to_le16(USB_SRN_2_0), \
493 .bDeviceClass = USB_BCC_MISCELLANEOUS, \
494 .bDeviceSubClass = 2, \
495 .bDeviceProtocol = 1, \
496 .bMaxPacketSize0 = 64, \
497 .idVendor = vid, \
498 .idProduct = pid, \
499 .bcdDevice = sys_cpu_to_le16(USB_BCD_DRN), \
500 .iManufacturer = 0, \
501 .iProduct = 0, \
502 .iSerialNumber = 0, \
503 .bNumConfigurations = 0, \
504 }; \
505 static STRUCT_SECTION_ITERABLE(usbd_context, device_name) = { \
506 .name = STRINGIFY(device_name), \
507 .dev = udc_dev, \
508 .fs_desc = &fs_desc_##device_name, \
509 .hs_desc = &hs_desc_##device_name, \
510 }
511
512 /**
513 * @brief Define USB device configuration
514 *
515 * USB device requires at least one configuration instance per supported speed.
516 * @p attrib is a combination of `USB_SCD_SELF_POWERED` or `USB_SCD_REMOTE_WAKEUP`,
517 * depending on which characteristic the USB device should have in this
518 * configuration.
519 *
520 * @param name Configuration name
521 * @param attrib Configuration characteristics. Attributes can also be updated
522 * with usbd_config_attrib_rwup() and usbd_config_attrib_self()
523 * @param power bMaxPower value in 2 mA units. This value can also be set with
524 * usbd_config_maxpower()
525 * @param desc_nd Address of the string descriptor node used to describe the
526 * configuration, see USBD_DESC_CONFIG_DEFINE().
527 * String descriptors are optional and the parameter can be NULL.
528 */
529 #define USBD_CONFIGURATION_DEFINE(name, attrib, power, desc_nd) \
530 static struct usb_cfg_descriptor \
531 cfg_desc_##name = { \
532 .bLength = sizeof(struct usb_cfg_descriptor), \
533 .bDescriptorType = USB_DESC_CONFIGURATION, \
534 .wTotalLength = 0, \
535 .bNumInterfaces = 0, \
536 .bConfigurationValue = 1, \
537 .iConfiguration = 0, \
538 .bmAttributes = USB_SCD_RESERVED | (attrib), \
539 .bMaxPower = (power), \
540 }; \
541 BUILD_ASSERT((power) < 256, "Too much power"); \
542 static struct usbd_config_node name = { \
543 .desc = &cfg_desc_##name, \
544 .str_desc_nd = desc_nd, \
545 }
546
547 /**
548 * @brief Create a string descriptor node and language string descriptor
549 *
550 * This macro defines a descriptor node and a string descriptor that,
551 * when added to the device context, is automatically used as the language
552 * string descriptor zero. Both descriptor node and descriptor are defined with
553 * static-storage-class specifier. Default and currently only supported
554 * language ID is 0x0409 English (United States).
555 * If string descriptors are used, it is necessary to add this descriptor
556 * as the first one to the USB device context.
557 *
558 * @param name Language string descriptor node identifier.
559 */
560 #define USBD_DESC_LANG_DEFINE(name) \
561 static uint16_t langid_##name = sys_cpu_to_le16(0x0409); \
562 static struct usbd_desc_node name = { \
563 .str = { \
564 .idx = 0, \
565 .utype = USBD_DUT_STRING_LANG, \
566 }, \
567 .ptr = &langid_##name, \
568 .bLength = sizeof(struct usb_string_descriptor), \
569 .bDescriptorType = USB_DESC_STRING, \
570 }
571
572 /**
573 * @brief Create a string descriptor
574 *
575 * This macro defines a descriptor node and a string descriptor.
576 * The string literal passed to the macro should be in the ASCII7 format. It
577 * is converted to UTF16LE format on the host request.
578 *
579 * @param d_name Internal string descriptor node identifier name
580 * @param d_string ASCII7 encoded string literal
581 * @param d_utype String descriptor usage type
582 */
583 #define USBD_DESC_STRING_DEFINE(d_name, d_string, d_utype) \
584 static uint8_t ascii_##d_name[USB_BSTRING_LENGTH(d_string)] = d_string; \
585 static struct usbd_desc_node d_name = { \
586 .str = { \
587 .utype = d_utype, \
588 .ascii7 = true, \
589 }, \
590 .ptr = &ascii_##d_name, \
591 .bLength = USB_STRING_DESCRIPTOR_LENGTH(d_string), \
592 .bDescriptorType = USB_DESC_STRING, \
593 }
594
595 /**
596 * @brief Create a string descriptor node and manufacturer string descriptor
597 *
598 * This macro defines a descriptor node and a string descriptor that,
599 * when added to the device context, is automatically used as the manufacturer
600 * string descriptor. Both descriptor node and descriptor are defined with
601 * static-storage-class specifier.
602 *
603 * @param d_name String descriptor node identifier.
604 * @param d_string ASCII7 encoded manufacturer string literal
605 */
606 #define USBD_DESC_MANUFACTURER_DEFINE(d_name, d_string) \
607 USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_MANUFACTURER)
608
609 /**
610 * @brief Create a string descriptor node and product string descriptor
611 *
612 * This macro defines a descriptor node and a string descriptor that,
613 * when added to the device context, is automatically used as the product
614 * string descriptor. Both descriptor node and descriptor are defined with
615 * static-storage-class specifier.
616 *
617 * @param d_name String descriptor node identifier.
618 * @param d_string ASCII7 encoded product string literal
619 */
620 #define USBD_DESC_PRODUCT_DEFINE(d_name, d_string) \
621 USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_PRODUCT)
622
623 /**
624 * @brief Create a string descriptor node and serial number string descriptor
625 *
626 * This macro defines a descriptor node that, when added to the device context,
627 * is automatically used as the serial number string descriptor. A valid serial
628 * number is generated from HWID (HWINFO= whenever this string descriptor is
629 * requested.
630 *
631 * @param d_name String descriptor node identifier.
632 */
633 #define USBD_DESC_SERIAL_NUMBER_DEFINE(d_name) \
634 static struct usbd_desc_node d_name = { \
635 .str = { \
636 .utype = USBD_DUT_STRING_SERIAL_NUMBER, \
637 .ascii7 = true, \
638 .use_hwinfo = true, \
639 }, \
640 .bDescriptorType = USB_DESC_STRING, \
641 }
642
643 /**
644 * @brief Create a string descriptor node for configuration descriptor
645 *
646 * This macro defines a descriptor node whose address can be used as an
647 * argument for the USBD_CONFIGURATION_DEFINE() macro.
648 *
649 * @param d_name String descriptor node identifier.
650 * @param d_string ASCII7 encoded configuration description string literal
651 */
652 #define USBD_DESC_CONFIG_DEFINE(d_name, d_string) \
653 USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_CONFIG)
654
655 /**
656 * @brief Define BOS Device Capability descriptor node
657 *
658 * The application defines a BOS capability descriptor node for descriptors
659 * such as USB 2.0 Extension Descriptor.
660 *
661 * @param name Descriptor node identifier
662 * @param len Device Capability descriptor length
663 * @param subset Pointer to a Device Capability descriptor
664 */
665 #define USBD_DESC_BOS_DEFINE(name, len, subset) \
666 static struct usbd_desc_node name = { \
667 .bos = { \
668 .utype = USBD_DUT_BOS_NONE, \
669 }, \
670 .ptr = subset, \
671 .bLength = len, \
672 .bDescriptorType = USB_DESC_BOS, \
673 }
674
675 /**
676 * @brief Define a vendor request with recipient device
677 *
678 * @param name Vendor request identifier
679 * @param vcode Vendor request code
680 * @param vto_host Vendor callback for to-host direction request
681 * @param vto_dev Vendor callback for to-device direction request
682 */
683 #define USBD_VREQUEST_DEFINE(name, vcode, vto_host, vto_dev) \
684 static struct usbd_vreq_node name = { \
685 .code = vcode, \
686 .to_host = vto_host, \
687 .to_dev = vto_dev, \
688 }
689
690 /**
691 * @brief Define BOS Device Capability descriptor node with vendor request
692 *
693 * This macro defines a BOS descriptor, usually a platform capability, with a
694 * vendor request node.
695 *
696 * USBD_DESC_BOS_VREQ_DEFINE(bos_vreq_webusb, sizeof(bos_cap_webusb), &bos_cap_webusb,
697 * SAMPLE_WEBUSB_VENDOR_CODE, webusb_to_host_cb, NULL);
698 *
699 * @param name Descriptor node identifier
700 * @param len Device Capability descriptor length
701 * @param subset Pointer to a Device Capability descriptor
702 * @param vcode Vendor request code
703 * @param vto_host Vendor callback for to-host direction request
704 * @param vto_dev Vendor callback for to-device direction request
705 */
706 #define USBD_DESC_BOS_VREQ_DEFINE(name, len, subset, vcode, vto_host, vto_dev) \
707 USBD_VREQUEST_DEFINE(vreq_nd_##name, vcode, vto_host, vto_dev); \
708 static struct usbd_desc_node name = { \
709 .bos = { \
710 .utype = USBD_DUT_BOS_VREQ, \
711 .vreq_nd = &vreq_nd_##name, \
712 }, \
713 .ptr = subset, \
714 .bLength = len, \
715 .bDescriptorType = USB_DESC_BOS, \
716 }
717
718 /**
719 * @brief Define USB device support class data
720 *
721 * Macro defines class (function) data, as well as corresponding node
722 * structures used internally by the stack.
723 *
724 * @param class_name Class name
725 * @param class_api Pointer to struct usbd_class_api
726 * @param class_priv Class private data
727 * @param class_v_reqs Pointer to struct usbd_cctx_vendor_req
728 */
729 #define USBD_DEFINE_CLASS(class_name, class_api, class_priv, class_v_reqs) \
730 static struct usbd_class_data class_name = { \
731 .name = STRINGIFY(class_name), \
732 .api = class_api, \
733 .v_reqs = class_v_reqs, \
734 .priv = class_priv, \
735 }; \
736 static STRUCT_SECTION_ITERABLE_ALTERNATE( \
737 usbd_class_fs, usbd_class_node, class_name##_fs) = { \
738 .c_data = &class_name, \
739 }; \
740 static STRUCT_SECTION_ITERABLE_ALTERNATE( \
741 usbd_class_hs, usbd_class_node, class_name##_hs) = { \
742 .c_data = &class_name, \
743 }
744
745 /** @brief Helper to declare request table of usbd_cctx_vendor_req
746 *
747 * @param _reqs Pointer to the vendor request field
748 * @param _len Number of supported vendor requests
749 */
750 #define VENDOR_REQ_DEFINE(_reqs, _len) \
751 { \
752 .reqs = (const uint8_t *)(_reqs), \
753 .len = (_len), \
754 }
755
756 /** @brief Helper to declare supported vendor requests
757 *
758 * @param _reqs Variable number of vendor requests
759 */
760 #define USBD_VENDOR_REQ(_reqs...) \
761 VENDOR_REQ_DEFINE(((uint8_t []) { _reqs }), \
762 sizeof((uint8_t []) { _reqs }))
763
764
765 /**
766 * @brief Add common USB descriptor
767 *
768 * Add common descriptor like string or BOS Device Capability.
769 *
770 * @param[in] uds_ctx Pointer to USB device support context
771 * @param[in] dn Pointer to USB descriptor node
772 *
773 * @return 0 on success, other values on fail.
774 */
775 int usbd_add_descriptor(struct usbd_context *uds_ctx,
776 struct usbd_desc_node *dn);
777
778 /**
779 * @brief Get USB string descriptor index from descriptor node
780 *
781 * @param[in] desc_nd Pointer to USB descriptor node
782 *
783 * @return Descriptor index, 0 if descriptor is not part of any device
784 */
785 uint8_t usbd_str_desc_get_idx(const struct usbd_desc_node *const desc_nd);
786
787 /**
788 * @brief Remove USB string descriptor
789 *
790 * Remove linked USB string descriptor from any list.
791 *
792 * @param[in] desc_nd Pointer to USB descriptor node
793 */
794 void usbd_remove_descriptor(struct usbd_desc_node *const desc_nd);
795
796 /**
797 * @brief Add a USB device configuration
798 *
799 * @param[in] uds_ctx Pointer to USB device support context
800 * @param[in] speed Speed at which this configuration operates
801 * @param[in] cd Pointer to USB configuration node
802 *
803 * @return 0 on success, other values on fail.
804 */
805 int usbd_add_configuration(struct usbd_context *uds_ctx,
806 const enum usbd_speed speed,
807 struct usbd_config_node *cd);
808
809 /**
810 * @brief Register an USB class instance
811 *
812 * An USB class implementation can have one or more instances.
813 * To identify the instances we use device drivers API.
814 * Device names have a prefix derived from the name of the class,
815 * for example CDC_ACM for CDC ACM class instance,
816 * and can also be easily identified in the shell.
817 * Class instance can only be registered when the USB device stack
818 * is disabled.
819 * Registered instances are initialized at initialization
820 * of the USB device stack, and the interface descriptors
821 * of each instance are adapted to the whole context.
822 *
823 * @param[in] uds_ctx Pointer to USB device support context
824 * @param[in] name Class instance name
825 * @param[in] speed Configuration speed
826 * @param[in] cfg Configuration value (bConfigurationValue)
827 *
828 * @return 0 on success, other values on fail.
829 */
830 int usbd_register_class(struct usbd_context *uds_ctx,
831 const char *name,
832 const enum usbd_speed speed, uint8_t cfg);
833
834 /**
835 * @brief Register all available USB class instances
836 *
837 * Register all available instances. Like usbd_register_class, but does not
838 * take the instance name and instead registers all available instances.
839 *
840 * @note This cannot be combined. If your application calls
841 * usbd_register_class for any device, configuration number, or instance,
842 * either usbd_register_class or this function will fail.
843 *
844 * @param[in] uds_ctx Pointer to USB device support context
845 * @param[in] speed Configuration speed
846 * @param[in] cfg Configuration value (bConfigurationValue)
847 *
848 * @return 0 on success, other values on fail.
849 */
850 int usbd_register_all_classes(struct usbd_context *uds_ctx,
851 const enum usbd_speed speed, uint8_t cfg);
852
853 /**
854 * @brief Unregister an USB class instance
855 *
856 * USB class instance will be removed and will not appear
857 * on the next start of the stack. Instance can only be unregistered
858 * when the USB device stack is disabled.
859 *
860 * @param[in] uds_ctx Pointer to USB device support context
861 * @param[in] name Class instance name
862 * @param[in] speed Configuration speed
863 * @param[in] cfg Configuration value (bConfigurationValue)
864 *
865 * @return 0 on success, other values on fail.
866 */
867 int usbd_unregister_class(struct usbd_context *uds_ctx,
868 const char *name,
869 const enum usbd_speed speed, uint8_t cfg);
870
871 /**
872 * @brief Unregister all available USB class instances
873 *
874 * Unregister all available instances. Like usbd_unregister_class, but does not
875 * take the instance name and instead unregisters all available instances.
876 *
877 * @param[in] uds_ctx Pointer to USB device support context
878 * @param[in] speed Configuration speed
879 * @param[in] cfg Configuration value (bConfigurationValue)
880 *
881 * @return 0 on success, other values on fail.
882 */
883 int usbd_unregister_all_classes(struct usbd_context *uds_ctx,
884 const enum usbd_speed speed, uint8_t cfg);
885
886 /**
887 * @brief Register USB notification message callback
888 *
889 * @param[in] uds_ctx Pointer to USB device support context
890 * @param[in] cb Pointer to message callback function
891 *
892 * @return 0 on success, other values on fail.
893 */
894 int usbd_msg_register_cb(struct usbd_context *const uds_ctx,
895 const usbd_msg_cb_t cb);
896
897 /**
898 * @brief Initialize USB device
899 *
900 * Initialize USB device descriptors and configuration,
901 * initialize USB device controller.
902 * Class instances should be registered before they are involved.
903 * However, the stack should also initialize without registered instances,
904 * even if the host would complain about missing interfaces.
905 *
906 * @param[in] uds_ctx Pointer to USB device support context
907 *
908 * @return 0 on success, other values on fail.
909 */
910 int usbd_init(struct usbd_context *uds_ctx);
911
912 /**
913 * @brief Enable the USB device support and registered class instances
914 *
915 * This function enables the USB device support.
916 *
917 * @param[in] uds_ctx Pointer to USB device support context
918 *
919 * @return 0 on success, other values on fail.
920 */
921 int usbd_enable(struct usbd_context *uds_ctx);
922
923 /**
924 * @brief Disable the USB device support
925 *
926 * This function disables the USB device support.
927 *
928 * @param[in] uds_ctx Pointer to USB device support context
929 *
930 * @return 0 on success, other values on fail.
931 */
932 int usbd_disable(struct usbd_context *uds_ctx);
933
934 /**
935 * @brief Shutdown the USB device support
936 *
937 * This function completely disables the USB device support.
938 *
939 * @param[in] uds_ctx Pointer to USB device support context
940 *
941 * @return 0 on success, other values on fail.
942 */
943 int usbd_shutdown(struct usbd_context *const uds_ctx);
944
945 /**
946 * @brief Halt endpoint
947 *
948 * @param[in] uds_ctx Pointer to USB device support context
949 * @param[in] ep Endpoint address
950 *
951 * @return 0 on success, or error from udc_ep_set_halt()
952 */
953 int usbd_ep_set_halt(struct usbd_context *uds_ctx, uint8_t ep);
954
955 /**
956 * @brief Clear endpoint halt
957 *
958 * @param[in] uds_ctx Pointer to USB device support context
959 * @param[in] ep Endpoint address
960 *
961 * @return 0 on success, or error from udc_ep_clear_halt()
962 */
963 int usbd_ep_clear_halt(struct usbd_context *uds_ctx, uint8_t ep);
964
965 /**
966 * @brief Checks whether the endpoint is halted.
967 *
968 * @param[in] uds_ctx Pointer to USB device support context
969 * @param[in] ep Endpoint address
970 *
971 * @return true if endpoint is halted, false otherwise
972 */
973 bool usbd_ep_is_halted(struct usbd_context *uds_ctx, uint8_t ep);
974
975 /**
976 * @brief Allocate buffer for USB device request
977 *
978 * Allocate a new buffer from controller's driver buffer pool.
979 *
980 * @param[in] c_data Pointer to USB device class data
981 * @param[in] ep Endpoint address
982 * @param[in] size Size of the request buffer
983 *
984 * @return pointer to allocated request or NULL on error.
985 */
986 struct net_buf *usbd_ep_buf_alloc(const struct usbd_class_data *const c_data,
987 const uint8_t ep, const size_t size);
988
989 /**
990 * @brief Queue USB device control request
991 *
992 * Add control request to the queue.
993 *
994 * @param[in] uds_ctx Pointer to USB device support context
995 * @param[in] buf Pointer to UDC request buffer
996 *
997 * @return 0 on success, all other values should be treated as error.
998 */
999 int usbd_ep_ctrl_enqueue(struct usbd_context *const uds_ctx,
1000 struct net_buf *const buf);
1001
1002 /**
1003 * @brief Queue USB device request
1004 *
1005 * Add request to the queue.
1006 *
1007 * @param[in] c_data Pointer to USB device class data
1008 * @param[in] buf Pointer to UDC request buffer
1009 *
1010 * @return 0 on success, or error from udc_ep_enqueue()
1011 */
1012 int usbd_ep_enqueue(const struct usbd_class_data *const c_data,
1013 struct net_buf *const buf);
1014
1015 /**
1016 * @brief Remove all USB device controller requests from endpoint queue
1017 *
1018 * @param[in] uds_ctx Pointer to USB device support context
1019 * @param[in] ep Endpoint address
1020 *
1021 * @return 0 on success, or error from udc_ep_dequeue()
1022 */
1023 int usbd_ep_dequeue(struct usbd_context *uds_ctx, const uint8_t ep);
1024
1025 /**
1026 * @brief Free USB device request buffer
1027 *
1028 * Put the buffer back into the request buffer pool.
1029 *
1030 * @param[in] uds_ctx Pointer to USB device support context
1031 * @param[in] buf Pointer to UDC request buffer
1032 *
1033 * @return 0 on success, all other values should be treated as error.
1034 */
1035 int usbd_ep_buf_free(struct usbd_context *uds_ctx, struct net_buf *buf);
1036
1037 /**
1038 * @brief Checks whether the USB device controller is suspended.
1039 *
1040 * @param[in] uds_ctx Pointer to USB device support context
1041 *
1042 * @return true if endpoint is halted, false otherwise
1043 */
1044 bool usbd_is_suspended(struct usbd_context *uds_ctx);
1045
1046 /**
1047 * @brief Initiate the USB remote wakeup (TBD)
1048 *
1049 * @return 0 on success, other values on fail.
1050 */
1051 int usbd_wakeup_request(struct usbd_context *uds_ctx);
1052
1053 /**
1054 * @brief Get actual device speed
1055 *
1056 * @param[in] uds_ctx Pointer to a device context
1057 *
1058 * @return Actual device speed
1059 */
1060 enum usbd_speed usbd_bus_speed(const struct usbd_context *const uds_ctx);
1061
1062 /**
1063 * @brief Get highest speed supported by the controller
1064 *
1065 * @param[in] uds_ctx Pointer to a device context
1066 *
1067 * @return Highest supported speed
1068 */
1069 enum usbd_speed usbd_caps_speed(const struct usbd_context *const uds_ctx);
1070
1071 /**
1072 * @brief Set USB device descriptor value bcdUSB
1073 *
1074 * @param[in] uds_ctx Pointer to USB device support context
1075 * @param[in] speed Speed for which the bcdUSB should be set
1076 * @param[in] bcd bcdUSB value
1077 *
1078 * @return 0 on success, other values on fail.
1079 */
1080 int usbd_device_set_bcd_usb(struct usbd_context *const uds_ctx,
1081 const enum usbd_speed speed, const uint16_t bcd);
1082
1083 /**
1084 * @brief Set USB device descriptor value idVendor
1085 *
1086 * @param[in] uds_ctx Pointer to USB device support context
1087 * @param[in] vid idVendor value
1088 *
1089 * @return 0 on success, other values on fail.
1090 */
1091 int usbd_device_set_vid(struct usbd_context *const uds_ctx,
1092 const uint16_t vid);
1093
1094 /**
1095 * @brief Set USB device descriptor value idProduct
1096 *
1097 * @param[in] uds_ctx Pointer to USB device support context
1098 * @param[in] pid idProduct value
1099 *
1100 * @return 0 on success, other values on fail.
1101 */
1102 int usbd_device_set_pid(struct usbd_context *const uds_ctx,
1103 const uint16_t pid);
1104
1105 /**
1106 * @brief Set USB device descriptor value bcdDevice
1107 *
1108 * @param[in] uds_ctx Pointer to USB device support context
1109 * @param[in] bcd bcdDevice value
1110 *
1111 * @return 0 on success, other values on fail.
1112 */
1113 int usbd_device_set_bcd_device(struct usbd_context *const uds_ctx,
1114 const uint16_t bcd);
1115
1116 /**
1117 * @brief Set USB device descriptor code triple Base Class, SubClass, and Protocol
1118 *
1119 * @param[in] uds_ctx Pointer to USB device support context
1120 * @param[in] speed Speed for which the code triple should be set
1121 * @param[in] base_class bDeviceClass value
1122 * @param[in] subclass bDeviceSubClass value
1123 * @param[in] protocol bDeviceProtocol value
1124 *
1125 * @return 0 on success, other values on fail.
1126 */
1127 int usbd_device_set_code_triple(struct usbd_context *const uds_ctx,
1128 const enum usbd_speed speed,
1129 const uint8_t base_class,
1130 const uint8_t subclass, const uint8_t protocol);
1131
1132 /**
1133 * @brief Setup USB device configuration attribute Remote Wakeup
1134 *
1135 * @param[in] uds_ctx Pointer to USB device support context
1136 * @param[in] speed Configuration speed
1137 * @param[in] cfg Configuration number
1138 * @param[in] enable Sets attribute if true, clears it otherwise
1139 *
1140 * @return 0 on success, other values on fail.
1141 */
1142 int usbd_config_attrib_rwup(struct usbd_context *const uds_ctx,
1143 const enum usbd_speed speed,
1144 const uint8_t cfg, const bool enable);
1145
1146 /**
1147 * @brief Setup USB device configuration attribute Self-powered
1148 *
1149 * @param[in] uds_ctx Pointer to USB device support context
1150 * @param[in] speed Configuration speed
1151 * @param[in] cfg Configuration number
1152 * @param[in] enable Sets attribute if true, clears it otherwise
1153 *
1154 * @return 0 on success, other values on fail.
1155 */
1156 int usbd_config_attrib_self(struct usbd_context *const uds_ctx,
1157 const enum usbd_speed speed,
1158 const uint8_t cfg, const bool enable);
1159
1160 /**
1161 * @brief Setup USB device configuration power consumption
1162 *
1163 * @param[in] uds_ctx Pointer to USB device support context
1164 * @param[in] speed Configuration speed
1165 * @param[in] cfg Configuration number
1166 * @param[in] power Maximum power consumption value (bMaxPower)
1167 *
1168 * @return 0 on success, other values on fail.
1169 */
1170 int usbd_config_maxpower(struct usbd_context *const uds_ctx,
1171 const enum usbd_speed speed,
1172 const uint8_t cfg, const uint8_t power);
1173
1174 /**
1175 * @brief Check that the controller can detect the VBUS state change.
1176 *
1177 * This can be used in a generic application to explicitly handle the VBUS
1178 * detected event after usbd_init(). For example, to call usbd_enable() after a
1179 * short delay to give the PMIC time to detect the bus, or to handle cases
1180 * where usbd_enable() can only be called after a VBUS detected event.
1181 *
1182 * @param[in] uds_ctx Pointer to USB device support context
1183 *
1184 * @return true if controller can detect VBUS state change, false otherwise
1185 */
1186 bool usbd_can_detect_vbus(struct usbd_context *const uds_ctx);
1187
1188 /**
1189 * @brief Register an USB vendor request with recipient device
1190 *
1191 * The vendor request with the recipient device applies to all configurations
1192 * within the device.
1193 *
1194 * @param[in] uds_ctx Pointer to USB device support context
1195 * @param[in] vreq_nd Pointer to vendor request node
1196 *
1197 * @return 0 on success, other values on fail.
1198 */
1199 int usbd_device_register_vreq(struct usbd_context *const uds_ctx,
1200 struct usbd_vreq_node *const vreq_nd);
1201
1202 /**
1203 * @}
1204 */
1205
1206 #ifdef __cplusplus
1207 }
1208 #endif
1209
1210 #endif /* ZEPHYR_INCLUDE_USBD_H_ */
1211