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