Merge branch 'docs/usb_docs_p4_backport_v5.3' into 'release/v5.3'

usb_host: P4 Docs and DMA fix backport to v5.3

See merge request espressif/esp-idf!33075
This commit is contained in:
morris
2024-09-05 10:40:53 +08:00
11 changed files with 151 additions and 172 deletions

View File

@ -17,7 +17,7 @@ Configuration Set ID: 11
/* 3.1 Basic Config Parameters */
#define OTG_MODE 0
#define OTG_ARCHITECTURE 2
#define OTG_SINGLE_POINT 0
#define OTG_SINGLE_POINT 1
#define OTG_ENABLE_LPM 0
#define OTG_EN_DED_TX_FIFO 1
#define OTG_EN_DESC_DMA 1

View File

@ -11,7 +11,6 @@
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_heap_caps.h"
#include "esp_dma_utils.h"
#include "esp_intr_alloc.h"
#include "soc/interrupts.h" // For interrupt index
#include "esp_err.h"
@ -25,7 +24,6 @@
#include "soc/soc_caps.h"
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#include "esp_cache.h"
#include "esp_private/esp_cache_private.h"
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
// ----------------------------------------------------- Macros --------------------------------------------------------
@ -325,35 +323,6 @@ static inline void cache_sync_data_buffer(pipe_t *pipe, urb_t *urb, bool done)
}
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
// --------------------- Allocation ------------------------
/**
* @brief Allocate Frame List
*
* - Frame list is allocated in DMA capable memory
* - Frame list is aligned to 512 and cache line size
*
* @note Free the memory with heap_caps_free() call
*
* @param[in] frame_list_len Length of the Frame List
* @return Pointer to allocated frame list
*/
static void *frame_list_alloc(size_t frame_list_len);
/**
* @brief Allocate Transfer Descriptor List
*
* - Frame list is allocated in DMA capable memory
* - Frame list is aligned to 512 and cache line size
*
* @note Free the memory with heap_caps_free() call
*
* @param[in] list_len Required length
* @param[out] list_len_bytes_out Allocated length in bytes (can be greater than required)
* @return Pointer to allocated transfer descriptor list
*/
static void *transfer_descriptor_list_alloc(size_t list_len, size_t *list_len_bytes_out);
// ------------------- Buffer Control ----------------------
/**
@ -987,7 +956,7 @@ static port_t *port_obj_alloc(void)
{
port_t *port = calloc(1, sizeof(port_t));
usb_dwc_hal_context_t *hal = malloc(sizeof(usb_dwc_hal_context_t));
void *frame_list = frame_list_alloc(FRAME_LIST_LEN);
void *frame_list = heap_caps_aligned_calloc(USB_DWC_FRAME_LIST_MEM_ALIGN, FRAME_LIST_LEN, sizeof(uint32_t), MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED | MALLOC_CAP_INTERNAL);
SemaphoreHandle_t port_mux = xSemaphoreCreateMutex();
if (port == NULL || hal == NULL || frame_list == NULL || port_mux == NULL) {
free(port);
@ -1015,59 +984,6 @@ static void port_obj_free(port_t *port)
free(port);
}
void *frame_list_alloc(size_t frame_list_len)
{
esp_err_t ret;
void *frame_list = NULL;
size_t actual_size = 0;
esp_dma_mem_info_t dma_mem_info = {
.dma_alignment_bytes = USB_DWC_FRAME_LIST_MEM_ALIGN,
};
ret = esp_dma_capable_calloc(frame_list_len, sizeof(uint32_t), &dma_mem_info, &frame_list, &actual_size);
assert(ret == ESP_OK);
// Both Frame List start address and size should be already cache aligned so this is only a sanity check
if (frame_list) {
if (!esp_dma_is_buffer_alignment_satisfied(frame_list, actual_size, dma_mem_info)) {
// This should never happen
heap_caps_free(frame_list);
frame_list = NULL;
}
}
return frame_list;
}
void *transfer_descriptor_list_alloc(size_t list_len, size_t *list_len_bytes_out)
{
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
// Required Transfer Descriptor List size (in bytes) might not be aligned to cache line size, align the size up
size_t data_cache_line_size = 0;
esp_cache_get_alignment(MALLOC_CAP_DMA, &data_cache_line_size);
const size_t required_list_len_bytes = list_len * sizeof(usb_dwc_ll_dma_qtd_t);
*list_len_bytes_out = ALIGN_UP_BY(required_list_len_bytes, data_cache_line_size);
#else
*list_len_bytes_out = list_len * sizeof(usb_dwc_ll_dma_qtd_t);
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_err_t ret;
void *qtd_list = NULL;
size_t actual_size = 0;
esp_dma_mem_info_t dma_mem_info = {
.dma_alignment_bytes = USB_DWC_QTD_LIST_MEM_ALIGN,
};
ret = esp_dma_capable_calloc(*list_len_bytes_out, 1, &dma_mem_info, &qtd_list, &actual_size);
assert(ret == ESP_OK);
if (qtd_list) {
if (!esp_dma_is_buffer_alignment_satisfied(qtd_list, actual_size, dma_mem_info)) {
// This should never happen
heap_caps_free(qtd_list);
qtd_list = NULL;
}
}
return qtd_list;
}
// ----------------------- Public --------------------------
esp_err_t hcd_install(const hcd_config_t *config)
@ -1593,16 +1509,24 @@ static dma_buffer_block_t *buffer_block_alloc(usb_transfer_type_t type)
desc_list_len = XFER_LIST_LEN_INTR;
break;
}
// DMA buffer lock: Software structure for managing the transfer buffer
dma_buffer_block_t *buffer = calloc(1, sizeof(dma_buffer_block_t));
size_t real_len = 0;
void *xfer_desc_list = transfer_descriptor_list_alloc(desc_list_len, &real_len);
if (buffer == NULL || xfer_desc_list == NULL) {
if (buffer == NULL) {
return NULL;
}
// Transfer descriptor list: Must be 512 aligned and DMA capable (USB-DWC requirement) and its size must be cache aligned
void *xfer_desc_list = heap_caps_aligned_calloc(USB_DWC_QTD_LIST_MEM_ALIGN, desc_list_len * sizeof(usb_dwc_ll_dma_qtd_t), 1, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED | MALLOC_CAP_INTERNAL);
if (xfer_desc_list == NULL) {
free(buffer);
heap_caps_free(xfer_desc_list);
return NULL;
}
buffer->xfer_desc_list = xfer_desc_list;
buffer->xfer_desc_list_len_bytes = real_len;
// For targets with L1CACHE, the allocated size might be bigger than requested, this value is than used during memory sync
// We save this value here, so we don't have to call 'heap_caps_get_allocated_size()' during every memory sync
buffer->xfer_desc_list_len_bytes = heap_caps_get_allocated_size(xfer_desc_list);
return buffer;
}

View File

@ -21,7 +21,6 @@
#include "test_usb_common.h"
#include "mock_msc.h"
#include "unity.h"
#include "esp_dma_utils.h"
#define PORT_NUM 1
#define EVENT_QUEUE_LEN 5
@ -264,19 +263,14 @@ urb_t *test_hcd_alloc_urb(int num_isoc_packets, size_t data_buffer_size)
{
// Allocate a URB and data buffer
urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (sizeof(usb_isoc_packet_desc_t) * num_isoc_packets), MALLOC_CAP_DEFAULT);
void *data_buffer;
size_t real_size;
esp_dma_mem_info_t dma_mem_info = {
.dma_alignment_bytes = 4,
};
esp_dma_capable_malloc(data_buffer_size, &dma_mem_info, &data_buffer, &real_size);
void *data_buffer = heap_caps_malloc(data_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED);
TEST_ASSERT_NOT_NULL_MESSAGE(urb, "Failed to allocate URB");
TEST_ASSERT_NOT_NULL_MESSAGE(data_buffer, "Failed to allocate transfer buffer");
// Initialize URB and underlying transfer structure. Need to cast to dummy due to const fields
usb_transfer_dummy_t *transfer_dummy = (usb_transfer_dummy_t *)&urb->transfer;
transfer_dummy->data_buffer = data_buffer;
transfer_dummy->data_buffer_size = real_size;
transfer_dummy->data_buffer_size = heap_caps_get_allocated_size(data_buffer);
transfer_dummy->num_isoc_packets = num_isoc_packets;
return urb;
}

View File

@ -5,27 +5,20 @@
*/
#include "esp_heap_caps.h"
#include "esp_dma_utils.h"
#include "usb_private.h"
#include "usb/usb_types_ch9.h"
urb_t *urb_alloc(size_t data_buffer_size, int num_isoc_packets)
{
urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (sizeof(usb_isoc_packet_desc_t) * num_isoc_packets), MALLOC_CAP_DEFAULT);
void *data_buffer;
size_t real_size;
esp_dma_mem_info_t dma_mem_info = {
.dma_alignment_bytes = 4,
};
//TODO: IDF-9639
esp_dma_capable_malloc(data_buffer_size, &dma_mem_info, &data_buffer, &real_size);
void *data_buffer = heap_caps_malloc(data_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED);
if (urb == NULL || data_buffer == NULL) {
goto err;
}
// Cast as dummy transfer so that we can assign to const fields
usb_transfer_dummy_t *dummy_transfer = (usb_transfer_dummy_t *)&urb->transfer;
dummy_transfer->data_buffer = data_buffer;
dummy_transfer->data_buffer_size = real_size;
dummy_transfer->data_buffer_size = heap_caps_get_allocated_size(data_buffer);
dummy_transfer->num_isoc_packets = num_isoc_packets;
return urb;
err:

View File

@ -8,13 +8,6 @@ api-guides/dfu.rst
api-guides/wifi-security.rst
api-reference/peripherals/adc_continuous.rst
api-reference/peripherals/adc_oneshot.rst
api-reference/peripherals/usb_host.rst
api-reference/peripherals/usb_host/usb_host_notes_arch.rst
api-reference/peripherals/usb_host/usb_host_notes_index.rst
api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst
api-reference/peripherals/usb_host/usb_host_notes_design.rst
api-reference/peripherals/usb_host/usb_host_notes_usbh.rst
api-reference/peripherals/usb_device.rst
api-reference/peripherals/touch_element.rst
api-reference/peripherals/touch_pad.rst
api-reference/peripherals/adc_calibration.rst

View File

@ -5,9 +5,9 @@ USB Device Stack
{IDF_TARGET_USB_DP_GPIO_NUM:default="20"}
{IDF_TARGET_USB_DM_GPIO_NUM:default="19"}
{IDF_TARGET_USB_EP_NUM:default="6"}
{IDF_TARGET_USB_EP_NUM_INOUT:default="5"}
{IDF_TARGET_USB_EP_NUM_IN:default="1"}
{IDF_TARGET_USB_EP_NUM: default="6", esp32p4="15"}
{IDF_TARGET_USB_EP_NUM_INOUT:default="5", esp32p4="8"}
{IDF_TARGET_USB_EP_NUM_IN:default="1", esp32p4="7"}
Overview
--------
@ -34,16 +34,24 @@ Features
Hardware Connection
-------------------
The {IDF_TARGET_NAME} routes the USB D+ and D- signals to GPIOs {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_USB_DM_GPIO_NUM} respectively. For USB device functionality, these GPIOs should be connected to the bus in some way (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug).
.. only:: esp32s2 or esp32s3
The {IDF_TARGET_NAME} routes the USB D+ and D- signals to GPIOs {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_USB_DM_GPIO_NUM} respectively. For USB device functionality, these GPIOs should be connected to the bus in some way (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug).
.. only:: esp32p4
The {IDF_TARGET_NAME} routes the USB D+ and D- signals to their dedicated pins. For USB device functionality, these pins should be connected to the bus in some way (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug).
.. figure:: ../../../_static/usb-board-connection.png
:align: center
:alt: Connection of an USB GPIOs directly to a USB standard-A plug
:figclass: align-center
.. note::
.. only:: esp32s2 or esp32s3
If you are using an {IDF_TARGET_NAME} development board with two USB ports, the port labeled "USB" will already be connected to the D+ and D- GPIOs.
.. note::
If you are using an {IDF_TARGET_NAME} development board with two USB ports, the port labeled "USB" will already be connected to the D+ and D- GPIOs.
.. note::
@ -95,15 +103,17 @@ Full-speed devices should initialize the following field to provide their config
- :cpp:member:`configuration_descriptor`
High-speed devices should initialize the following fields to provide configuration descriptors at each speed:
.. only:: esp32p4
- :cpp:member:`fs_configuration_descriptor`
- :cpp:member:`hs_configuration_descriptor`
- :cpp:member:`qualifier_descriptor`
High-speed devices should initialize the following fields to provide configuration descriptors at each speed:
.. note::
- :cpp:member:`fs_configuration_descriptor`
- :cpp:member:`hs_configuration_descriptor`
- :cpp:member:`qualifier_descriptor`
When Device Stack supports high-speed, both :cpp:member:`fs_configuration_descriptor` and :cpp:member:`hs_configuration_descriptor` should be present to comply with usb2.0 specification.
.. note::
Both :cpp:member:`fs_configuration_descriptor` and :cpp:member:`hs_configuration_descriptor` must be present to comply with USB 2.0 specification.
The Device Stack will instantiate a USB device based on the descriptors provided in the fields described above when :cpp:func:`tinyusb_driver_install` is called.

View File

@ -25,18 +25,26 @@ Features & Limitations
The Host Library has the following features:
- Supports Full Speed (FS) and Low Speed (LS) Devices.
- Supports all four transfer types, i.e., Control, Bulk, Interrupt, and Isochronous.
- Allows multiple class drivers to run simultaneously, i.e., multiple clients of the Host Library.
- A single device can be used by multiple clients simultaneously, e.g., composite devices.
- The Host Library itself and the underlying Host Stack does not internally instantiate any OS tasks. The number of tasks is entirely controlled by how the Host Library interface is used. However, a general rule of thumb regarding the number of tasks is ``(the number of host class drivers running + 1)``.
.. list::
:esp32s2 or esp32s3: - Supports Full Speed (FS) and Low Speed (LS) Devices.
:esp32p4: - Supports High Speed (HS), Full Speed (FS) and Low Speed (LS) Devices.
- Supports all four transfer types: Control, Bulk, Interrupt, and Isochronous.
:esp32p4: - Supports High-Bandwidth Isochronous endpoints.
- Allows multiple class drivers to run simultaneously, i.e., multiple clients of the Host Library.
- A single device can be used by multiple clients simultaneously, e.g., composite devices.
- The Host Library itself and the underlying Host Stack does not internally instantiate any OS tasks. The number of tasks is entirely controlled by how the Host Library interface is used. However, a general rule of thumb regarding the number of tasks is ``(the number of host class drivers running + 1)``.
Currently, the Host Library and the underlying Host Stack has the following limitations:
- Only supports a single device, but the Host Library's API is designed for multiple device support.
- Only supports Asynchronous transfers.
- Only supports using the first configuration found. Changing to other configurations is not supported yet.
- Transfer timeouts are not supported yet.
.. list::
- Only supports a single device, but the Host Library's API is designed for multiple device support.
- Only supports Asynchronous transfers.
- Only supports using one configuration. Changing to other configurations after enumeration is not supported yet.
- Transfer timeouts are not supported yet.
:esp32p4: - {IDF_TARGET_NAME} contains two USB-OTG peripherals USB 2.0 OTG High-Speed and USB 2.0 OTG Full-Speed. Only the High-Speed instance is supported now.
:esp32p4: - {IDF_TARGET_NAME} cannot enumerate Low-Speed devices yet.
.. -------------------------------------------------- Architecture -----------------------------------------------------
@ -89,7 +97,7 @@ Therefore, in addition to the client tasks, the Host Library also requires a tas
Devices
^^^^^^^
The Host Library shields clients from the details of device handling, encompassing details such as connection, memory allocation, and enumeration. The clients are provided only with a list of already connected and enumerated devices to choose from. During enumeration, each device is automatically configured to use the first configuration found, namely, the first configuration descriptor returned on a Get Configuration Descriptor request. For most standard devices, the first configuration will have a ``bConfigurationValue`` of ``1``.
The Host Library shields clients from the details of device handling, encompassing details such as connection, memory allocation, and enumeration. The clients are provided only with a list of already connected and enumerated devices to choose from. By default during enumeration, each device is automatically configured to use the first configuration found, namely, the first configuration descriptor returned on a Get Configuration Descriptor request. For most standard devices, the first configuration will have a ``bConfigurationValue`` of ``1``. If option :ref:`CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK` is enabled, a different ``bConfigurationValue`` can be selected, see `Multiple configuration Support`_ for more details.
It is possible for two or more clients to simultaneously communicate with the same device as long as they are not communicating to the same interface. However, multiple clients can simultaneously communicate with the same device's default endpoint (i.e., EP0), which will result in their control transfers being serialized.

View File

@ -37,7 +37,7 @@ The layers of the Host Stack are described in the following table. The layers ar
- ``usb_host.h``, ``usb_host.c``
- The USB Host Library layer is the lowest public API layer of the Host Stack and presents the concept of USB Host Clients. The abstraction of clients allows for multiple class drivers to coexist simultaneously (where each class roughly maps to a single client) and also acts as a mechanism for division of labor (where each client is responsible for its own processing and event handling).
* - Host Class Drivers
- See the `ESP-IDF Extra Components repository <https://github.com/espressif/idf-extra-components>`_ or the USB Host examples in ESP-IDF (via :example:`peripherals/usb/host`).
- See the `ESP-USB repository <https://github.com/espressif/esp-usb>`_ or the USB Host examples in ESP-IDF (via :example:`peripherals/usb/host`).
- The Host Class Drivers implement the host side of a particular device class (e.g., CDC, MSC, HID). The exposed API is specific to each class driver.
Layer Dependencies

View File

@ -89,26 +89,51 @@ Hardware Configuration
The DWC_OTG IP is configurable. The notable Host related configurations of the {IDF_TARGET_NAME}'s DWC_OTG are listed below:
.. list-table:: {IDF_TARGET_NAME}'s DWC_OTG Configuration
:widths: 70 30
:header-rows: 1
.. only:: esp32p4
* - Description
- Configuration
* - Host and Device Mode support with OTG
- ``OTG_MODE = 0``
* - Full Speed (FS) and Low Speed (LS) support
- ``OTG_FSPHY_INTERFACE = 1``, ``OTG_HSPHY_INTERFACE = 0``
* - Internal DMA controller with Scatter/Gather DMA
- ``OTG_ARCHITECTURE = 2``, ``OTG_EN_DESC_DMA = 1``
* - FS Hubs are supported but HS Hub are not (i.e., split transfers not supported)
- ``OTG_SINGLE_POINT = 0``
* - 8 Host Mode channels
- ``OTG_NUM_HOST_CHAN = 8``
* - All transfer types supported, including ISOC and INTR OUT transfers
- ``OTG_EN_PERIO_HOST = 1``
* - Dynamically sized Data FIFO of 1024 bytes (256 lines)
- ``OTG_DFIFO_DYNAMIC = 1``, ``OTG_DFIFO_DEPTH = 256``
.. list-table:: {IDF_TARGET_NAME}'s DWC_OTG Configuration
:widths: 70 30
:header-rows: 1
* - Description
- Configuration
* - Host and Device Mode support with OTG
- ``OTG_MODE = 0``
* - High Speed (HS), Full Speed (FS) and Low Speed (LS) support
- ``OTG_FSPHY_INTERFACE = 2``, ``OTG_HSPHY_INTERFACE = 3``
* - Internal DMA controller with Scatter/Gather DMA
- ``OTG_ARCHITECTURE = 2``, ``OTG_EN_DESC_DMA = 1``
* - Split transfers not supported
- ``OTG_SINGLE_POINT = 1``
* - 16 Host Mode channels
- ``OTG_NUM_HOST_CHAN = 16``
* - All transfer types supported, including ISOC and INTR OUT transfers
- ``OTG_EN_PERIO_HOST = 1``
* - Dynamically sized Data FIFO of 4096 bytes (1024 lines)
- ``OTG_DFIFO_DYNAMIC = 1``, ``OTG_DFIFO_DEPTH = 1024``
* - Only 4 periodic and 4 non-periodic transactions per microframe
- ``OTG_NPERIO_TX_QUEUE_DEPTH = 4``, ``OTG_PERIO_TX_QUEUE_DEPTH = 4``
.. only:: esp32s2 or esp32s3
.. list-table:: {IDF_TARGET_NAME}'s DWC_OTG Configuration
:widths: 70 30
:header-rows: 1
* - Description
- Configuration
* - Host and Device Mode support with OTG
- ``OTG_MODE = 0``
* - Full Speed (FS) and Low Speed (LS) support
- ``OTG_FSPHY_INTERFACE = 1``, ``OTG_HSPHY_INTERFACE = 0``
* - Internal DMA controller with Scatter/Gather DMA
- ``OTG_ARCHITECTURE = 2``, ``OTG_EN_DESC_DMA = 1``
* - 8 Host Mode channels
- ``OTG_NUM_HOST_CHAN = 8``
* - All transfer types supported, including ISOC and INTR OUT transfers
- ``OTG_EN_PERIO_HOST = 1``
* - Dynamically sized Data FIFO of 1024 bytes (256 lines)
- ``OTG_DFIFO_DYNAMIC = 1``, ``OTG_DFIFO_DEPTH = 256``
Scatter/Gather DMA Transfer
---------------------------

View File

@ -5,9 +5,9 @@ USB 设备栈
{IDF_TARGET_USB_DP_GPIO_NUM:default="20"}
{IDF_TARGET_USB_DM_GPIO_NUM:default="19"}
{IDF_TARGET_USB_EP_NUM:default="6"}
{IDF_TARGET_USB_EP_NUM_INOUT:default="5"}
{IDF_TARGET_USB_EP_NUM_IN:default="1"}
{IDF_TARGET_USB_EP_NUM: default="6", esp32p4="15"}
{IDF_TARGET_USB_EP_NUM_INOUT:default="5", esp32p4="8"}
{IDF_TARGET_USB_EP_NUM_IN:default="1", esp32p4="7"}
概述
--------
@ -34,16 +34,24 @@ USB 设备栈(以下简称设备栈)支持在 {IDF_TARGET_NAME} 上启用 US
硬件连接
--------
{IDF_TARGET_NAME} 将 USB D+ 和 D- 信号分别路由到 GPIO {IDF_TARGET_USB_DP_GPIO_NUM} 和 {IDF_TARGET_USB_DM_GPIO_NUM}。为了实现 USB 设备功能,这些 GPIO 应通过某种方式连接到总线上(例如,通过 Micro-B 端口、USB-C 端口或直接连接到标准-A 插头)。
.. only:: esp32s2 or esp32s3
{IDF_TARGET_NAME} 将 USB D+ 和 D- 信号分别路由到 GPIO {IDF_TARGET_USB_DP_GPIO_NUM} 和 {IDF_TARGET_USB_DM_GPIO_NUM}。为了实现 USB 设备功能,这些 GPIO 应通过某种方式连接到总线(例如,通过 Micro-B 端口、USB-C 端口或直接连接到标准-A 插头)。
.. only:: esp32p4
{IDF_TARGET_NAME} 将 USB D+ 和 D- 信号路由到其专用引脚。为了实现 USB 设备功能,这些引脚应通过某种方式连接到总线(例如,通过 Micro-B 端口、USB-C 端口或直接连接到标准-A 插头)。
.. figure:: ../../../_static/usb-board-connection.png
:align: center
:alt: 将 USB GPIO 直接接连至 USB 标准-A 插头
:figclass: align-center
.. note::
.. only:: esp32s2 or esp32s3
如果你使用带有两个 USB 端口的 {IDF_TARGET_NAME} 开发板,标有 "USB" 的端口已经连接到 D+ 和 D- GPIO。
.. note::
如果你使用带有两个 USB 端口的 {IDF_TARGET_NAME} 开发板,标有 "USB" 的端口已经连接到 D+ 和 D- GPIO。
.. note::
@ -90,6 +98,22 @@ USB 设备栈(以下简称设备栈)支持在 {IDF_TARGET_NAME} 上启用 US
- :cpp:member:`configuration_descriptor`
- :cpp:member:`string_descriptor`
全速 USB 设备应初始化以下字段,以提供相应的配置描述符:
- :cpp:member:`configuration_descriptor`
.. only:: esp32p4
高速 USB 设备应初始化以下字段,以提供不同速度下的配置描述符:
- :cpp:member:`fs_configuration_descriptor`
- :cpp:member:`hs_configuration_descriptor`
- :cpp:member:`qualifier_descriptor`
.. note::
为符合 USB 2.0 协议规范,需同时初始化 :cpp:member:`fs_configuration_descriptor`:cpp:member:`hs_configuration_descriptor`
调用 :cpp:func:`tinyusb_driver_install` 时,设备栈将基于上述字段中提供的描述符实现 USB 设备。
设备栈还提供了默认描述符,将 :cpp:func:`tinyusb_driver_install` 中的相应字段设置为 ``NULL`` 即可安装。默认描述符包括:

View File

@ -25,18 +25,26 @@ USB 主机库(以下简称主机库)是 USB 主机栈的最底层,提供
主机库具有以下特性:
- 支持全速 (FS) 和低速 (LS) 设备。
- 支持四种传输类型,即控制传输、块传输、中断传输和同步传输。
- 支持多个 Class 驱动程序同时运行,即主机的多个客户端同时运行。
- 单个设备可以由多个客户端同时使用,如复合设备。
- 主机库及其底层主机栈不会在内部自动创建操作系统任务,任务数量完全由主机库接口的使用方式决定。一般来说,任务数量为 ``(运行中的主机 Class 驱动程序数量 + 1``
.. list::
:esp32s2 or esp32s3: - 支持全速 (FS) 和低速 (LS) 设备。
:esp32p4: - 支持高速 (HS)、全速 (FS) 和低速 (LS) 设备。
- 支持四种传输类型,即控制传输、块传输、中断传输和同步传输。
:esp32p4: - 支持高带宽等时性端点。
- 支持多个 Class 驱动程序同时运行,即主机的多个客户端同时运行。
- 单个设备可以由多个客户端同时使用,如复合设备。
- 主机库及其底层主机栈不会在内部自动创建操作系统任务,任务数量完全由主机库接口的使用方式决定。一般来说,任务数量为 ``(运行中的主机 Class 驱动程序数量 + 1``
目前,主机库及其底层主机栈存在以下限制:
- 仅支持单个设备,而主机库的 API 支持多设备。
- 仅支持异步传输。
- 仅支持使用发现的首个配置,尚不支持变更为其他配置
- 尚不支持传输超时
.. list::
- 仅支持单个设备,而主机库的 API 支持多设备
- 仅支持异步传输
- 仅支持使用发现的首个配置,尚不支持变更为其他配置。
- 尚不支持传输超时。
:esp32p4: - {IDF_TARGET_NAME} 包含两个 USB-OTG 外设USB 2.0 OTG 高速和 USB 2.0 OTG 全速。目前仅支持高速实例。
:esp32p4: - {IDF_TARGET_NAME} 目前无法枚举低速设备。
.. -------------------------------------------------- Architecture -----------------------------------------------------
@ -89,7 +97,7 @@ USB 主机库(以下简称主机库)是 USB 主机栈的最底层,提供
设备
^^^^^^^
主机库隔离了客户端与设备处理的细节,包括连接、内存分配和枚举等,客户端只需提供已连接且已枚举的设备列表供选择。在枚举过程中,每个设备都会自动配置为使用找到的第一个配置,即通过获取配置描述符请求返回的第一个配置描述符。对于大多数标准设备,通常将第一个配置的 ``bConfigurationValue`` 设置为 ``1``
主机库隔离了客户端与设备处理的细节,包括连接、内存分配和枚举等,客户端只需提供已连接且已枚举的设备列表供选择。默认情况下,在枚举过程中,每个设备都会自动配置为使用找到的第一个配置,即通过获取配置描述符请求返回的第一个配置描述符。对于大多数标准设备,通常将第一个配置的 ``bConfigurationValue`` 设置为 ``1``启用选项 :ref:`CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK` 后,可以选择不同的 ``bConfigurationValue``。获取更多详细信息,请参阅 `Multiple configuration Support_`
只要不与相同接口通信,两个及以上的客户端可以同时与同一设备通信。然而,多个客户端同时与相同设备的默认端点(即 EP0通信将导致它们的控制传输序列化。