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