usb_device.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. USB Device Driver
  2. =================
  3. {IDF_TARGET_USB_DP_GPIO_NUM:default="20"}
  4. {IDF_TARGET_USB_DM_GPIO_NUM:default="19"}
  5. {IDF_TARGET_USB_EP_NUM:default="6"}
  6. {IDF_TARGET_USB_EP_NUM_INOUT:default="5"}
  7. {IDF_TARGET_USB_EP_NUM_IN:default="1"}
  8. Overview
  9. --------
  10. The driver allows you to use {IDF_TARGET_NAME} chips to develop USB devices on a top of TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as simple or composite device supporting several USB devices simultaneously.
  11. TinyUSB stack is distributed via `IDF Component Registry <https://components.espressif.com/components/espressif/esp_tinyusb>`_.
  12. Our USB-OTG implementation is limited to {IDF_TARGET_USB_EP_NUM} USB endpoints ({IDF_TARGET_USB_EP_NUM_INOUT} IN/OUT endpoints and {IDF_TARGET_USB_EP_NUM_IN} IN endpoint) . Please note that enabling Secure Boot or flash encryption disables the USB-OTG USB stack in the ROM, disallowing updates via the serial emulation or Device Firmware Update (DFU) on that port. For more details, please refer to `technical reference manual <{IDF_TARGET_TRM_EN_URL}>`_.
  13. Features
  14. --------
  15. - Configuration of device and string USB descriptors
  16. - USB Serial Device (CDC-ACM)
  17. - Input and output streams through USB Serial Device
  18. - Other USB classes (MIDI, MSC, HID...) support directly via TinyUSB
  19. - VBUS monitoring for self-powered devices
  20. Hardware USB Connection
  21. -----------------------
  22. - Any board with the {IDF_TARGET_NAME} chip with USB connectors or with exposed USB's D+ and D- (DATA+/DATA-) pins.
  23. If the board has no USB connector but has the pins, connect pins directly to the host (e.g. with do-it-yourself cable from any USB connection cable).
  24. On {IDF_TARGET_NAME}, connect GPIO {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_USB_DM_GPIO_NUM} to D+/D- respectively:
  25. .. figure:: ../../../_static/usb-board-connection.png
  26. :align: center
  27. :alt: Connection of an ESP board to a USB host
  28. :figclass: align-center
  29. Self-powered devices must also connect VBUS through voltage divider or comparator, more details in :ref:`self-powered-device` subchapter.
  30. Driver Structure
  31. ----------------
  32. As the basis is used the TinyUSB stack.
  33. On top of it the driver implements:
  34. - Customization of USB descriptors
  35. - Serial device support
  36. - Redirecting of standard streams through the Serial device
  37. - Encapsulated driver's task servicing the TinyUSB
  38. Configuration
  39. -------------
  40. Via Menuconfig options you can specify:
  41. - Several of descriptor's parameters (see: Descriptors Configuration bellow)
  42. - USB Serial low-level Configuration
  43. - The verbosity of the TinyUSB's log
  44. - Disable the TinyUSB main task (for the custom implementation)
  45. Descriptors Configuration
  46. ^^^^^^^^^^^^^^^^^^^^^^^^^
  47. The driver's descriptors are provided by :cpp:type:`tinyusb_config_t` structure's :cpp:member:`device_descriptor`, :cpp:member:`configuration_descriptor` and :cpp:member:`string_descriptor` members. Therefore, you should initialize :cpp:type:`tinyusb_config_t` with your desired descriptors before calling :cpp:func:`tinyusb_driver_install` to install the driver.
  48. However, the driver also provides default descriptors. You can install the driver with default device and string descriptors by setting the :cpp:member:`device_descriptor` and :cpp:member:`string_descriptor` members of :cpp:type:`tinyusb_config_t` to `NULL` before calling :cpp:func:`tinyusb_driver_install`. To lower your development effort we also provide default configuration descriptor for CDC and MSC class, as these classes rarely require custom configuration. The driver's default device descriptor is specified using Menuconfig, where the following fields should be configured:
  49. - PID
  50. - VID
  51. - bcdDevice
  52. - Manufacturer
  53. - Product name
  54. - Name of CDC or MSC device if it is On
  55. - Serial number
  56. If you want to use your own descriptors with extended modification, you can define them during the driver installation process.
  57. Install Driver
  58. --------------
  59. To initialize the driver, users should call :cpp:func:`tinyusb_driver_install`. The driver's configuration is specified in a :cpp:type:`tinyusb_config_t` structure that is passed as an argument to :cpp:func:`tinyusb_driver_install`.
  60. Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``const tinyusb_config_t tusb_cfg = { 0 };``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below)
  61. .. code-block:: c
  62. const tinyusb_config_t partial_init = {
  63. .device_descriptor = NULL, // Use default device descriptor specified in Menuconfig
  64. .string_descriptor = NULL, // Use default string descriptors specified in Menuconfig
  65. .external_phy = false, // Use internal USB PHY
  66. .configuration_descriptor = NULL, // Use default configuration descriptor according to settings in Menuconfig
  67. };
  68. .. _self-powered-device:
  69. Self-Powered Device
  70. -------------------
  71. USB specification mandates self-powered devices to monitor voltage level on USB's VBUS signal. As opposed to bus-powered devices, a self-powered device can be fully functional even without USB connection. The self-powered device detects connection and disconnection events by monitoring the VBUS voltage level. VBUS is considered valid if it rises above 4.75V and invalid if it falls below 4.35V.
  72. No {IDF_TARGET_NAME} pin is 5V tolerant, so you must connect the VBUS to {IDF_TARGET_NAME} via a comparator with voltage thresholds as described above, or use a simple resistor voltage divider that will output (0.75 x Vdd) if VBUS is 4.4V (see figure below). In both cases, voltage on the sensing pin must be logic low within 3ms after the device is unplugged from USB host.
  73. .. figure:: ../../../_static/diagrams/usb/usb_vbus_voltage_monitor.png
  74. :align: center
  75. :alt: Simple voltage divider for VBUS monitoring
  76. :figclass: align-center
  77. Simple voltage divider for VBUS monitoring
  78. To use this feature, in :cpp:type:`tinyusb_config_t` you must set :cpp:member:`self_powered` to ``true`` and :cpp:member:`vbus_monitor_io` to GPIO number that will be used for VBUS monitoring.
  79. USB Serial Device (CDC-ACM)
  80. ---------------------------
  81. If the CDC option is enabled in Menuconfig, the USB Serial Device can be initialized with :cpp:func:`tusb_cdc_acm_init` according to the settings from :cpp:type:`tinyusb_config_cdcacm_t` (see example below).
  82. .. code-block:: c
  83. const tinyusb_config_cdcacm_t acm_cfg = {
  84. .usb_dev = TINYUSB_USBDEV_0,
  85. .cdc_port = TINYUSB_CDC_ACM_0,
  86. .rx_unread_buf_sz = 64,
  87. .callback_rx = NULL,
  88. .callback_rx_wanted_char = NULL,
  89. .callback_line_state_changed = NULL,
  90. .callback_line_coding_changed = NULL
  91. };
  92. tusb_cdc_acm_init(&acm_cfg);
  93. To specify callbacks you can either set the pointer to your :cpp:type:`tusb_cdcacm_callback_t` function in the configuration structure or call :cpp:func:`tinyusb_cdcacm_register_callback` after initialization.
  94. USB Serial Console
  95. ^^^^^^^^^^^^^^^^^^
  96. The driver allows to redirect all standard application streams (stdinm stdout, stderr) to the USB Serial Device and return them to UART using :cpp:func:`esp_tusb_init_console`/:cpp:func:`esp_tusb_deinit_console` functions.
  97. USB Mass Storage Device (MSC)
  98. -----------------------------
  99. If the MSC CONFIG_TINYUSB_MSC_ENABLED option is enabled, the USB MSC Device can be initialized as shown below (see example below).
  100. .. code-block:: c
  101. static uint8_t const desc_configuration[] = {
  102. // Config number, interface count, string index, total length, attribute, power in mA
  103. TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
  104. // Interface number, string index, EP Out & EP In address, EP size
  105. TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64),
  106. };
  107. static tusb_desc_device_t descriptor_config = {
  108. .bLength = sizeof(descriptor_config),
  109. .bDescriptorType = TUSB_DESC_DEVICE,
  110. .bcdUSB = 0x0200,
  111. .bDeviceClass = TUSB_CLASS_MISC,
  112. .bDeviceSubClass = MISC_SUBCLASS_COMMON,
  113. .bDeviceProtocol = MISC_PROTOCOL_IAD,
  114. .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
  115. .idVendor = 0x303A,
  116. .idProduct = 0x4002,
  117. .bcdDevice = 0x100,
  118. .iManufacturer = 0x01,
  119. .iProduct = 0x02,
  120. .iSerialNumber = 0x03,
  121. .bNumConfigurations = 0x01
  122. };
  123. static char const *string_desc_arr[] = {
  124. (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
  125. "TinyUSB", // 1: Manufacturer
  126. "TinyUSB Device", // 2: Product
  127. "123456", // 3: Serials
  128. "Example MSC", // 4. MSC
  129. };
  130. const tinyusb_config_t tusb_cfg = {
  131. .device_descriptor = &descriptor_config,
  132. .string_descriptor = string_desc_arr,
  133. .external_phy = false,
  134. .configuration_descriptor = desc_configuration,
  135. };
  136. tinyusb_driver_install(&tusb_cfg);
  137. The mandatory callbacks that are required to be implemented are
  138. .. code-block:: c
  139. void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
  140. bool tud_msc_test_unit_ready_cb(uint8_t lun)
  141. void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size)
  142. bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
  143. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
  144. int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
  145. int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize)
  146. Application Examples
  147. --------------------
  148. The table below describes the code examples available in the directory :example:`peripherals/usb/`.
  149. .. list-table::
  150. :widths: 35 65
  151. :header-rows: 1
  152. * - Code Example
  153. - Description
  154. * - :example:`peripherals/usb/device/tusb_console`
  155. - How to set up {IDF_TARGET_NAME} chip to get log output via Serial Device connection
  156. * - :example:`peripherals/usb/device/tusb_serial_device`
  157. - How to set up {IDF_TARGET_NAME} chip to work as a USB Serial Device
  158. * - :example:`peripherals/usb/device/tusb_midi`
  159. - How to set up {IDF_TARGET_NAME} chip to work as a USB MIDI Device
  160. * - :example:`peripherals/usb/device/tusb_hid`
  161. - How to set up {IDF_TARGET_NAME} chip to work as a USB Human Interface Device
  162. * - :example:`peripherals/usb/device/tusb_msc`
  163. - How to set up {IDF_TARGET_NAME} chip to work as a USB Mass Storage Device