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