Line data Source code
1 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 0 : #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 0 : #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 1 : struct usbd_str_desc_data {
88 : /** Descriptor index, required for string descriptors */
89 1 : uint8_t idx;
90 : /** Descriptor usage type (not bDescriptorType) */
91 1 : enum usbd_str_desc_utype utype : 8;
92 : /** The string descriptor is in ASCII7 format */
93 1 : unsigned int ascii7 : 1;
94 : /** Device stack obtains SerialNumber using the HWINFO API */
95 1 : 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 1 : struct usbd_vreq_node {
132 : /** Node information for the dlist */
133 1 : sys_dnode_t node;
134 : /** Vendor code (bRequest value) */
135 1 : const uint8_t code;
136 : /** Vendor request callback for device-to-host direction */
137 1 : 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 1 : 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 1 : struct usbd_bos_desc_data {
150 : /** Descriptor usage type (not bDescriptorType) */
151 1 : enum usbd_bos_desc_utype utype : 8;
152 : union {
153 0 : struct usbd_vreq_node *const vreq_nd;
154 0 : };
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 1 : struct usbd_desc_node {
164 : /** slist node struct */
165 1 : sys_dnode_t node;
166 : union {
167 0 : struct usbd_str_desc_data str;
168 0 : struct usbd_bos_desc_data bos;
169 0 : };
170 : /** Opaque pointer to a descriptor payload */
171 1 : const void *const ptr;
172 : /** Descriptor size in bytes */
173 1 : uint8_t bLength;
174 : /** Descriptor type */
175 1 : 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 1 : struct usbd_config_node {
187 : /** slist node struct */
188 1 : sys_snode_t node;
189 : /** Pointer to configuration descriptor */
190 1 : void *desc;
191 : /** Optional pointer to string descriptor node */
192 1 : struct usbd_desc_node *str_desc_nd;
193 : /** List of registered classes (functions) */
194 1 : sys_slist_t class_list;
195 : };
196 :
197 : /* TODO: Kconfig option USBD_NUMOF_INTERFACES_MAX? */
198 0 : #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 0 : 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 1 : struct usbd_ch9_data {
217 : /** Setup packet, up-to-date for the respective control request */
218 1 : struct usb_setup_packet setup;
219 : /** Control type, internally used for stage verification */
220 1 : int ctrl_type;
221 : /** Protocol state of the USB device stack */
222 1 : enum usbd_ch9_state state;
223 : /** Halted endpoints bitmap */
224 1 : uint32_t ep_halt;
225 : /** USB device stack selected configuration */
226 1 : uint8_t configuration;
227 : /** Post status stage work required, e.g. set new device address */
228 1 : bool post_status;
229 : /** Array to track interfaces alternate settings */
230 1 : uint8_t alternate[USBD_NUMOF_INTERFACES_MAX];
231 : };
232 :
233 : /**
234 : * @brief USB device speed
235 : */
236 1 : 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 1 : struct usbd_status {
249 : /** USB device support is initialized */
250 1 : unsigned int initialized : 1;
251 : /** USB device support is enabled */
252 1 : unsigned int enabled : 1;
253 : /** USB device is suspended */
254 1 : unsigned int suspended : 1;
255 : /** USB remote wake-up feature is enabled */
256 1 : unsigned int rwup : 1;
257 : /** USB device speed */
258 1 : 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 1 : 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 1 : struct usbd_context {
282 : /** Name of the USB device */
283 1 : const char *name;
284 : /** Access mutex */
285 1 : struct k_mutex mutex;
286 : /** Pointer to UDC device */
287 1 : const struct device *dev;
288 : /** Notification message recipient callback */
289 1 : usbd_msg_cb_t msg_cb;
290 : /** Middle layer runtime data */
291 1 : struct usbd_ch9_data ch9_data;
292 : /** slist to manage descriptors like string, BOS */
293 1 : sys_dlist_t descriptors;
294 : /** slist to manage Full-Speed device configurations */
295 1 : sys_slist_t fs_configs;
296 : /** slist to manage High-Speed device configurations */
297 1 : sys_slist_t hs_configs;
298 : /** dlist to manage vendor requests with recipient device */
299 1 : sys_dlist_t vreqs;
300 : /** Status of the USB device support */
301 1 : struct usbd_status status;
302 : /** Pointer to Full-Speed device descriptor */
303 1 : void *fs_desc;
304 : /** Pointer to High-Speed device descriptor */
305 1 : void *hs_desc;
306 : };
307 :
308 : /**
309 : * @brief Vendor Requests Table
310 : */
311 1 : struct usbd_cctx_vendor_req {
312 : /** Array of vendor requests supported by the class */
313 1 : const uint8_t *reqs;
314 : /** Length of the array */
315 1 : uint8_t len;
316 : };
317 :
318 : /** USB Class instance registered flag */
319 1 : #define USBD_CCTX_REGISTERED 0
320 :
321 : struct usbd_class_data;
322 :
323 : /**
324 : * @brief USB device support class instance API
325 : */
326 1 : struct usbd_class_api {
327 : /** Feature halt state update handler */
328 1 : void (*feature_halt)(struct usbd_class_data *const c_data,
329 : uint8_t ep, bool halted);
330 :
331 : /** Configuration update handler */
332 1 : 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 1 : 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 1 : 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 1 : int (*request)(struct usbd_class_data *const c_data,
347 : struct net_buf *buf, int err);
348 :
349 : /** USB power management handler suspended */
350 1 : void (*suspended)(struct usbd_class_data *const c_data);
351 :
352 : /** USB power management handler resumed */
353 1 : void (*resumed)(struct usbd_class_data *const c_data);
354 :
355 : /** Start of Frame */
356 1 : void (*sof)(struct usbd_class_data *const c_data);
357 :
358 : /** Class associated configuration is selected */
359 1 : void (*enable)(struct usbd_class_data *const c_data);
360 :
361 : /** Class associated configuration is disabled */
362 1 : void (*disable)(struct usbd_class_data *const c_data);
363 :
364 : /** Initialization of the class implementation */
365 1 : int (*init)(struct usbd_class_data *const c_data);
366 :
367 : /** Shutdown of the class implementation */
368 1 : void (*shutdown)(struct usbd_class_data *const c_data);
369 :
370 : /** Get function descriptor based on speed parameter */
371 1 : 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 1 : struct usbd_class_data {
379 : /** Name of the USB device class instance */
380 1 : const char *name;
381 : /** Pointer to USB device stack context structure */
382 1 : struct usbd_context *uds_ctx;
383 : /** Pointer to device support class API */
384 1 : const struct usbd_class_api *api;
385 : /** Supported vendor request table, can be NULL */
386 1 : const struct usbd_cctx_vendor_req *v_reqs;
387 : /** Pointer to private data */
388 1 : 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 : */
430 1 : 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 : */
445 1 : 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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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_ */
|