1.. _usb_device_stack_next: 2 3USB device support 4################## 5 6Overview 7******** 8 9USB device support consists of the USB device controller (UDC) drivers 10, :ref:`udc_api`, and USB device stack, :ref:`usbd_api`. 11The :ref:`udc_api` provides a generic and vendor independent interface to USB 12device controllers, and although, there a is clear separation between these 13layers, the purpose of :ref:`udc_api` is to serve Zephyr's USB device stack 14exclusively. 15 16The device stack supports multiple device controllers, meaning that if a 17SoC has multiple controllers, they can be used simultaneously. Full and 18high-speed device controllers are supported. It also provides support for 19registering multiple function or class instances to a configuration at runtime, 20or changing the configuration later. It has built-in support for several USB 21classes and provides an API to implement custom USB functions. 22 23Samples 24======= 25 26* :zephyr:code-sample:`usb-hid-keyboard` 27 28* :zephyr:code-sample:`uac2-explicit-feedback` 29 30* :zephyr:code-sample:`uac2-implicit-feedback` 31 32* :zephyr:code-sample:`uvc` 33 34* :zephyr:code-sample:`bluetooth_hci_usb` 35 36* :zephyr:code-sample:`usb-cdc-acm` 37 38* :zephyr:code-sample:`usb-cdc-acm-console` 39 40* :zephyr:code-sample:`usb-mass` 41 42* :zephyr:code-sample:`usb-hid-mouse` 43 44* :zephyr:code-sample:`zperf` To build the sample for the device support, 45 set the configuration overlay file 46 ``-DDEXTRA_CONF_FILE=overlay-usbd_next_ecm.conf`` and devicetree overlay file 47 ``-DDTC_OVERLAY_FILE="usbd_next_ecm.overlay`` either directly or via ``west``. 48 49How to configure and enable USB device support 50********************************************** 51 52For the USB device support samples in the Zephyr project repository, we have a 53common file for instantiation, configuration and initialization, 54:zephyr_file:`samples/subsys/usb/common/sample_usbd_init.c`. The following code 55snippets from this file are used as examples. USB Samples Kconfig options used 56in the USB samples and prefixed with ``SAMPLE_USBD_`` have default values 57specific to the Zephyr project and the scope is limited to the project samples. 58In the examples below, you will need to replace these Kconfig options and other 59defaults with values appropriate for your application or hardware. 60 61The USB device stack requires a context structure to manage its properties and 62runtime data. The preferred way to define a device context is to use the 63:c:macro:`USBD_DEVICE_DEFINE` macro. This creates a static 64:c:struct:`usbd_context` variable with a given name. Any number of contexts may 65be instantiated. A USB controller device can be assigned to multiple contexts, 66but only one context can be initialized and used at a time. Context properties 67must not be directly accessed or manipulated by the application. 68 69.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 70 :language: c 71 :dedent: 72 :start-after: doc device instantiation start 73 :end-before: doc device instantiation end 74 75Your USB device may have manufacturer, product, and serial number string 76descriptors. To instantiate these string descriptors, the application should 77use the appropriate :c:macro:`USBD_DESC_MANUFACTURER_DEFINE`, 78:c:macro:`USBD_DESC_PRODUCT_DEFINE`, and 79:c:macro:`USBD_DESC_SERIAL_NUMBER_DEFINE` macros. String descriptors also 80require a single instantiation of the language descriptor using the 81:c:macro:`USBD_DESC_LANG_DEFINE` macro. 82 83.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 84 :language: c 85 :dedent: 86 :start-after: doc string instantiation start 87 :end-before: doc string instantiation end 88 89String descriptors must be added to the device context at runtime before 90initializing the USB device with :c:func:`usbd_add_descriptor`. 91 92.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 93 :language: c 94 :dedent: 95 :start-after: doc add string descriptor start 96 :end-before: doc add string descriptor end 97 98USB device requires at least one configuration instance per supported speed. 99The application should use :c:macro:`USBD_CONFIGURATION_DEFINE` to instantiate 100a configuration. Later, USB device functions are assigned to a configuration. 101 102.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 103 :language: c 104 :dedent: 105 :start-after: doc configuration instantiation start 106 :end-before: doc configuration instantiation end 107 108Each configuration instance for a specific speed must be added to the device 109context at runtime before the USB device is initialized using 110:c:func:`usbd_add_configuration`. Note :c:enumerator:`USBD_SPEED_FS` and 111:c:enumerator:`USBD_SPEED_HS`. The first full-speed or high-speed 112configuration will get ``bConfigurationValue`` one, and then further upward. 113 114.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 115 :language: c 116 :dedent: 117 :start-after: doc configuration register start 118 :end-before: doc configuration register end 119 120 121Although we have already done a lot, this USB device has no function. A device 122can have multiple configurations with different set of functions at different 123speeds. A function or class can be registered on a USB device before 124it is initialized using :c:func:`usbd_register_class`. The desired 125configuration is specified using :c:enumerator:`USBD_SPEED_FS` or 126:c:enumerator:`USBD_SPEED_HS` and the configuration number. For simple cases, 127:c:func:`usbd_register_all_classes` can be used to register all available 128instances. 129 130.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 131 :language: c 132 :dedent: 133 :start-after: doc functions register start 134 :end-before: doc functions register end 135 136The last step in the preparation is to initialize the device with 137:c:func:`usbd_init`. After this, the configuration of the device cannot be 138changed. A device can be deinitialized with :c:func:`usbd_shutdown` and all 139instances can be reused, but the previous steps must be repeated. So it is 140possible to shutdown a device, register another type of configuration or 141function, and initialize it again. At the USB controller level, 142:c:func:`usbd_init` does only what is necessary to detect VBUS changes. There 143are controller types where the next step is only possible if a VBUS signal is 144present. 145 146A function or class implementation may require its own specific configuration 147steps, which should be performed prior to initializing the USB device. 148 149.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 150 :language: c 151 :dedent: 152 :start-after: doc device init start 153 :end-before: doc device init end 154 155The final step to enable the USB device is :c:func:`usbd_enable`, after that, 156if the USB device is connected to a USB host controller, the host can start 157enumerating the device. The application can disable the USB device using 158:c:func:`usbd_disable`. 159 160.. literalinclude:: ../../../../samples/subsys/usb/hid-keyboard/src/main.c 161 :language: c 162 :dedent: 163 :start-after: doc device enable start 164 :end-before: doc device enable end 165 166USB Message notifications 167========================= 168 169The application can register a callback using :c:func:`usbd_msg_register_cb` to 170receive message notification from the USB device support subsystem. The 171messages are mostly about the common device state changes, and a few specific 172types from the USB CDC ACM implementation. 173 174.. literalinclude:: ../../../../samples/subsys/usb/common/sample_usbd_init.c 175 :language: c 176 :dedent: 177 :start-after: doc device init-and-msg start 178 :end-before: doc device init-and-msg end 179 180The helper function :c:func:`usbd_msg_type_string()` can be used to convert 181:c:enumerator:`usbd_msg_type` to a human readable form for logging. 182 183If the controller supports VBUS state change detection, the battery-powered 184application may want to enable the USB device only when it is connected to a 185host. A generic application should use :c:func:`usbd_can_detect_vbus` to check 186for this capability. 187 188.. literalinclude:: ../../../../samples/subsys/usb/hid-keyboard/src/main.c 189 :language: c 190 :dedent: 191 :start-after: doc device msg-cb start 192 :end-before: doc device msg-cb end 193 194Built-in functions 195****************** 196 197The USB device stack has built-in USB functions. Some can be used directly in 198the user application through a special API, such as HID or Audio class devices, 199while others use a general Zephyr RTOS driver API, such as MSC and CDC class 200implementations. The *Identification string* identifies a class or function 201instance (``n``) and is used as an argument to the :c:func:`usbd_register_class`. 202 203+-----------------------------------+-------------------------+-------------------------+ 204| Class or function | User API (if any) | Identification string | 205+===================================+=========================+=========================+ 206| USB Audio 2 class | :ref:`uac2_device` | :samp:`uac2_{n}` | 207+-----------------------------------+-------------------------+-------------------------+ 208| USB CDC ACM class | :ref:`uart_api` | :samp:`cdc_acm_{n}` | 209+-----------------------------------+-------------------------+-------------------------+ 210| USB CDC ECM class | Ethernet device | :samp:`cdc_ecm_{n}` | 211+-----------------------------------+-------------------------+-------------------------+ 212| USB Mass Storage Class (MSC) | :ref:`usbd_msc_device` | :samp:`msc_{n}` | 213+-----------------------------------+-------------------------+-------------------------+ 214| USB Human Interface Devices (HID) | :ref:`usbd_hid_device` | :samp:`hid_{n}` | 215+-----------------------------------+-------------------------+-------------------------+ 216| Bluetooth HCI USB transport layer | :ref:`bt_hci_raw` | :samp:`bt_hci_{n}` | 217+-----------------------------------+-------------------------+-------------------------+ 218| USB Video Class (UVC) | Video device | :samp:`uvc_{n}` | 219+-----------------------------------+-------------------------+-------------------------+ 220 221CDC ACM UART 222============ 223 224CDC ACM implements a virtual UART controller and provides Interrupt-driven UART 225API and Polling UART API. 226 227Interrupt-driven UART API 228------------------------- 229 230Internally the implementation uses two ringbuffers, these take over the 231function of the TX/RX FIFOs (TX/RX buffers) from the :ref:`uart_interrupt_api`. 232 233As described in the :ref:`uart_interrupt_api`, the functions 234:c:func:`uart_irq_update()`, :c:func:`uart_irq_is_pending`, 235:c:func:`uart_irq_rx_ready()`, :c:func:`uart_irq_tx_ready()` 236:c:func:`uart_fifo_read()`, and :c:func:`uart_fifo_fill()` 237should be called from the interrupt handler, see 238:c:func:`uart_irq_callback_user_data_set()`. To prevent undefined behaviour, 239the implementation of these functions checks in what context they are called 240and fails if it is not an interrupt handler. 241 242Also, as described in the UART API, :c:func:`uart_irq_is_pending` 243:c:func:`uart_irq_rx_ready()`, and :c:func:`uart_irq_tx_ready()` 244can only be called after :c:func:`uart_irq_update()`. 245 246Simplified, the interrupt handler should look something like: 247 248.. code-block:: c 249 250 static void interrupt_handler(const struct device *dev, void *user_data) 251 { 252 while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { 253 if (uart_irq_rx_ready(dev)) { 254 int len; 255 int n; 256 257 /* ... */ 258 n = uart_fifo_read(dev, buffer, len); 259 /* ... */ 260 } 261 262 if (uart_irq_tx_ready(dev)) { 263 int len; 264 int n; 265 266 /* ... */ 267 n = uart_fifo_fill(dev, buffer, len); 268 /* ... */ 269 } 270 } 271 272All these functions are not directly dependent on the status of the USB device. 273Filling the TX FIFO does not mean that data is being sent to the host. And 274successfully reading the RX FIFO does not mean that the device is still 275connected to the host. If there is space in the TX FIFO, and the TX interrupt 276is enabled, :c:func:`uart_irq_tx_ready()` will succeed. If there is data in the 277RX FIFO, and the RX interrupt is enabled, :c:func:`uart_irq_rx_ready()` will 278succeed. Function :c:func:`uart_irq_tx_complete()` is not implemented yet. 279 280Polling UART API 281---------------- 282 283The CDC ACM poll out implementation follows :ref:`uart_polling_api` and 284blocks when the TX FIFO is full only if the hw-flow-control property is enabled 285and called from a non-ISR context. 286