1.. _usb_device_stack:
2
3USB device support
4##################
5
6.. contents::
7    :local:
8    :depth: 3
9
10Overview
11********
12
13The USB device stack is a hardware independent interface between USB
14device controller driver and USB device class drivers or customer applications.
15It is a port of the LPCUSB device stack and has been modified and expanded
16over time. It provides the following functionalities:
17
18* Uses the :ref:`usb_dc_api` provided by the device controller drivers to interact with
19  the USB device controller.
20* Responds to standard device requests and returns standard descriptors,
21  essentially handling 'Chapter 9' processing, specifically the standard
22  device requests in table 9-3 from the universal serial bus specification
23  revision 2.0.
24* Provides a programming interface to be used by USB device classes or
25  customer applications. The APIs is described in
26  :zephyr_file:`include/zephyr/usb/usb_device.h`
27
28The device stack and :ref:`usb_dc_api` have some limitations, such as not being
29able to support more than one controller instance at runtime and only supporting
30one USB device configuration. We are actively working on new USB support, which
31means we will continue to maintain the device stack described here until all
32supported USB classes are ported, but do not expect any new features or enhancements.
33
34Supported USB classes
35*********************
36
37Audio
38=====
39
40There is an experimental implementation of the Audio class. It follows specification
41version 1.00 (``bcdADC 0x0100``) and supports synchronous synchronisation type only.
42See :zephyr:code-sample:`usb-audio-headphones-microphone` and
43:zephyr:code-sample:`usb-audio-headset` samples for reference.
44
45Bluetooth HCI USB transport layer
46=================================
47
48Bluetooth HCI USB transport layer implementation uses :ref:`bt_hci_raw`
49to expose HCI interface to the host. It is not fully in line with the description
50in the Bluetooth specification and consists only of an interface with the endpoint
51configuration:
52
53* HCI commands through control endpoint (host-to-device only)
54* HCI events through interrupt IN endpoint
55* ACL data through one bulk IN and one bulk OUT endpoints
56
57A second interface for the voice channels has not been implemented as there is
58no support for this type in :ref:`bluetooth`. It is not a big problem under Linux
59if HCI USB transport layer is the only interface that appears in the configuration,
60the btusb driver would not try to claim a second (isochronous) interface.
61The consequence is that if HCI USB is used in a composite configuration and is
62the first interface, then the Linux btusb driver will claim both the first and
63the next interface, preventing other composite functions from working.
64Because of this problem, HCI USB should not be used in a composite configuration.
65This problem is fixed in the implementation for new USB support.
66
67See :ref:`bluetooth-hci-usb-sample` sample for reference.
68
69.. _usb_device_cdc_acm:
70
71CDC ACM
72=======
73
74The CDC ACM class is used as backend for different subsystems in Zephyr.
75However, its configuration may not be easy for the inexperienced user.
76Below is a description of the different use cases and some pitfalls.
77
78The interface for CDC ACM user is :ref:`uart_api` driver API.
79But there are two important differences in behavior to a real UART controller:
80
81* Data transfer is only possible after the USB device stack has been
82  initialized and started, until then any data is discarded
83* If device is connected to the host, it still needs an application
84  on the host side which requests the data
85
86The devicetree compatible property for CDC ACM UART is
87:dtcompatible:`zephyr,cdc-acm-uart`.
88CDC ACM support is automatically selected when USB device support is enabled
89and a compatible node in the devicetree sources is present. If necessary,
90CDC ACM support can be explicitly disabled by :kconfig:option:`CONFIG_USB_CDC_ACM`.
91About four CDC ACM UART instances can be defined and used,
92limited by the maximum number of supported endpoints on the controller.
93
94CDC ACM UART node is supposed to be child of a USB device controller node.
95Since the designation of the controller nodes varies from vendor to vendor,
96and our samples and application should be as generic as possible,
97the default USB device controller is usually assigned an ``zephyr_udc0``
98node label. Often, CDC ACM UART is described in a devicetree overlay file
99and looks like this:
100
101.. code-block:: devicetree
102
103	&zephyr_udc0 {
104		cdc_acm_uart0: cdc_acm_uart0 {
105			compatible = "zephyr,cdc-acm-uart";
106			label = "CDC_ACM_0";
107		};
108	};
109
110Samples :zephyr:code-sample:`usb-cdc-acm` and :zephyr:code-sample:`usb-hid-cdc` have similar overlay files.
111And since no special properties are present, it may seem overkill to use
112devicetree to describe CDC ACM UART.  The motivation behind using devicetree
113is the easy interchangeability of a real UART controller and CDC ACM UART
114in applications.
115
116Console over CDC ACM UART
117-------------------------
118
119With the CDC ACM UART node from above and ``zephyr,console`` property of the
120chosen node, we can describe that CDC ACM UART is to be used with the console.
121A similar overlay file is used by the :zephyr:code-sample:`usb-cdc-acm-console` sample.
122
123.. code-block:: devicetree
124
125	/ {
126		chosen {
127			zephyr,console = &cdc_acm_uart0;
128		};
129	};
130
131	&zephyr_udc0 {
132		cdc_acm_uart0: cdc_acm_uart0 {
133			compatible = "zephyr,cdc-acm-uart";
134			label = "CDC_ACM_0";
135		};
136	};
137
138Before the application uses the console, it is recommended to wait for
139the DTR signal:
140
141.. code-block:: c
142
143	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
144	uint32_t dtr = 0;
145
146	if (usb_enable(NULL)) {
147		return;
148	}
149
150	while (!dtr) {
151		uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
152		k_sleep(K_MSEC(100));
153	}
154
155	printk("nuqneH\n");
156
157CDC ACM UART as backend
158-----------------------
159
160As for the console sample, it is possible to configure CDC ACM UART as
161backend for other subsystems by setting :ref:`devicetree-chosen-nodes`
162properties.
163
164List of few Zephyr specific chosen properties which can be used to select
165CDC ACM UART as backend for a subsystem or application:
166
167* ``zephyr,bt-c2h-uart`` used in Bluetooth,
168  for example see :ref:`bluetooth-hci-uart-sample`
169* ``zephyr,ot-uart`` used in OpenThread,
170  for example see :zephyr:code-sample:`coprocessor`
171* ``zephyr,shell-uart`` used by shell for serial backend,
172  for example see :zephyr_file:`samples/subsys/shell/shell_module`
173* ``zephyr,uart-mcumgr`` used by :zephyr:code-sample:`smp-svr` sample
174
175DFU
176===
177
178USB DFU class implementation is tightly coupled to :ref:`dfu` and :ref:`mcuboot_api`.
179This means that the target platform must support the :ref:`flash_img_api` API.
180
181See :zephyr:code-sample:`usb-dfu` sample for reference.
182
183USB Human Interface Devices (HID) support
184=========================================
185
186HID support abuses :ref:`device_model_api` simply to allow applications to use
187the :c:func:`device_get_binding`. Note that there is no HID device API as such,
188instead the interface is provided by :c:struct:`hid_ops`.
189The default instance name is ``HID_n``, where n can be {0, 1, 2, ...} depending on
190the :kconfig:option:`CONFIG_USB_HID_DEVICE_COUNT`.
191
192Each HID instance requires a HID report descriptor. The interface to the core
193and the report descriptor must be registered using :c:func:`usb_hid_register_device`.
194
195As the USB HID specification is not only used by the USB subsystem, the USB HID API
196reference is split into two parts, :ref:`usb_hid_common` and :ref:`usb_hid_device`.
197HID helper macros from :ref:`usb_hid_common` should be used to compose a
198HID report descriptor. Macro names correspond to those used in the USB HID specification.
199
200For the HID class interface, an IN interrupt endpoint is required for each instance,
201an OUT interrupt endpoint is optional. Thus, the minimum implementation requirement
202for :c:struct:`hid_ops` is to provide ``int_in_ready`` callback.
203
204.. code-block:: c
205
206	#define REPORT_ID		1
207	static bool configured;
208	static const struct device *hdev;
209
210	static void int_in_ready_cb(const struct device *dev)
211	{
212		static uint8_t report[2] = {REPORT_ID, 0};
213
214		if (hid_int_ep_write(hdev, report, sizeof(report), NULL)) {
215			LOG_ERR("Failed to submit report");
216		} else {
217			report[1]++;
218		}
219	}
220
221	static void status_cb(enum usb_dc_status_code status, const uint8_t *param)
222	{
223		if (status == USB_DC_RESET) {
224			configured = false;
225		}
226
227		if (status == USB_DC_CONFIGURED && !configured) {
228			int_in_ready_cb(hdev);
229			configured = true;
230		}
231	}
232
233	static const uint8_t hid_report_desc[] = {
234		HID_USAGE_PAGE(HID_USAGE_GEN_DESKTOP),
235		HID_USAGE(HID_USAGE_GEN_DESKTOP_UNDEFINED),
236		HID_COLLECTION(HID_COLLECTION_APPLICATION),
237		HID_LOGICAL_MIN8(0x00),
238		HID_LOGICAL_MAX16(0xFF, 0x00),
239		HID_REPORT_ID(REPORT_ID),
240		HID_REPORT_SIZE(8),
241		HID_REPORT_COUNT(1),
242		HID_USAGE(HID_USAGE_GEN_DESKTOP_UNDEFINED),
243		HID_INPUT(0x02),
244		HID_END_COLLECTION,
245	};
246
247	static const struct hid_ops my_ops = {
248		.int_in_ready = int_in_ready_cb,
249	};
250
251	int main(void)
252	{
253		int ret;
254
255		hdev = device_get_binding("HID_0");
256		if (hdev == NULL) {
257			return -ENODEV;
258		}
259
260		usb_hid_register_device(hdev, hid_report_desc, sizeof(hid_report_desc),
261					&my_ops);
262
263		ret = usb_hid_init(hdev);
264		if (ret) {
265			return ret;
266		}
267
268		return usb_enable(status_cb);
269	}
270
271
272If the application wishes to receive output reports via the OUT interrupt endpoint,
273it must enable :kconfig:option:`CONFIG_ENABLE_HID_INT_OUT_EP` and provide
274``int_out_ready`` callback.
275The disadvantage of this is that Kconfig options such as
276:kconfig:option:`CONFIG_ENABLE_HID_INT_OUT_EP` or
277:kconfig:option:`CONFIG_HID_INTERRUPT_EP_MPS` apply to all instances. This design
278issue will be fixed in the HID class implementation for the new USB support.
279
280See :zephyr:code-sample:`usb-hid` or :zephyr:code-sample:`usb-hid-mouse` sample for reference.
281
282Mass Storage Class
283==================
284
285MSC follows Bulk-Only Transport specification and uses :ref:`disk_access_api` to
286access and expose a RAM disk, emulated block device on a flash partition,
287or SD Card to the host. Only one disk instance can be exported at a time.
288
289The disc to be used by the implementation is set by the
290:kconfig:option:`CONFIG_MASS_STORAGE_DISK_NAME` and should be the same as the name
291used by the disc access driver that the application wants to expose to the host.
292SD card disk drivers use options :kconfig:option:`CONFIG_MMC_VOLUME_NAME` or
293:kconfig:option:`CONFIG_SDMMC_VOLUME_NAME`, and flash and RAM disk drivers use
294node property ``disk-name`` to set the disk name.
295
296For the emulated block device on a flash partition, the flash partition and
297flash disk to be used must be described in the devicetree. If a storage partition
298is already described at the board level, application devicetree overlay must also
299delete ``storage_partition`` node first. :kconfig:option:`CONFIG_MASS_STORAGE_DISK_NAME`
300should be the same as ``disk-name`` property.
301
302.. code-block:: devicetree
303
304	/delete-node/ &storage_partition;
305
306	&mx25r64 {
307		partitions {
308			compatible = "fixed-partitions";
309			#address-cells = <1>;
310			#size-cells = <1>;
311
312			storage_partition: partition@0 {
313				label = "storage";
314				reg = <0x00000000 0x00020000>;
315			};
316		};
317	};
318
319	/ {
320		msc_disk0 {
321			compatible = "zephyr,flash-disk";
322			partition = <&storage_partition>;
323			disk-name = "NAND";
324			cache-size = <4096>;
325		};
326	};
327
328The ``disk-property`` "NAND" may be confusing, but it is simply how some file
329systems identifies the disc. Therefore, if the application also accesses the
330file system on the exposed disc, default names should be used, see
331:zephyr:code-sample:`usb-mass` sample for reference.
332
333Networking
334==========
335
336There are three implementations that work in a similar way, providing a virtual
337Ethernet connection between the remote (USB host) and Zephyr network support.
338
339* CDC ECM class, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_ECM`
340* CDC EEM class, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_EEM`
341* RNDIS support, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_RNDIS`
342
343See :zephyr:code-sample:`zperf` or :zephyr:code-sample:`socket-dumb-http-server` for reference.
344Typically, users will need to add a configuration file overlay to the build,
345such as :zephyr_file:`samples/net/zperf/overlay-netusb.conf`.
346
347Applications using RNDIS support should enable :kconfig:option:`CONFIG_USB_DEVICE_OS_DESC`
348for a better user experience on a host running Microsoft Windows OS.
349
350Binary Device Object Store (BOS) support
351****************************************
352
353BOS handling can be enabled with Kconfig option :kconfig:option:`CONFIG_USB_DEVICE_BOS`.
354This option also has the effect of changing device descriptor ``bcdUSB`` to ``0210``.
355The application should register descriptors such as Capability Descriptor
356using :c:func:`usb_bos_register_cap`. Registered descriptors are added to the root
357BOS descriptor and handled by the stack.
358
359See :zephyr:code-sample:`webusb` sample for reference.
360
361Implementing a non-standard USB class
362*************************************
363
364The configuration of USB device is done in the stack layer.
365
366The following structures and callbacks need to be defined:
367
368* Part of USB Descriptor table
369* USB Endpoint configuration table
370* USB Device configuration structure
371* Endpoint callbacks
372* Optionally class, vendor and custom handlers
373
374For example, for the USB loopback application:
375
376.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
377   :language: c
378   :start-after: usb.rst config structure start
379   :end-before: usb.rst config structure end
380   :linenos:
381
382Endpoint configuration:
383
384.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
385   :language: c
386   :start-after: usb.rst endpoint configuration start
387   :end-before: usb.rst endpoint configuration end
388   :linenos:
389
390USB Device configuration structure:
391
392.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
393   :language: c
394   :start-after: usb.rst device config data start
395   :end-before: usb.rst device config data end
396   :linenos:
397
398
399The vendor device requests are forwarded by the USB stack core driver to the
400class driver through the registered vendor handler.
401
402For the loopback class driver, :c:func:`loopback_vendor_handler` processes
403the vendor requests:
404
405.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
406   :language: c
407   :start-after: usb.rst vendor handler start
408   :end-before:  usb.rst vendor handler end
409   :linenos:
410
411The class driver waits for the :makevar:`USB_DC_CONFIGURED` device status code
412before transmitting any data.
413
414.. _testing_USB_native_posix:
415
416Testing over USPIP in native_posix
417***********************************
418
419A virtual USB controller implemented through USBIP might be used to test the USB
420device stack. Follow the general build procedure to build the USB sample for
421the native_posix configuration.
422
423Run built sample with:
424
425.. code-block:: console
426
427   west build -t run
428
429In a terminal window, run the following command to list USB devices:
430
431.. code-block:: console
432
433   $ usbip list -r localhost
434   Exportable USB devices
435   ======================
436    - 127.0.0.1
437           1-1: unknown vendor : unknown product (2fe3:0100)
438              : /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1
439              : (Defined at Interface level) (00/00/00)
440              :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
441
442In a terminal window, run the following command to attach the USB device:
443
444.. code-block:: console
445
446   $ sudo usbip attach -r localhost -b 1-1
447
448The USB device should be connected to your Linux host, and verified with the
449following commands:
450
451.. code-block:: console
452
453   $ sudo usbip port
454   Imported USB devices
455   ====================
456   Port 00: <Port in Use> at Full Speed(12Mbps)
457          unknown vendor : unknown product (2fe3:0100)
458          7-1 -> usbip://localhost:3240/1-1
459              -> remote bus/dev 001/002
460   $ lsusb -d 2fe3:0100
461   Bus 007 Device 004: ID 2fe3:0100
462
463USB Vendor and Product identifiers
464**********************************
465
466The USB Vendor ID for the Zephyr project is ``0x2FE3``.
467This USB Vendor ID must not be used when a vendor
468integrates Zephyr USB device support into its own product.
469
470Each USB :ref:`sample<usb-samples>` has its own unique Product ID.
471The USB maintainer, if one is assigned, or otherwise the Zephyr Technical
472Steering Committee, may allocate other USB Product IDs based on well-motivated
473and documented requests.
474
475The following Product IDs are currently used:
476
477+----------------------------------------------------+--------+
478| Sample                                             | PID    |
479+====================================================+========+
480| :zephyr:code-sample:`usb-cdc-acm`                  | 0x0001 |
481+----------------------------------------------------+--------+
482| :zephyr:code-sample:`usb-cdc-acm-composite`        | 0x0002 |
483+----------------------------------------------------+--------+
484| :zephyr:code-sample:`usb-hid-cdc`                  | 0x0003 |
485+----------------------------------------------------+--------+
486| :zephyr:code-sample:`usb-cdc-acm-console`          | 0x0004 |
487+----------------------------------------------------+--------+
488| :zephyr:code-sample:`usb-dfu`                      | 0x0005 |
489+----------------------------------------------------+--------+
490| :zephyr:code-sample:`usb-hid`                      | 0x0006 |
491+----------------------------------------------------+--------+
492| :zephyr:code-sample:`usb-hid-mouse`                | 0x0007 |
493+----------------------------------------------------+--------+
494| :zephyr:code-sample:`usb-mass`                     | 0x0008 |
495+----------------------------------------------------+--------+
496| :zephyr:code-sample:`testusb-app`                  | 0x0009 |
497+----------------------------------------------------+--------+
498| :zephyr:code-sample:`webusb`                       | 0x000A |
499+----------------------------------------------------+--------+
500| :ref:`bluetooth-hci-usb-sample`                    | 0x000B |
501+----------------------------------------------------+--------+
502| :ref:`bluetooth-hci-usb-h4-sample`                 | 0x000C |
503+----------------------------------------------------+--------+
504| :zephyr:code-sample:`wpan-usb`                     | 0x000D |
505+----------------------------------------------------+--------+
506
507The USB device descriptor field ``bcdDevice`` (Device Release Number) represents
508the Zephyr kernel major and minor versions as a binary coded decimal value.
509