# USB 主机

[English]

本文档提供了 USB 主机库的相关信息，按以下章节展开：

## 概述

USB 主机库（以下简称主机库）是 USB 主机栈的最底层，提供面向公众开放的 API。应用程序使用 USB 主机功能时，通常无需与主机库直接交互，而是使用某个主机 Class 驱动提供的 API，这些主机 Class 驱动构建在主机库之上。

然而，由于以下的某些原因（但不仅限于此），有时你可能需要直接使用主机库：

- 需要实现自定义主机 Class 驱动程序

- 需要更低级别的 USB 主机 API

### 特性和限制

主机库具有以下特性：

- 支持全速 (FS) 和低速 (LS) 设备。

- 支持四种传输类型，即控制传输、块传输、中断传输和同步传输。

- 支持多个 Class 驱动程序同时运行，即主机的多个客户端同时运行。

- 单个设备可以由多个客户端同时使用，如复合设备。

- 主机库及其底层主机栈不会在内部自动创建操作系统任务，任务数量完全由主机库接口的使用方式决定。一般来说，任务数量为 `（运行中的主机 Class 驱动程序数量 + 1）`。

- 支持单个 Hub（启用选项 CONFIG_USB_HOST_HUBS_SUPPORTED）。

- 支持多个 Hub（启用选项 CONFIG_USB_HOST_HUB_MULTI_LEVEL）。

目前，主机库及其底层主机栈存在以下限制：

- 仅支持异步传输。

- 仅支持使用发现的首个配置，尚不支持变更为其他配置。

- 尚不支持传输超时。

- 外部 Hub 驱动：不支持远程唤醒功能（即使没有设备插入，外部 Hub 也处于工作状态）。

- 外部 Hub 驱动：不处理错误用例（尚未实现过流处理、初始化错误等功能）。

- 外部 Hub 驱动：不支持接口选择。驱动程序使用具有 Hub 类代码 (09h) 的第一个可用接口。

- 外部端口驱动：无下游端口去抖动机制（尚未实现）。

## 架构

USB 主机功能涉及的关键实体

上图展示了使用 USB 主机功能时涉及的关键实体，包括：

- 主机库

- 主机库的 客户端

- 设备

- 主机库的 守护进程任务

### 主机库

主机库是 ESP-IDF USB 主机栈中面向公众开放的最底层的 API 层。任何其他 ESP-IDF 组件（如 Class 驱动程序或用户组件），如果需要与连接的 USB 设备通信，只能直接或间接使用主机库 API。

主机库 API 分为两类，即 库 API 和 客户端 API。

- 客户端 API 负责主机库的客户端与一或多个 USB 设备间的通信，该 API 只能由主机库的注册客户端调用。

- 库 API 负责主机库处理的通信中不特定于单个客户端的通信，如设备枚举。该 API 通常由主机库的守护进程任务调用。

### 客户端

主机库的客户端指使用主机库与 USB 设备通信的软件组件，如主机 Class 驱动程序或用户组件。每个客户端通常与任务间存在一对一关系，这表明，对特定客户端而言，其所有客户端 API 都应该在同一任务的上下文中调用。

通过将使用主机库的软件组件进行分类，划分为独立的客户端，主机库可以将所有客户端特定事件的处理委托给客户端对应的任务。换句话说，每个客户端任务负责管理与其对应的客户端之间的所有 USB 通信操作和事件处理，无需关心其他客户端的事件。

### 守护进程任务

尽管主机库将客户端事件的处理委托给客户端本身，但仍然需要处理主机库事件，即不特定于客户端的事件。主机库事件处理可能涉及以下内容：

- 处理 USB 设备的连接、枚举和断连

- 将控制传输从/向客户端进行重定向

- 将事件转发给客户端

因此，除客户端任务外，主机库也需要一个任务来处理所有的库事件，这个任务通常是主机库守护进程任务。

### 设备

主机库隔离了客户端与设备处理的细节，包括连接、内存分配和枚举等，客户端只需提供已连接且已枚举的设备列表供选择。默认情况下，在枚举过程中，每个设备都会自动配置为使用找到的第一个配置，即通过获取配置描述符请求返回的第一个配置描述符。对于大多数标准设备，通常将第一个配置的 `bConfigurationValue` 设置为 `1`。启用选项 CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK 后，可以选择不同的 `bConfigurationValue`。获取更多详细信息，请参阅 多项配置支持。

只要不与相同接口通信，两个及以上的客户端可以同时与同一设备通信。然而，多个客户端同时与相同设备的默认端点（即 EP0）通信，将导致它们的控制传输序列化。

要与设备通信，客户端必须满足以下条件：

1. 使用设备地址打开设备，告知主机库，客户端正在使用该设备。

2. 获取将用于通信的接口，防止其他客户端获取相同的接口。

3. 通过已经获取了使用权的设备接口的端点通信通道发送数据传输。客户端的任务负责处理其与 USB 设备通信相关的操作和事件。

## 用法

主机库及底层主机栈不会创建任何任务，客户端任务和守护进程任务等均需由 Class 驱动程序或用户自行创建。然而，主机库提供了两个事件处理函数，可以处理所有必要的主机库操作，这些函数应从客户端任务和守护进程任务中重复调用。因此，客户端任务和守护进程任务的使用将主要集中于调用这些事件处理函数。

### 主机库与守护进程任务

#### 基本用法

主机库 API 提供了 `usb_host_lib_handle_events()`，可以处理库事件。该函数需要反复调用，通常是从守护进程任务中调用。函数 `usb_host_lib_handle_events()` 有以下特点：

- 该函数会持续阻塞，直至需要处理库事件。

- 每次调用该函数都会返回事件标志，有助于了解卸载主机库的时机。

最基础的守护进程任务通常类似以下代码片段：

    #include "usb/usb_host.h"

    void daemon_task(void *arg)
    {
        ...
        bool exit = false;
        while (!exit) {
            uint32_t event_flags;
            usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
            if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
                ...
            }
            if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
                ...
            }
            ...
        }
        ...
    }

备注

了解守护进程任务的完整示例，请前往 peripherals/usb/host/usb_host_lib。

#### 生命周期

USB 主机库典型生命周期

上图展示了 USB 主机库的典型生命周期，其中涉及多个客户端和设备。具体而言，示例涉及以下内容：

- 两个已注册的客户端（客户端 1 和客户端 2）。

- 两个已连接的设备（设备 1 和设备 2），其中客户端 1 与设备 1 通信，客户端 2 与设备 2 通信。

参考上图可知，典型 USB 主机库生命周期包括以下关键阶段：

1. 调用 `usb_host_install()`，安装主机库。

     - 调用任意主机库 API 前，请确保已完成主机库安装。

     - 调用 `usb_host_install()` 的位置（如从守护进程任务或其他任务中调用）取决于守护系统任务、客户端任务和系统其余部分间的同步逻辑。

2. 安装完主机库后，调用 `usb_host_client_register()` 注册客户端。

     - 该注册函数通常从客户端任务调用，而客户端任务需等待来自守护进程任务的信号。

     - 调用过 `usb_host_install()` 后，如有需要，也可以在其他地方调用该注册函数。

3. 设备 1 连接，并进行枚举。

     - 每个已注册的客户端（本案例中为客户端 1 和客户端 2）都会通过 `USB_HOST_CLIENT_EVENT_NEW_DEV` 事件得到新设备的通知。

     - 客户端 1 开启设备 1，并与之通信。

4. 设备 2 连接，并进行枚举。

     - 客户端 1 和 2 通过 `USB_HOST_CLIENT_EVENT_NEW_DEV` 事件得到新设备的通知。

     - 客户端 2 开启设备 2，并与之通信。

5. 设备 1 突然断开连接。

     - 客户端 1 通过 `USB_HOST_CLIENT_EVENT_DEV_GONE` 得到通知，并开始清理，关闭和释放客户端 1 与设备 1 之间的关联资源。

     - 客户端 2 不会收到通知，因为它并未开启设备 1。

6. 客户端 1 完成清理，调用 `usb_host_client_deregister()` 注销客户端。

     - 该注销函数通常在任务退出前，从客户端任务中调用。

     - 如有需要，只要客户端 1 已完成清理，也可以在其他地方调用该注销函数。

7. 客户端 2 完成与设备 2 的通信，随后关闭设备 2，并自行注销。

     - 由于客户端 2 是最后一个注销的客户端，通过 `USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS` 事件标志，守护进程任务可以得知，所有客户端已注销。

     - 设备 2 未释放，仍会进行分配，因为虽然没有任何客户端打开设备 2，但它仍处于连接状态。

8. 所有客户端注销后，守护进程任务开始清理。

     - 守护进程任务需要先调用 `usb_host_device_free_all()`，释放设备 2。

     - 如果 `usb_host_device_free_all()` 能够成功释放所有设备，函数将返回 ESP_OK，表明已释放所有设备。

     - 如果 `usb_host_device_free_all()` 无法成功释放所有设备，例如因为设备仍由某个客户端开启，函数将返回 ESP_ERR_NOT_FINISHED。

     - 守护进程任务必须等待 `usb_host_lib_handle_events()` 返回事件标志 `USB_HOST_LIB_EVENT_FLAGS_ALL_FREE`，方知何时所有设备均已释放。

9. 一旦守护进程任务确认所有客户端均已注销，且所有设备均已释放，便可调用 `usb_host_uninstall()`，卸载主机库。

### 客户端与 Class 驱动程序

#### 基本用法

主机库 API 提供函数 `usb_host_client_handle_events()`，可以处理特定客户端事件。该函数需要反复调用，通常是从客户端任务中调用。函数 `usb_host_client_handle_events()` 有以下特点：

- 该函数可以持续阻塞，直至需要处理客户端事件。

- 该函数的主要目的是发生客户端事件时，调用多个事件处理回调函数。

以下回调函数均从 `usb_host_client_handle_events()` 中调用，因此客户端任务能够获取事件通知。

- 类型为 `usb_host_client_event_cb_t` 的客户端事件回调函数会将客户端事件消息传递给客户端，提示添加、移除设备等事件。

- 类型为 `usb_transfer_cb_t` 的 USB 传输完成回调函数表明，先前由客户端提交的特定 USB 传输已完成。

备注

考虑到上述回调函数从 `usb_host_client_handle_events()` 中调用，应避免在回调函数内部阻塞，否则将导致 `usb_host_client_handle_events()` 阻塞，阻止其他待处理的客户端事件得到处理。

以下代码片段展示了一个基础的主机 Class 驱动程序及其客户端任务，代码片段中包括：

- 一个简单的客户端任务函数 `client_task`，它会在循环中调用 `usb_host_client_handle_events()`。

- 使用客户端事件回调函数和传输完成回调函数。

- 一个用于 Class 驱动程序的简单状态机。该 Class 驱动程序仅支持打开设备，发送 OUT 传输到 EP1，然后关闭设备。

    #include <string.h>
    #include "usb/usb_host.h"

    #define CLASS_DRIVER_ACTION_OPEN_DEV    0x01
    #define CLASS_DRIVER_ACTION_TRANSFER    0x02
    #define CLASS_DRIVER_ACTION_CLOSE_DEV   0x03

    struct class_driver_control {
        uint32_t actions;
        uint8_t dev_addr;
        usb_host_client_handle_t client_hdl;
        usb_device_handle_t dev_hdl;
    };

    static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg)
    {
        //该函数从 usb_host_client_handle_events() 中调用，请勿在此阻塞，并尽量保持简洁
        struct class_driver_control *class_driver_obj = (struct class_driver_control *)arg;
        switch (event_msg->event) {
            case USB_HOST_CLIENT_EVENT_NEW_DEV:
                class_driver_obj->actions |= CLASS_DRIVER_ACTION_OPEN_DEV;
                class_driver_obj->dev_addr = event_msg->new_dev.address; //存储新设备的地址
                break;
            case USB_HOST_CLIENT_EVENT_DEV_GONE:
                class_driver_obj->actions |= CLASS_DRIVER_ACTION_CLOSE_DEV;
                break;
            default:
                break;
        }
    }

    static void transfer_cb(usb_transfer_t *transfer)
    {
        //该函数从 usb_host_client_handle_events() 中调用，请勿在此阻塞，并尽量保持简洁
        struct class_driver_control *class_driver_obj = (struct class_driver_control *)transfer->context;
        printf("Transfer status %d, actual number of bytes transferred %d\n", transfer->status, transfer->actual_num_bytes);
        class_driver_obj->actions |= CLASS_DRIVER_ACTION_CLOSE_DEV;
    }

    void client_task(void *arg)
    {
        ... //等待主机库安装
        //初始化 Class 驱动程序对象
        struct class_driver_control class_driver_obj = {0};
        //注册客户端
        usb_host_client_config_t client_config = {
            .is_synchronous = false,
            .max_num_event_msg = 5,
            .async = {
                .client_event_callback = client_event_cb,
                .callback_arg = &class_driver_obj,
            }
        };
        usb_host_client_register(&client_config, &class_driver_obj.client_hdl);
        //分配一个 USB 传输
        usb_transfer_t *transfer;
        usb_host_transfer_alloc(1024, 0, &transfer);

        //事件处理循环
        bool exit = false;
        while (!exit) {
            //调用客户端事件处理函数
            usb_host_client_handle_events(class_driver_obj.client_hdl, portMAX_DELAY);
            //执行待处理的 Class 驱动程序操作
            if (class_driver_obj.actions & CLASS_DRIVER_ACTION_OPEN_DEV) {
                //开启设备，声明接口 1
                usb_host_device_open(class_driver_obj.client_hdl, class_driver_obj.dev_addr, &class_driver_obj.dev_hdl);
                usb_host_interface_claim(class_driver_obj.client_hdl, class_driver_obj.dev_hdl, 1, 0);
            }
            if (class_driver_obj.actions & CLASS_DRIVER_ACTION_TRANSFER) {
                //发送一个 OUT 传输到 EP1
                memset(transfer->data_buffer, 0xAA, 1024);
                transfer->num_bytes = 1024;
                transfer->device_handle = class_driver_obj.dev_hdl;
                transfer->bEndpointAddress = 0x01;
                transfer->callback = transfer_cb;
                transfer->context = (void *)&class_driver_obj;
                usb_host_transfer_submit(transfer);
            }
            if (class_driver_obj.actions & CLASS_DRIVER_ACTION_CLOSE_DEV) {
                //释放接口，关闭设备
                usb_host_interface_release(class_driver_obj.client_hdl, class_driver_obj.dev_hdl, 1);
                usb_host_device_close(class_driver_obj.client_hdl, class_driver_obj.dev_hdl);
                exit = true;
            }
            ... //处理其他 Class 驱动程序要求的行为
        }

        //清理 Class 驱动程序
        usb_host_transfer_free(transfer);
        usb_host_client_deregister(class_driver_obj.client_hdl);
        ... //删除客户端任务。如有需要，向守护进程任务发送信号。
    }

备注

在实际应用中，主机 Class 驱动程序还能支持更多功能，因此也存在更复杂的状态机。主机 Class 驱动程序可能需要：

- 能够开启多个设备

- 解析已开启设备的描述符，确定设备是否是目标 Class

- 按特定顺序，与接口的多个端点通信

- 声明设备的多个接口

- 处理各种错误情况

#### 生命周期

客户端任务与 Class 驱动程序的典型生命周期包括以下关键阶段：

1. 等待与主机库有关的信号完成安装。

2. 通过 `usb_host_client_register()` 注册客户端，并分配其他的 Class 驱动程序资源，如使用 `usb_host_transfer_alloc()` 分配传输。

3. 对于 Class 驱动程序需要与之通信的各个新设备：

   > 1. 调用 `usb_host_device_addr_list_fill()`，检查设备是否已连接。

   > 2. 如果设备尚未连接，则等待客户端事件回调函数的 `USB_HOST_CLIENT_EVENT_NEW_DEV` 事件。

   > 3. 调用 `usb_host_device_open()` 开启设备。

   > 4. 分别调用 `usb_host_get_device_descriptor()` 和 `usb_host_get_active_config_descriptor()`，解析设备和配置描述符。

   > 5. 调用 `usb_host_interface_claim()`，声明设备的必要接口。

4. 调用 `usb_host_transfer_submit()` 或 `usb_host_transfer_submit_control()`，向设备提交传输。

5. 一旦 `USB_HOST_CLIENT_EVENT_DEV_GONE` 事件表示，Class 驱动程序不再需要已打开的设备，或者设备断开连接：

   > 1. 在这些端点上调用 `usb_host_endpoint_halt()` 和 `usb_host_endpoint_flush()`，停止先前提交的传输。

   > 2. 调用 `usb_host_interface_release()`，释放先前声明的所有接口。

   > 3. 调用 `usb_host_device_close()`，关闭设备。

6. 调用 `usb_host_client_deregister()` 注销客户端，并释放其他 Class 驱动程序资源。

7. 删除客户端任务。如有需要，向守护进程任务发送信号。

## 示例

### 主机库示例

peripherals/usb/host/usb_host_lib 演示了如何使用 USB 主机库 API 来安装和注册客户端、等待设备连接、打印设备信息和处理断开连接，并重复这些步骤，直到退出应用程序。

### Class 驱动程序示例

USB 主机栈提供了大量示例，展示了如何通过使用主机库 API 创建主机 Class 驱动程序。

#### CDC-ACM

- 通信设备 Class（抽象控制模型）的主机 Class 驱动程序通过 乐鑫组件注册表 作为受管理的组件分发。

- 示例 peripherals/usb/host/cdc/cdc_acm_host 演示了使用 CDC-ACM 主机驱动程序组件，实现 ESP32-S3 与 USB CDC-ACM 设备的通信。

- 示例 peripherals/usb/host/cdc/cdc_acm_vcp 演示了如何扩展 CDC-ACM 的主机驱动程序，以支持 VCP 设备（即虚拟通信端口设备，如 CP210x、FTDI FT23x 或 CH34x），以及如何使用 CDC-ACM API 控制设备并发送数据。

- 示例 esp_modem 中也使用了 CDC-ACM 驱动程序，该程序在这些示例中与蜂窝模块通信。

#### MSC

- 大容量存储 Class（仅支持批量传输）的主机 Class 驱动程序已部署到 乐鑫组件注册表。

- 示例 peripherals/usb/host/msc 演示了如何使用 USB 大容量存储类来访问、读取、写入和操作 USB 闪存驱动器，包括处理 USB 重新连接和反初始化 USB 主机堆栈。

#### HID

- HID（人机接口设备）的主机 class 驱动作为托管组件通过 乐鑫组件注册表 分发。

- 示例 peripherals/usb/host/hid 演示了如何在 ESP32-S3 上实现基本的 USB 主机 HID 类驱动，以便与 USB HID 设备（如键盘和鼠标）进行通信，并持续扫描设备的连接状态。一旦连接成功，即获取 HID 报告。

#### UVC

- USB 视频设备 Class 的主机 Class 驱动程序作为托管组件通过 乐鑫组件注册表 分发。

- 示例 peripherals/usb/host/uvc 演示了如何使用 UVC 驱动程序从 USB 摄像头捕获视频帧。

## 主机栈配置

### 非兼容设备支持

为了支持某些非兼容或具有特定行为的 USB 设备，可以对 USB 主机栈进行配置。

USB 设备可能是热插拔的，因此必须配置电源开关和设备连接之间的延迟，以及设备内部电源稳定后的延迟。

#### 枚举配置

在枚举已连接 USB 设备的过程中，需要给一些事件配置合适的间隔时间以确保设备正常运行。

USB 根集线器上电和连接事件时序

上图展示了与连接设备时开启端口电源和热插拔设备相关的所有间隔时间。

- 端口复位或恢复运行后，USB 系统软件应提供 10 毫秒的恢复时间，此后连接到端口的设备才会响应数据传输。

- 恢复时间结束后，如果设备收到 `SetAddress()` 请求，设备必须能够完成对该请求的处理，并能在 50 毫秒内成功完成请求的状态 (Status) 阶段。

- 状态阶段结束后，设备允许有 2 毫秒的 `SetAddress()` 恢复时间。

备注

有关连接事件时序的更多信息，请参阅 通用串行总线 2.0 规范 > 第 7.1.7.3 章 连接和断开信令。

可通过 Menuconfig 选项设置 USB 主机栈的可配置参数。

- CONFIG_USB_HOST_DEBOUNCE_DELAY_MS 用于配置防抖延迟。

- CONFIG_USB_HOST_RESET_HOLD_MS 用于配置重置保持时间。

- CONFIG_USB_HOST_RESET_RECOVERY_MS 用于配置重置恢复时间。

- CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS 用于配置 `SetAddress()` 恢复时间。

### 下游端口配置

当支持外部 Hub 功能时，可以为外部 Hub 端口配置多个参数。

每个外部 Hub 都有一个 Hub 描述符，用于描述设备特性。

备注

有关 Hub 描述符的详细信息，请参考 USB 2.0 规范 > 章节 11.23.2.1 Hub Descriptor。

可以通过 Menuconfig 配置下游端口的可配置参数。

- 对于在端口上电后稳定电源的自定义值（PwrOn2PwrGood 值），请参阅 CONFIG_USB_HOST_EXT_PORT_CUSTOM_POWER_ON_DELAY_MS。

- 对于复位恢复间隔，请参阅 CONFIG_USB_HOST_EXT_PORT_RESET_RECOVERY_DELAY_MS。

备注

规范规定，对于没有电源开关的 Hub，PwrOn2PwrGood 必须设置为零。同时，对于某些设备，可以增加此值以提供额外的上电时间。如需启用此功能，请参考 CONFIG_USB_HOST_EXT_PORT_CUSTOM_POWER_ON_DELAY_ENABLE。

#### 主机通道

当启用外部 Hub 支持功能（CONFIG_USB_HOST_HUBS_SUPPORTED）时，主机通道的数量非常重要，因为每个下游设备都需要空闲通道。

每个连接的设备需要不同数量的通道，而所需通道数则取决于设备类别（EP 数量）。

对于 ESP32-S3，支持的通道数量为 8。

备注

- 需要一个空闲通道来枚举设备。

- 需要 1 到 N（N 为 EP 数量）个空闲通道来占用接口。

- 如果所有的主机通道都已经被占用，则设备无法进行枚举，也无法获取接口。

### 多项配置支持

对于具有多项配置的 USB 设备，可以在设备枚举过程中指定所需的配置编号。

#### 枚举过滤器

枚举过滤器是类型为 `usb_host_enum_filter_cb_t` 的回调函数。从新连接的 USB 设备上读取设备描述符后，USB 主机栈会在枚举过程开始时调用枚举过滤器，从而为用户提供读取的设备描述符。借助此回调，用户得以：

- 选择 USB 设备的配置。

- 过滤应该进行枚举的 USB 设备。

在 menuconfig 中启用 CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK 选项即可启用枚举过滤器。可以通过设置 `usb_host_config_t::enum_filter_cb` 来指定回调函数，该函数会在调用 `usb_host_install()` 时传递至主机库。

## API 参考

USB 主机库的 API 包含以下头文件，但应用程序调用该 API 时只需 `#include "usb/usb_host.h"`，该头文件包含了所有 USB 主机库的头文件。

- usb/include/usb/usb_host.h 包含 USB 主机库的函数和类型。

- usb/include/usb/usb_helpers.h 包含与 USB 协议相关的各种辅助函数，如描述符解析等。

- usb/include/usb/usb_types_stack.h 包含在 USB 主机栈的多个层次中使用的类型。

- usb/include/usb/usb_types_ch9.h 包含了与 USB 2.0 规范中第 9 章相关的类型和宏，即描述符和标准请求。

### Header File

- components/usb/include/usb/usb_host.h

- This header file can be included with:

  >     #include "usb/usb_host.h"

- This header file is a part of the API provided by the `usb` component. To declare that your component depends on `usb`, add the following to your CMakeLists.txt:

  >     REQUIRES usb

  > or

  >     PRIV_REQUIRES usb

### Functions

esp_err_t usb_host_install(const usb_host_config_t *config)

  Install the USB Host Library.

  - This function should be called only once to install the USB Host Library

  - This function should be called before any other USB Host Library functions are called

  备注

  If skip_phy_setup is set in the install configuration, the user is responsible for ensuring that the underlying Host Controller is enabled and the USB PHY (internal or external) is already setup before this function is called.

  参数:

    config -- [in] USB Host Library configuration

  返回:

    - ESP_OK: USB Host installed successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_INVALID_STATE: USB Host Library is not in correct state to be installed (eg. the library itself of one of it's drivers is already installed)

    - ESP_ERR_NO_MEM: Insufficient memory

esp_err_t usb_host_uninstall(void)

  Uninstall the USB Host Library.

  - This function should be called to uninstall the USB Host Library, thereby freeing its resources

  - All clients must have been deregistered before calling this function

  - All devices must have been freed by calling usb_host_device_free_all() and receiving the USB_HOST_LIB_EVENT_FLAGS_ALL_FREE event flag

  备注

  If skip_phy_setup was set when the Host Library was installed, the user is responsible for disabling the underlying Host Controller and USB PHY (internal or external).

  返回:

    - ESP_OK: USB Host uninstalled successfully

    - ESP_ERR_INVALID_STATE: USB Host Library is not installed, or has unfinished actions

esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_flags_ret)

  Handle USB Host Library events.

  - This function handles all of the USB Host Library's processing and should be called repeatedly in a loop

  - Check event_flags_ret to see if an flags are set indicating particular USB Host Library events

  - This function should never be called by multiple threads simultaneously

  备注

  This function can block

  参数:

    - timeout_ticks -- [in] Timeout in ticks to wait for an event to occur

    - event_flags_ret -- [out] Event flags that indicate what USB Host Library event occurred.

  返回:

    - ESP_OK: No events to be handled

    - ESP_ERR_INVALID_STATE: USB Host Library is not installed

    - ESP_ERR_TIMEOUT: Semaphore waiting for events has timed out

esp_err_t usb_host_lib_unblock(void)

  Unblock the USB Host Library handler.

  - This function simply unblocks the USB Host Library event handling function (usb_host_lib_handle_events())

  返回:

    - ESP_OK: USB Host library unblocked successfully

    - ESP_ERR_INVALID_STATE: USB Host Library is not installed

esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret)

  Get current information about the USB Host Library.

  参数:

    info_ret -- [out] USB Host Library Information

  返回:

    - ESP_OK: USB Host Library info obtained successfully

    - ESP_ERR_INVALID_STATE: USB Host Library is not installed

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_lib_set_root_port_power(bool enable)

  Power the root port ON or OFF.

  - Powering ON the root port will allow device connections to occur

  - Powering OFF the root port will disconnect all devices downstream off the root port and prevent any further device connections.

  备注

  If 'usb_host_config_t.root_port_unpowered' was set on USB Host Library installation, users must call this function to power ON the root port before any device connections can occur.

  参数:

    enable -- [in] True to power the root port ON, false to power OFF

  返回:

    - ESP_OK: Root port power enabled/disabled

    - ESP_ERR_INVALID_STATE: Root port already powered or HUB driver not installed

esp_err_t usb_host_client_register(const usb_host_client_config_t *client_config, usb_host_client_handle_t *client_hdl_ret)

  Register a client of the USB Host Library.

  - This function registers a client of the USB Host Library

  - Once a client is registered, its processing function usb_host_client_handle_events() should be called repeatedly

  参数:

    - client_config -- [in] Client configuration

    - client_hdl_ret -- [out] Client handle

  返回:

    - ESP_OK: USB Host Library client registered successfully

    - ESP_ERR_INVALID_STATE: USB Host Library is not installed

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NO_MEM: Insufficient memory

esp_err_t usb_host_client_deregister(usb_host_client_handle_t client_hdl)

  Deregister a USB Host Library client.

  - This function deregisters a client of the USB Host Library

  - The client must have closed all previously opened devices before attempting to deregister

  参数:

    client_hdl -- [in] Client handle

  返回:

    - ESP_OK: USB Host Library client deregistered successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_client_handle_events(usb_host_client_handle_t client_hdl, TickType_t timeout_ticks)

  USB Host Library client processing function.

  - This function handles all of a client's processing and should be called repeatedly in a loop

  - For a particular client, this function should never be called by multiple threads simultaneously

  备注

  This function can block

  参数:

    - client_hdl -- [in] Client handle

    - timeout_ticks -- [in] Timeout in ticks to wait for an event to occur

  返回:

    - ESP_OK: No event to be handled

    - ESP_ERR_INVALID_STATE: USB Host Library is not installed

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_TIMEOUT: Semaphore waiting for events has timed out

esp_err_t usb_host_client_unblock(usb_host_client_handle_t client_hdl)

  Unblock a client.

  - This function simply unblocks a client if it is blocked on the usb_host_client_handle_events() function.

  - This function is useful when need to unblock a client in order to deregister it.

  参数:

    client_hdl -- [in] Client handle

  返回:

    - ESP_OK: Client unblocked successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_device_open(usb_host_client_handle_t client_hdl, uint8_t dev_addr, usb_device_handle_t *dev_hdl_ret)

  Open a device.

  - This function allows a client to open a device

  - A client must open a device first before attempting to use it (e.g., sending transfers, device requests etc.)

  参数:

    - client_hdl -- [in] Client handle

    - dev_addr -- [in] Device's address

    - dev_hdl_ret -- [out] Device's handle

  返回:

    - ESP_OK: Device opened successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_device_close(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl)

  Close a device.

  - This function allows a client to close a device

  - A client must close a device after it has finished using the device (claimed interfaces must also be released)

  - A client must close all devices it has opened before de-registering

  备注

  This function can block

  参数:

    - client_hdl -- [in] Client handle

    - dev_hdl -- [in] Device handle

  返回:

    - ESP_OK: Device closed successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_FOUND: The client never opened the device (the device address not found among opened devices)

    - ESP_ERR_INVALID_STATE: The client has not released all interfaces from the device

esp_err_t usb_host_device_free_all(void)

  Indicate that all devices can be freed when possible.

  - This function marks all devices as waiting to be freed

  - If a device is not opened by any clients, it will be freed immediately

  - If a device is opened by at least one client, the device will be free when the last client closes that device.

  - Wait for the USB_HOST_LIB_EVENT_FLAGS_ALL_FREE flag to be set by usb_host_lib_handle_events() in order to know when all devices have been freed

  - This function is useful when cleaning up devices before uninstalling the USB Host Library

  返回:

    - ESP_OK: All devices already freed (i.e., there were no devices)

    - ESP_ERR_INVALID_STATE: Client must be deregistered

    - ESP_ERR_NOT_FINISHED: There are one or more devices that still need to be freed, wait for USB_HOST_LIB_EVENT_FLAGS_ALL_FREE event

esp_err_t usb_host_device_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret)

  Fill a list of device address.

  - This function fills an empty list with the address of connected devices

  - The Device addresses can then used in usb_host_device_open()

  - If there are more devices than the list_len, this function will only fill up to list_len number of devices.

  参数:

    - list_len -- [in] Length of the empty list

    - dev_addr_list -- [inout] Empty list to be filled

    - num_dev_ret -- [out] Number of devices

  返回:

    - ESP_OK: Device list filled successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_device_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_info)

  Get device's information.

  - This function gets some basic information of a device

  - The device must be opened first before attempting to get its information

  备注

  This function can block

  参数:

    - dev_hdl -- [in] Device handle

    - dev_info -- [out] Device information

  返回:

    - ESP_OK: Device information obtained successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_get_device_descriptor(usb_device_handle_t dev_hdl, const usb_device_desc_t **device_desc)

  Get device's device descriptor.

  - A client must call usb_host_device_open() first

  - No control transfer is sent. The device's descriptor is cached on enumeration

  - This function simple returns a pointer to the cached descriptor

  备注

  No control transfer is sent. The device's descriptor is cached on enumeration

  参数:

    - dev_hdl -- [in] Device handle

    - device_desc -- [out] Device descriptor

  返回:

    - ESP_OK: Device descriptor obtained successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_get_active_config_descriptor(usb_device_handle_t dev_hdl, const usb_config_desc_t **config_desc)

  Get device's active configuration descriptor.

  - A client must call usb_host_device_open() first

  - No control transfer is sent. The device's active configuration descriptor is cached on enumeration

  - This function simple returns a pointer to the cached descriptor

  备注

  This function can block

  备注

  No control transfer is sent. A device's active configuration descriptor is cached on enumeration

  参数:

    - dev_hdl -- [in] Device handle

    - config_desc -- [out] Configuration descriptor

  返回:

    - ESP_OK: Active configuration descriptor obtained successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_get_config_desc(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bConfigurationValue, const usb_config_desc_t **config_desc_ret)

  Get get device's configuration descriptor.

  - The USB Host library only caches a device's active configuration descriptor.

  - This function reads any configuration descriptor of a particular device (specified by bConfigurationValue).

  - This function will read the specified configuration descriptor via control transfers, and allocate memory to store that descriptor.

  - Users can call usb_host_free_config_desc() to free the descriptor's memory afterwards.

  备注

  This function can block

  备注

  A client must call usb_host_device_open() on the device first

  备注

  bConfigurationValue starts from index 1

  参数:

    - client_hdl -- [in] Client handle - usb_host_client_handle_events() should be called repeatedly in a separate task to handle client events

    - dev_hdl -- [in] Device handle

    - bConfigurationValue -- [in] Index of device's configuration descriptor to be read

    - config_desc_ret -- [out] Returned configuration descriptor

  返回:

    - ESP_OK: Configuration descriptor obtained successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_SUPPORTED: Invalid bConfigurationValue value (the device does not have this configuration value)

    - ESP_ERR_NO_MEM: Insufficient memory

esp_err_t usb_host_free_config_desc(const usb_config_desc_t *config_desc)

  Free a configuration descriptor.

  This function frees a configuration descriptor that was returned by usb_host_get_config_desc()

  参数:

    config_desc -- [out] Configuration descriptor

  返回:

    - ESP_OK: Configuration descriptor freed successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

esp_err_t usb_host_interface_claim(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bInterfaceNumber, uint8_t bAlternateSetting)

  Function for a client to claim a device's interface.

  - A client must claim a device's interface before attempting to communicate with any of its endpoints

  - Once an interface is claimed by a client, it cannot be claimed by any other client.

  备注

  This function can block

  参数:

    - client_hdl -- [in] Client handle

    - dev_hdl -- [in] Device handle

    - bInterfaceNumber -- [in] Interface number

    - bAlternateSetting -- [in] Interface alternate setting number

  返回:

    - ESP_OK: Interface claimed successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_INVALID_STATE: USB Host is not a correct state to claim an interface

    - ESP_ERR_NOT_FOUND: Interface or EP not found

    - ESP_ERR_NO_MEM: Insufficient memory

esp_err_t usb_host_interface_release(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bInterfaceNumber)

  Function for a client to release a previously claimed interface.

  - A client should release a device's interface after it no longer needs to communicate with the interface

  - A client must release all of its interfaces of a device it has claimed before being able to close the device

  备注

  This function can block

  参数:

    - client_hdl -- [in] Client handle

    - dev_hdl -- [in] Device handle

    - bInterfaceNumber -- [in] Interface number

  返回:

    - ESP_OK: Interface released successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_INVALID_STATE: Client never opened the USB Device, or interface currently can not be freed

    - ESP_ERR_NOT_FOUND: Interface number not found in the list of interfaces

esp_err_t usb_host_endpoint_halt(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress)

  Halt a particular endpoint.

  - The device must have been opened by a client

  - The endpoint must be part of an interface claimed by a client

  - Once halted, the endpoint must be cleared using usb_host_endpoint_clear() before it can communicate again

  备注

  This function can block

  参数:

    - dev_hdl -- [in] Device handle

    - bEndpointAddress -- [in] Endpoint address

  返回:

    - ESP_OK: Endpoint halted successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_FOUND: Endpoint address not found

    - ESP_ERR_INVALID_STATE: Endpoint pipe is not in the correct state/condition to execute a command

esp_err_t usb_host_endpoint_flush(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress)

  Flush a particular endpoint.

  - The device must have been opened by a client

  - The endpoint must be part of an interface claimed by a client

  - The endpoint must have been halted (either through a transfer error, or usb_host_endpoint_halt())

  - Flushing an endpoint will caused an queued up transfers to be canceled

  备注

  This function can block

  参数:

    - dev_hdl -- [in] Device handle

    - bEndpointAddress -- [in] Endpoint address

  返回:

    - ESP_OK: Endpoint flushed successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_FOUND: Endpoint address not found

    - ESP_ERR_INVALID_STATE: Endpoint pipe is not in the correct state/condition to execute a command

esp_err_t usb_host_endpoint_clear(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress)

  Clear a halt on a particular endpoint.

  - The device must have been opened by a client

  - The endpoint must be part of an interface claimed by a client

  - The endpoint must have been halted (either through a transfer error, or usb_host_endpoint_halt())

  - If the endpoint has any queued up transfers, clearing a halt will resume their execution

  备注

  This function can block

  参数:

    - dev_hdl -- [in] Device handle

    - bEndpointAddress -- [in] Endpoint address

  返回:

    - ESP_OK: Endpoint cleared successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_FOUND: Endpoint address not found

    - ESP_ERR_INVALID_STATE: Endpoint pipe is not in the correct state/condition to execute a command

esp_err_t usb_host_transfer_alloc(size_t data_buffer_size, int num_isoc_packets, usb_transfer_t **transfer)

  Allocate a transfer object.

  - This function allocates a transfer object

  - Each transfer object has a fixed sized buffer specified on allocation

  - The resulting data_buffer_size can be bigger that the requested size. This is to ensure that the data buffer is cache aligned

  - A transfer object can be re-used indefinitely

  - A transfer can be submitted using usb_host_transfer_submit() or usb_host_transfer_submit_control()

  参数:

    - data_buffer_size -- [in] Size of the transfer's data buffer

    - num_isoc_packets -- [in] Number of isochronous packets in transfer (set to 0 for non-isochronous transfers)

    - transfer -- [out] Transfer object

  返回:

    - ESP_OK: Transfer object allocated successfully

    - ESP_ERR_NO_MEM: Insufficient memory

esp_err_t usb_host_transfer_free(usb_transfer_t *transfer)

  Free a transfer object.

  - Free a transfer object previously allocated using usb_host_transfer_alloc()

  - The transfer must not be in-flight when attempting to free it

  - If a NULL pointer is passed, this function will simply return ESP_OK

  参数:

    transfer -- [in] Transfer object

  返回:

    - ESP_OK: Transfer object freed successfully

esp_err_t usb_host_transfer_submit(usb_transfer_t *transfer)

  Submit a non-control transfer.

  - Submit a transfer to a particular endpoint. The device and endpoint number is specified inside the transfer

  - The transfer must be properly initialized before submitting

  - On completion, the transfer's callback will be called from the client's usb_host_client_handle_events() function.

  参数:

    transfer -- [in] Initialized transfer object

  返回:

    - ESP_OK: Transfer submitted successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_FINISHED: Transfer already in-flight

    - ESP_ERR_NOT_FOUND: Endpoint address not found

    - ESP_ERR_INVALID_STATE: Endpoint pipe is not in a correct state to submit transfer

esp_err_t usb_host_transfer_submit_control(usb_host_client_handle_t client_hdl, usb_transfer_t *transfer)

  Submit a control transfer.

  - Submit a control transfer to a particular device. The client must have opened the device first

  - The transfer must be properly initialized before submitting. The first 8 bytes of the transfer's data buffer should contain the control transfer setup packet

  - On completion, the transfer's callback will be called from the client's usb_host_client_handle_events() function.

  参数:

    - client_hdl -- [in] Client handle

    - transfer -- [in] Initialized transfer object

  返回:

    - ESP_OK: Control transfer submitted successfully

    - ESP_ERR_INVALID_ARG: Invalid argument

    - ESP_ERR_NOT_FINISHED: Transfer already in-flight

    - ESP_ERR_NOT_FOUND: Endpoint address not found

    - ESP_ERR_INVALID_STATE: Endpoint pipe is not in a correct state to submit transfer

### Structures

struct usb_host_client_event_msg_t

  Client event message.

  Client event messages are sent to each client of the USB Host Library in order to notify them of various USB Host Library events such as:

  - Addition of new devices

  - Removal of existing devices

  备注

  The event message structure has a union with members corresponding to each particular event. Based on the event type, only the relevant member field should be accessed.

  Public Members

  usb_host_client_event_t event

    Type of event

  uint8_t address

    New device's address

  struct usb_host_client_event_msg_t new_dev

    New device info

  usb_device_handle_t dev_hdl

    The handle of the device that was gone

  struct usb_host_client_event_msg_t dev_gone

    Gone device info

struct usb_host_lib_info_t

  Current information about the USB Host Library obtained via usb_host_lib_info()

  Public Members

  int num_devices

    Current number of connected (and enumerated) devices

  int num_clients

    Current number of registered clients

struct usb_host_config_t

  USB Host Library configuration.

  Configuration structure of the USB Host Library. Provided in the usb_host_install() function

  Public Members

  bool skip_phy_setup

    If set, the USB Host Library will not configure the USB PHY thus allowing the user to manually configure the USB PHY before calling usb_host_install(). Users should set this if they want to use an external USB PHY. Otherwise, the USB Host Library will automatically configure the internal USB PHY

  bool root_port_unpowered

    If set, the USB Host Library will not power on the root port on installation. This allows users to power on the root port manually by calling usb_host_lib_set_root_port_power().

  int intr_flags

    Interrupt flags for the underlying ISR used by the USB Host stack

  usb_host_enum_filter_cb_t enum_filter_cb

    Enumeration filter callback. Enable CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK to use this feature. Set to NULL otherwise.

  uint32_t nptx_fifo_lines

    Required: Number of non-periodic TX FIFO lines. Must be > 0 to enable custom configuration.

  uint32_t ptx_fifo_lines

    Optional: Number of periodic TX FIFO lines. Can be 0 if periodic TX endpoints are not used.

  uint32_t rx_fifo_lines

    Required: Number of RX FIFO lines. Must be > 0 to enable custom configuration.

  struct usb_host_config_t fifo_settings_custom

    Optional custom FIFO configuration (advanced use). RX and NPTX must be > 0. If all fields are zero, a default configuration will be selected based on Kconfig bias.

  unsigned peripheral_map

    Selects the USB peripheral(s) to use.

    - On targets with multiple USB peripherals, this field can be used to specify which ones to enable.

    - Set to 0 to use the default peripheral.

    - On High-Speed capable targets, the default is the High-Speed peripheral.

    - On Full-Speed only targets, the default is the Full-Speed peripheral.

    - Example: peripheral_map = BIT1; installs USB host on peripheral 1.

    - The mapping of bits to specific peripherals is defined in the USB_DWC_LL_GET_HW() macro.

struct usb_host_client_config_t

  USB Host Library Client configuration.

  Configuration structure for a USB Host Library client. Provided in usb_host_client_register()

  Public Members

  bool is_synchronous

    Whether the client is asynchronous or synchronous or not. Set to false for now.

  int max_num_event_msg

    Maximum number of event messages that can be stored (e.g., 3)

  usb_host_client_event_cb_t client_event_callback

    Client's event callback function

  void *callback_arg

    Event callback function argument

  struct usb_host_client_config_t async

    Async callback config

### Macros

USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS

  All clients have been deregistered from the USB Host Library

USB_HOST_LIB_EVENT_FLAGS_ALL_FREE

  The USB Host Library has freed all devices

### Type Definitions

typedef struct usb_host_client_handle_s *usb_host_client_handle_t

  Handle to a USB Host Library asynchronous client.

  An asynchronous client can be registered using usb_host_client_register()

  备注

  Asynchronous API

typedef void (*usb_host_client_event_cb_t)(const usb_host_client_event_msg_t *event_msg, void *arg)

  Client event callback.

  - Each client of the USB Host Library must register an event callback to receive event messages from the USB Host Library.

  - The client event callback is run from the context of the clients usb_host_client_handle_events() function

### Enumerations

enum usb_host_client_event_t

  The type event in a client event message.

  Values:

  enumerator USB_HOST_CLIENT_EVENT_NEW_DEV

    A new device has been enumerated and added to the USB Host Library

  enumerator USB_HOST_CLIENT_EVENT_DEV_GONE

    A device opened by the client is now gone

### Header File

- components/usb/include/usb/usb_helpers.h

- This header file can be included with:

  >     #include "usb/usb_helpers.h"

- This header file is a part of the API provided by the `usb` component. To declare that your component depends on `usb`, add the following to your CMakeLists.txt:

  >     REQUIRES usb

  > or

  >     PRIV_REQUIRES usb

### Functions

const usb_standard_desc_t *usb_parse_next_descriptor(const usb_standard_desc_t *cur_desc, uint16_t wTotalLength, int *offset)

  Get the next descriptor.

  Given a particular descriptor within a full configuration descriptor, get the next descriptor within the configuration descriptor. This is a convenience function that can be used to walk each individual descriptor within a full configuration descriptor.

  参数:

    - cur_desc -- [in] Current descriptor

    - wTotalLength -- [in] Total length of the configuration descriptor

    - offset -- [inout] Byte offset relative to the start of the configuration descriptor. On input, it is the offset of the current descriptor. On output, it is the offset of the returned descriptor.

  返回:

    usb_standard_desc_t* Next descriptor, NULL if end of configuration descriptor reached

const usb_standard_desc_t *usb_parse_next_descriptor_of_type(const usb_standard_desc_t *cur_desc, uint16_t wTotalLength, uint8_t bDescriptorType, int *offset)

  Get the next descriptor of a particular type.

  Given a particular descriptor within a full configuration descriptor, get the next descriptor of a particular type (i.e., using the bDescriptorType value) within the configuration descriptor.

  参数:

    - cur_desc -- [in] Current descriptor

    - wTotalLength -- [in] Total length of the configuration descriptor

    - bDescriptorType -- [in] Type of the next descriptor to get

    - offset -- [inout] Byte offset relative to the start of the configuration descriptor. On input, it is the offset of the current descriptor. On output, it is the offset of the returned descriptor.

  返回:

    usb_standard_desc_t* Next descriptor, NULL if end descriptor is not found or configuration descriptor reached

int usb_parse_interface_number_of_alternate(const usb_config_desc_t *config_desc, uint8_t bInterfaceNumber)

  Get the number of alternate settings for a bInterfaceNumber.

  Given a particular configuration descriptor, for a particular bInterfaceNumber, get the number of alternate settings available for that interface (i.e., the max possible value of bAlternateSetting for that bInterfaceNumber).

  参数:

    - config_desc -- [in] Pointer to the start of a full configuration descriptor

    - bInterfaceNumber -- [in] Interface number

  返回:

    int The number of alternate settings that the interface has, -1 if bInterfaceNumber not found

const usb_intf_desc_t *usb_parse_interface_descriptor(const usb_config_desc_t *config_desc, uint8_t bInterfaceNumber, uint8_t bAlternateSetting, int *offset)

  Get a particular interface descriptor (using bInterfaceNumber and bAlternateSetting)

  Given a full configuration descriptor, get a particular interface descriptor.

  备注

  To get the number of alternate settings for a particular bInterfaceNumber, call usb_parse_interface_number_of_alternate()

  参数:

    - config_desc -- [in] Pointer to the start of a full configuration descriptor

    - bInterfaceNumber -- [in] Interface number

    - bAlternateSetting -- [in] Alternate setting number

    - offset -- [out] Byte offset of the interface descriptor relative to the start of the configuration descriptor. Can be NULL.

  返回:

    const usb_intf_desc_t* Pointer to interface descriptor, NULL if not found.

const usb_ep_desc_t *usb_parse_endpoint_descriptor_by_index(const usb_intf_desc_t *intf_desc, int index, uint16_t wTotalLength, int *offset)

  Get an endpoint descriptor within an interface descriptor.

  Given an interface descriptor, get the Nth endpoint descriptor of the interface. The number of endpoints in an interface is indicated by the bNumEndpoints field of the interface descriptor.

  备注

  If bNumEndpoints is 0, it means the interface uses the default endpoint only

  参数:

    - intf_desc -- [in] Pointer to thee start of an interface descriptor

    - index -- [in] Endpoint index

    - wTotalLength -- [in] Total length of the containing configuration descriptor

    - offset -- [inout] Byte offset relative to the start of the configuration descriptor. On input, it is the offset of the interface descriptor. On output, it is the offset of the endpoint descriptor.

  返回:

    const usb_ep_desc_t* Pointer to endpoint descriptor, NULL if not found.

const usb_ep_desc_t *usb_parse_endpoint_descriptor_by_address(const usb_config_desc_t *config_desc, uint8_t bInterfaceNumber, uint8_t bAlternateSetting, uint8_t bEndpointAddress, int *offset)

  Get an endpoint descriptor based on an endpoint's address.

  Given a configuration descriptor, get an endpoint descriptor based on it's bEndpointAddress, bAlternateSetting, and bInterfaceNumber.

  参数:

    - config_desc -- [in] Pointer to the start of a full configuration descriptor

    - bInterfaceNumber -- [in] Interface number

    - bAlternateSetting -- [in] Alternate setting number

    - bEndpointAddress -- [in] Endpoint address

    - offset -- [out] Byte offset of the endpoint descriptor relative to the start of the configuration descriptor. Can be NULL

  返回:

    const usb_ep_desc_t* Pointer to endpoint descriptor, NULL if not found.

void usb_print_device_descriptor(const usb_device_desc_t *devc_desc)

  Print device descriptor.

  参数:

    devc_desc -- [in] Device descriptor

void usb_print_config_descriptor(const usb_config_desc_t *cfg_desc, print_class_descriptor_cb class_specific_cb)

  Print configuration descriptor.

  - This function prints the full contents of a configuration descriptor (including interface and endpoint descriptors)

  - When a non-standard descriptor is encountered, this function will call the class_specific_cb if it is provided

  参数:

    - cfg_desc -- [in] Configuration descriptor

    - class_specific_cb -- [in] Class specific descriptor callback. Can be NULL

void usb_print_string_descriptor(const usb_str_desc_t *str_desc)

  Print a string descriptor.

  This function will only print ASCII characters of the UTF-16 encoded string

  参数:

    str_desc -- [in] String descriptor

static inline int usb_round_up_to_mps(int num_bytes, int mps)

  Round up to an integer multiple of endpoint's MPS.

  This is a convenience function to round up a size/length to an endpoint's MPS (Maximum packet size). This is useful when calculating transfer or buffer lengths of IN endpoints.

  - If MPS <= 0, this function will return 0

  - If num_bytes <= 0, this function will return 0

  参数:

    - num_bytes -- [in] Number of bytes

    - mps -- [in] MPS

  返回:

    int Round up integer multiple of MPS

### Type Definitions

typedef void (*print_class_descriptor_cb)(const usb_standard_desc_t*)

  Print class specific descriptor callback.

  Optional callback to be provided to usb_print_config_descriptor() function. The callback is called when when a non-standard descriptor is encountered. The callback should decode the descriptor as print it.

### Header File

- components/usb/include/usb/usb_types_stack.h

- This header file can be included with:

  >     #include "usb/usb_types_stack.h"

- This header file is a part of the API provided by the `usb` component. To declare that your component depends on `usb`, add the following to your CMakeLists.txt:

  >     REQUIRES usb

  > or

  >     PRIV_REQUIRES usb

### Structures

struct usb_parent_dev_info_t

  Parent device information.

  Public Members

  usb_device_handle_t dev_hdl

    Device's parent handle

  uint8_t port_num

    Device's parent port number

struct usb_device_info_t

  Basic information of an enumerated device.

  Public Members

  usb_parent_dev_info_t parent

    Device's parent information

  usb_speed_t speed

    Device's speed

  uint8_t dev_addr

    Device's address

  uint8_t bMaxPacketSize0

    The maximum packet size of the device's default endpoint

  uint8_t bConfigurationValue

    Device's current configuration number

  const usb_str_desc_t *str_desc_manufacturer

    Pointer to Manufacturer string descriptor (can be NULL)

  const usb_str_desc_t *str_desc_product

    Pointer to Product string descriptor (can be NULL)

  const usb_str_desc_t *str_desc_serial_num

    Pointer to Serial Number string descriptor (can be NULL)

struct usb_isoc_packet_desc_t

  Isochronous packet descriptor.

  If the number of bytes in an Isochronous transfer is larger than the MPS of the endpoint, the transfer is split into multiple packets transmitted at the endpoint's specified interval. An array of Isochronous packet descriptors describes how an Isochronous transfer should be split into multiple packets.

  Public Members

  int num_bytes

    Number of bytes to transmit/receive in the packet. IN packets should be integer multiple of MPS

  int actual_num_bytes

    Actual number of bytes transmitted/received in the packet

  usb_transfer_status_t status

    Status of the packet

struct usb_transfer_s

  USB transfer structure.

  Public Members

  uint8_t *const data_buffer

    Pointer to data buffer

  const size_t data_buffer_size

    Size of the data buffer in bytes

  int num_bytes

    Number of bytes to transfer. Control transfers should include the size of the setup packet. Isochronous transfer should be the total transfer size of all packets. For non-control IN transfers, num_bytes should be an integer multiple of MPS.

  int actual_num_bytes

    Actual number of bytes transferred

  uint32_t flags

    Transfer flags

  usb_device_handle_t device_handle

    Device handle

  uint8_t bEndpointAddress

    Endpoint Address

  usb_transfer_status_t status

    Status of the transfer

  uint32_t timeout_ms

    Timeout (in milliseconds) of the packet (currently not supported yet)

  usb_transfer_cb_t callback

    Transfer callback

  void *context

    Context variable for transfer to associate transfer with something

  const int num_isoc_packets

    Only relevant to Isochronous. Number of service periods (i.e., intervals) to transfer data buffer over.

  usb_isoc_packet_desc_t isoc_packet_desc[]

    Descriptors for each Isochronous packet

### Macros

USB_TRANSFER_FLAG_ZERO_PACK

  Terminate Bulk/Interrupt OUT transfer with a zero length packet.

  OUT transfers normally terminate when the Host has transferred the exact amount of data it needs to the device. However, for bulk and interrupt OUT transfers, if the transfer size just happened to be a multiple of MPS, it will be impossible to know the boundary between two consecutive transfers to the same endpoint.

  Therefore, this flag will cause the transfer to automatically add a zero length packet (ZLP) at the end of the transfer if the following conditions are met:

  - The target endpoint is a Bulk/Interrupt OUT endpoint (Host to device)

  - The transfer's length (i.e., transfer.num_bytes) is a multiple of the endpoint's MPS

  Otherwise, this flag has no effect.

  Users should check whether their target device's class requires a ZLP, as not all Bulk/Interrupt OUT endpoints require them. For example:

  - For MSC Bulk Only Transport class, the Host MUST NEVER send a ZLP. Bulk transfer boundaries are determined by the CBW and CSW instead

  - For CDC Ethernet, the Host MUST ALWAYS send a ZLP if a segment (i.e., a transfer) is a multiple of MPS (See 3.3.1 Segment Delineation)

  备注

  See USB2.0 specification 5.7.3 and 5.8.3 for more details

  备注

  IN transfers normally terminate when the Host as receive the exact amount of data it needs (must be multiple of MPS) or the endpoint sends a short packet to the Host (For bulk OUT only). Indicates that a bulk OUT transfers should always terminate with a short packet, even if it means adding an extra zero length packet

### Type Definitions

typedef struct usb_device_handle_s *usb_device_handle_t

  Handle of a USB Device connected to a USB Host.

typedef bool (*usb_host_enum_filter_cb_t)(const usb_device_desc_t *dev_desc, uint8_t *bConfigurationValue)

  Enumeration filter callback.

  This callback is called at the beginning of the enumeration process for a newly attached device. Through this callback, users are able to:

  - filter which devices should be enumerated

  - select the configuration number to use when enumerating the device

  The device descriptor is passed to this callback to allow users to filter devices based on Vendor ID, Product ID, and class code.

  Attention

    This callback must be non-blocking

  Attention

    This callback must not submit any USB transfers

  Param dev_desc:

    [in] Device descriptor of the device to enumerate

  Param bConfigurationValue:

    [out] Configuration number to use when enumerating the device (starts with 1)

  Return:

    bool

    - true: USB device will be enumerated

    - false: USB device will not be enumerated

typedef struct usb_transfer_s usb_transfer_t

  USB transfer structure.

  This structure is used to represent a transfer from a software client to an endpoint over the USB bus. Some of the fields are made const on purpose as they are fixed on allocation. Users should call the appropriate USB Host Library function to allocate a USB transfer structure instead of allocating this structure themselves.

  The transfer type is inferred from the endpoint this transfer is sent to. Depending on the transfer type, users should note the following:

  - Bulk: This structure represents a single bulk transfer. If the number of bytes exceeds the endpoint's MPS, the transfer will be split into multiple MPS sized packets followed by a short packet.

  - Control: This structure represents a single control transfer. This first 8 bytes of the data_buffer must be filled with the setup packet (see usb_setup_packet_t). The num_bytes field should be the total size of the transfer (i.e., size of setup packet + wLength).

  - Interrupt: Represents an interrupt transfer. If num_bytes exceeds the MPS of the endpoint, the transfer will be split into multiple packets, and each packet is transferred at the endpoint's specified interval.

  - Isochronous: Represents a stream of bytes that should be transferred to an endpoint at a fixed rate. The transfer is split into packets according to the each isoc_packet_desc. A packet is transferred at each interval of the endpoint. If an entire ISOC URB was transferred without error (skipped packets do not count as errors), the URB's overall status and the status of each packet descriptor will be updated, and the actual_num_bytes reflects the total bytes transferred over all packets. If the ISOC URB encounters an error, the entire URB is considered erroneous so only the overall status will updated.

  备注

  For Bulk/Control/Interrupt IN transfers, the num_bytes must be a integer multiple of the endpoint's MPS

  备注

  This structure should be allocated via usb_host_transfer_alloc()

  备注

  Once the transfer has be submitted, users should not modify the structure until the transfer has completed

typedef void (*usb_transfer_cb_t)(usb_transfer_t *transfer)

  USB transfer completion callback.

### Enumerations

enum usb_speed_t

  USB Standard Speeds.

  Values:

  enumerator USB_SPEED_LOW

    USB Low Speed (1.5 Mbit/s)

  enumerator USB_SPEED_FULL

    USB Full Speed (12 Mbit/s)

  enumerator USB_SPEED_HIGH

    USB High Speed (480 Mbit/s)

enum usb_transfer_type_t

  The type of USB transfer.

  备注

  The enum values need to match the bmAttributes field of an EP descriptor

  Values:

  enumerator USB_TRANSFER_TYPE_CTRL
  enumerator USB_TRANSFER_TYPE_ISOCHRONOUS
  enumerator USB_TRANSFER_TYPE_BULK
  enumerator USB_TRANSFER_TYPE_INTR

enum usb_transfer_status_t

  The status of a particular transfer.

  Values:

  enumerator USB_TRANSFER_STATUS_COMPLETED

    The transfer was successful (but may be short)

  enumerator USB_TRANSFER_STATUS_ERROR

    The transfer failed because due to excessive errors (e.g. no response or CRC error)

  enumerator USB_TRANSFER_STATUS_TIMED_OUT

    The transfer failed due to a time out

  enumerator USB_TRANSFER_STATUS_CANCELED

    The transfer was canceled

  enumerator USB_TRANSFER_STATUS_STALL

    The transfer was stalled

  enumerator USB_TRANSFER_STATUS_OVERFLOW

    The transfer as more data was sent than was requested

  enumerator USB_TRANSFER_STATUS_SKIPPED

    ISOC packets only. The packet was skipped due to system latency or bus overload

  enumerator USB_TRANSFER_STATUS_NO_DEVICE

    The transfer failed because the target device is gone

### Header File

- components/usb/include/usb/usb_types_ch9.h

- This header file can be included with:

  >     #include "usb/usb_types_ch9.h"

- This header file is a part of the API provided by the `usb` component. To declare that your component depends on `usb`, add the following to your CMakeLists.txt:

  >     REQUIRES usb

  > or

  >     PRIV_REQUIRES usb

### Unions

union usb_setup_packet_t
  #include <usb_types_ch9.h>

  Structure representing a USB control transfer setup packet.

  See Table 9-2 of USB2.0 specification for more details

  Public Members

  uint8_t bmRequestType

    Characteristics of request

  uint8_t bRequest

    Specific request

  uint16_t wValue

    Word-sized field that varies according to request

  uint16_t wIndex

    Word-sized field that varies according to request; typically used to pass an index or offset

  uint16_t wLength

    Number of bytes to transfer if there is a data stage

  struct usb_setup_packet_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_SETUP_PACKET_SIZE]

    Descriptor value

union usb_device_status_t
  #include <usb_types_ch9.h>

  Structure representing a USB device status.

  See Figures 9-4 Information Returned by a GetStatus() Request to a Device of USB2.0 specification for more details

  Public Members

  uint16_t self_powered

    1 - Device is currently self-powered, 0 - bus powered

  uint16_t remote_wakeup

    1 - the ability of the device to signal remote wakeup is enabled, 0 - the ability of the device to signal remote wakeup is disabled.

  uint16_t reserved

    reserved

  struct usb_device_status_t USB_DESC_ATTR

    Packed

  uint16_t val

    Device status value

union usb_standard_desc_t
  #include <usb_types_ch9.h>

  USB standard descriptor.

  All USB standard descriptors start with these two bytes. Use this type when traversing over configuration descriptors

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    Descriptor Type

  struct usb_standard_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_STANDARD_DESC_SIZE]

    Descriptor value

union usb_device_desc_t
  #include <usb_types_ch9.h>

  Structure representing a USB device descriptor.

  See Table 9-8 of USB2.0 specification for more details

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    DEVICE Descriptor Type

  uint16_t bcdUSB

    USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H)

  uint8_t bDeviceClass

    Class code (assigned by the USB-IF)

  uint8_t bDeviceSubClass

    Subclass code (assigned by the USB-IF)

  uint8_t bDeviceProtocol

    Protocol code (assigned by the USB-IF)

  uint8_t bMaxPacketSize0

    Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid)

  uint16_t idVendor

    Vendor ID (assigned by the USB-IF)

  uint16_t idProduct

    Product ID (assigned by the manufacturer)

  uint16_t bcdDevice

    Device release number in binary-coded decimal

  uint8_t iManufacturer

    Index of string descriptor describing manufacturer

  uint8_t iProduct

    Index of string descriptor describing product

  uint8_t iSerialNumber

    Index of string descriptor describing the device’s serial number

  uint8_t bNumConfigurations

    Number of possible configurations

  struct usb_device_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_DEVICE_DESC_SIZE]

    Descriptor value

union usb_config_desc_t
  #include <usb_types_ch9.h>

  Structure representing a short USB configuration descriptor.

  See Table 9-10 of USB2.0 specification for more details

  备注

  The full USB configuration includes all the interface and endpoint descriptors of that configuration.

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    CONFIGURATION Descriptor Type

  uint16_t wTotalLength

    Total length of data returned for this configuration

  uint8_t bNumInterfaces

    Number of interfaces supported by this configuration

  uint8_t bConfigurationValue

    Value to use as an argument to the SetConfiguration() request to select this configuration

  uint8_t iConfiguration

    Index of string descriptor describing this configuration

  uint8_t bmAttributes

    Configuration characteristics

  uint8_t bMaxPower

    Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational.

  struct usb_config_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_CONFIG_DESC_SIZE]

    Descriptor value

union usb_iad_desc_t
  #include <usb_types_ch9.h>

  Structure representing a USB interface association descriptor.

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    INTERFACE ASSOCIATION Descriptor Type

  uint8_t bFirstInterface

    Interface number of the first interface that is associated with this function

  uint8_t bInterfaceCount

    Number of contiguous interfaces that are associated with this function

  uint8_t bFunctionClass

    Class code (assigned by USB-IF)

  uint8_t bFunctionSubClass

    Subclass code (assigned by USB-IF)

  uint8_t bFunctionProtocol

    Protocol code (assigned by USB-IF)

  uint8_t iFunction

    Index of string descriptor describing this function

  struct usb_iad_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_IAD_DESC_SIZE]

    Descriptor value

union usb_intf_desc_t
  #include <usb_types_ch9.h>

  Structure representing a USB interface descriptor.

  See Table 9-12 of USB2.0 specification for more details

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    INTERFACE Descriptor Type

  uint8_t bInterfaceNumber

    Number of this interface.

  uint8_t bAlternateSetting

    Value used to select this alternate setting for the interface identified in the prior field

  uint8_t bNumEndpoints

    Number of endpoints used by this interface (excluding endpoint zero).

  uint8_t bInterfaceClass

    Class code (assigned by the USB-IF)

  uint8_t bInterfaceSubClass

    Subclass code (assigned by the USB-IF)

  uint8_t bInterfaceProtocol

    Protocol code (assigned by the USB)

  uint8_t iInterface

    Index of string descriptor describing this interface

  struct usb_intf_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_INTF_DESC_SIZE]

    Descriptor value

union usb_ep_desc_t
  #include <usb_types_ch9.h>

  Structure representing a USB endpoint descriptor.

  See Table 9-13 of USB2.0 specification for more details

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    ENDPOINT Descriptor Type

  uint8_t bEndpointAddress

    The address of the endpoint on the USB device described by this descriptor

  uint8_t bmAttributes

    This field describes the endpoint’s attributes when it is configured using the bConfigurationValue.

  uint16_t wMaxPacketSize

    Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected.

  uint8_t bInterval

    Interval for polling Isochronous and Interrupt endpoints. Expressed in frames or microframes depending on the device operating speed (1 ms for Low-Speed and Full-Speed or 125 us for USB High-Speed and above).

  struct usb_ep_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_EP_DESC_SIZE]

    Descriptor value

union usb_str_desc_t
  #include <usb_types_ch9.h>

  Structure representing a USB string descriptor.

  Public Members

  uint8_t bLength

    Size of the descriptor in bytes

  uint8_t bDescriptorType

    STRING Descriptor Type

  uint16_t wData[]

    UTF-16LE encoded

  struct usb_str_desc_t USB_DESC_ATTR

    USB descriptor attributes

  uint8_t val[USB_STR_DESC_SIZE]

    Descriptor value

### Macros

USB_DESC_ATTR

USB_B_DESCRIPTOR_TYPE_DEVICE

  Descriptor types from USB2.0 specification table 9.5.

USB_B_DESCRIPTOR_TYPE_CONFIGURATION

USB_B_DESCRIPTOR_TYPE_STRING

USB_B_DESCRIPTOR_TYPE_INTERFACE

USB_B_DESCRIPTOR_TYPE_ENDPOINT

USB_B_DESCRIPTOR_TYPE_DEVICE_QUALIFIER

USB_B_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION

USB_B_DESCRIPTOR_TYPE_INTERFACE_POWER

USB_B_DESCRIPTOR_TYPE_OTG

  Descriptor types from USB 2.0 ECN.

USB_B_DESCRIPTOR_TYPE_DEBUG

USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION

USB_B_DESCRIPTOR_TYPE_SECURITY

  Descriptor types from Wireless USB spec.

USB_B_DESCRIPTOR_TYPE_KEY

USB_B_DESCRIPTOR_TYPE_ENCRYPTION_TYPE

USB_B_DESCRIPTOR_TYPE_BOS

USB_B_DESCRIPTOR_TYPE_DEVICE_CAPABILITY

USB_B_DESCRIPTOR_TYPE_WIRELESS_ENDPOINT_COMP

USB_B_DESCRIPTOR_TYPE_WIRE_ADAPTER

USB_B_DESCRIPTOR_TYPE_RPIPE

USB_B_DESCRIPTOR_TYPE_CS_RADIO_CONTROL

USB_B_DESCRIPTOR_TYPE_PIPE_USAGE

  Descriptor types from UAS specification.

USB_SETUP_PACKET_SIZE

  Size of a USB control transfer setup packet in bytes.

USB_BM_REQUEST_TYPE_DIR_OUT

  Bit masks belonging to the bmRequestType field of a setup packet.

USB_BM_REQUEST_TYPE_DIR_IN

USB_BM_REQUEST_TYPE_TYPE_STANDARD

USB_BM_REQUEST_TYPE_TYPE_CLASS

USB_BM_REQUEST_TYPE_TYPE_VENDOR

USB_BM_REQUEST_TYPE_TYPE_RESERVED

USB_BM_REQUEST_TYPE_TYPE_MASK

USB_BM_REQUEST_TYPE_RECIP_DEVICE

USB_BM_REQUEST_TYPE_RECIP_INTERFACE

USB_BM_REQUEST_TYPE_RECIP_ENDPOINT

USB_BM_REQUEST_TYPE_RECIP_OTHER

USB_BM_REQUEST_TYPE_RECIP_MASK

USB_B_REQUEST_GET_STATUS

  Bit masks belonging to the bRequest field of a setup packet.

USB_B_REQUEST_CLEAR_FEATURE

USB_B_REQUEST_SET_FEATURE

USB_B_REQUEST_SET_ADDRESS

USB_B_REQUEST_GET_DESCRIPTOR

USB_B_REQUEST_SET_DESCRIPTOR

USB_B_REQUEST_GET_CONFIGURATION

USB_B_REQUEST_SET_CONFIGURATION

USB_B_REQUEST_GET_INTERFACE

USB_B_REQUEST_SET_INTERFACE

USB_B_REQUEST_SYNCH_FRAME

USB_W_VALUE_DT_DEVICE

  Bit masks belonging to the wValue field of a setup packet.

USB_W_VALUE_DT_CONFIG

USB_W_VALUE_DT_STRING

USB_W_VALUE_DT_INTERFACE

USB_W_VALUE_DT_ENDPOINT

USB_W_VALUE_DT_DEVICE_QUALIFIER

USB_W_VALUE_DT_OTHER_SPEED_CONFIG

USB_W_VALUE_DT_INTERFACE_POWER

USB_SETUP_PACKET_INIT_GET_STATUS(setup_pkt_ptr)

  Initializer for a GET_STATUS request.

  Sets the address of a connected device

USB_SETUP_PACKET_INIT_SET_ADDR(setup_pkt_ptr, addr)

  Initializer for a SET_ADDRESS request.

  Sets the address of a connected device

USB_SETUP_PACKET_INIT_GET_DEVICE_DESC(setup_pkt_ptr)

  Initializer for a request to get a device's device descriptor.

USB_SETUP_PACKET_INIT_GET_CONFIG(setup_pkt_ptr)

  Initializer for a request to get a device's current configuration number.

USB_SETUP_PACKET_INIT_GET_CONFIG_DESC(setup_pkt_ptr, desc_index, desc_len)

  Initializer for a request to get one of the device's current configuration descriptor.

  - desc_index indicates the configuration's index number

  - Number of bytes of the configuration descriptor to get

USB_SETUP_PACKET_INIT_SET_CONFIG(setup_pkt_ptr, config_num)

  Initializer for a request to set a device's current configuration number.

USB_SETUP_PACKET_INIT_SET_INTERFACE(setup_pkt_ptr, intf_num, alt_setting_num)

  Initializer for a request to set an interface's alternate setting.

USB_SETUP_PACKET_INIT_GET_STR_DESC(setup_pkt_ptr, string_index, lang_id, desc_len)

  Initializer for a request to get an string descriptor.

USB_STANDARD_DESC_SIZE

  Size of dummy USB standard descriptor.

USB_DEVICE_DESC_SIZE

  Size of a USB device descriptor in bytes.

USB_CLASS_PER_INTERFACE

  Possible base class values of the bDeviceClass field of a USB device descriptor.

USB_CLASS_AUDIO

USB_CLASS_COMM

USB_CLASS_HID

USB_CLASS_PHYSICAL

USB_CLASS_STILL_IMAGE

USB_CLASS_PRINTER

USB_CLASS_MASS_STORAGE

USB_CLASS_HUB

USB_CLASS_CDC_DATA

USB_CLASS_CSCID

USB_CLASS_CONTENT_SEC

USB_CLASS_VIDEO

USB_CLASS_WIRELESS_CONTROLLER

USB_CLASS_PERSONAL_HEALTHCARE

USB_CLASS_AUDIO_VIDEO

USB_CLASS_BILLBOARD

USB_CLASS_USB_TYPE_C_BRIDGE

USB_CLASS_MISC

USB_CLASS_APP_SPEC

USB_CLASS_VENDOR_SPEC

USB_SUBCLASS_VENDOR_SPEC

  Vendor specific subclass code.

USB_CONFIG_DESC_SIZE

  Size of a short USB configuration descriptor in bytes.

  备注

  The size of a full USB configuration includes all the interface and endpoint descriptors of that configuration.

USB_BM_ATTRIBUTES_ONE

  Bit masks belonging to the bmAttributes field of a configuration descriptor.

  Must be set

USB_BM_ATTRIBUTES_SELFPOWER

  Self powered

USB_BM_ATTRIBUTES_WAKEUP

  Can wake-up

USB_BM_ATTRIBUTES_BATTERY

  Battery powered

USB_IAD_DESC_SIZE

  Size of a USB interface association descriptor in bytes.

USB_INTF_DESC_SIZE

  Size of a USB interface descriptor in bytes.

USB_EP_DESC_SIZE

  Size of a USB endpoint descriptor in bytes.

USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK

  Bit masks belonging to the bEndpointAddress field of an endpoint descriptor.

USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK

USB_W_MAX_PACKET_SIZE_MPS_MASK

  Bit masks belonging to the wMaxPacketSize field of endpoint descriptor.

USB_W_MAX_PACKET_SIZE_MULT_MASK

USB_BM_ATTRIBUTES_XFERTYPE_MASK

  Bit masks belonging to the bmAttributes field of an endpoint descriptor.

USB_BM_ATTRIBUTES_XFER_CONTROL

USB_BM_ATTRIBUTES_XFER_ISOC

USB_BM_ATTRIBUTES_XFER_BULK

USB_BM_ATTRIBUTES_XFER_INT

USB_BM_ATTRIBUTES_SYNCTYPE_MASK

USB_BM_ATTRIBUTES_SYNC_NONE

USB_BM_ATTRIBUTES_SYNC_ASYNC

USB_BM_ATTRIBUTES_SYNC_ADAPTIVE

USB_BM_ATTRIBUTES_SYNC_SYNC

USB_BM_ATTRIBUTES_USAGETYPE_MASK

USB_BM_ATTRIBUTES_USAGE_DATA

USB_BM_ATTRIBUTES_USAGE_FEEDBACK

USB_BM_ATTRIBUTES_USAGE_IMPLICIT_FB

USB_EP_DESC_GET_XFERTYPE(desc_ptr)

  Macro helpers to get information about an endpoint from its descriptor.

USB_EP_DESC_GET_EP_NUM(desc_ptr)

USB_EP_DESC_GET_EP_DIR(desc_ptr)

USB_EP_DESC_GET_MPS(desc_ptr)

USB_EP_DESC_GET_MULT(desc_ptr)

USB_EP_DESC_GET_SYNCTYPE(desc_ptr)

USB_EP_DESC_GET_USAGETYPE(desc_ptr)

USB_STR_DESC_SIZE

  Size of a short USB string descriptor in bytes.

### Enumerations

enum usb_device_state_t

  USB2.0 device states.

  See Table 9-1 of USB2.0 specification for more details

  备注

  The USB_DEVICE_STATE_NOT_ATTACHED is not part of the USB2.0 specification, but is a catch all state for devices that need to be cleaned up after a sudden disconnection or port error.

  Values:

  enumerator USB_DEVICE_STATE_NOT_ATTACHED

    The device was previously configured or suspended, but is no longer attached (either suddenly disconnected or a port error)

  enumerator USB_DEVICE_STATE_ATTACHED

    Device is attached to the USB, but is not powered.

  enumerator USB_DEVICE_STATE_POWERED

    Device is attached to the USB and powered, but has not been reset.

  enumerator USB_DEVICE_STATE_DEFAULT

    Device is attached to the USB and powered and has been reset, but has not been assigned a unique address. Device responds at the default address.

  enumerator USB_DEVICE_STATE_ADDRESS

    Device is attached to the USB, powered, has been reset, and a unique device address has been assigned. Device is not configured.

  enumerator USB_DEVICE_STATE_CONFIGURED

    Device is attached to the USB, powered, has been reset, has a unique address, is configured, and is not suspended. The host may now use the function provided by the device.

  enumerator USB_DEVICE_STATE_SUSPENDED

    Device is, at minimum, attached to the USB and is powered and has not seen bus activity for 3 ms. It may also have a unique address and be configured for use. However, because the device is suspended, the host may not use the device’s function.

## 维护注意事项

备注

有关 USB 主机栈内部实现的更多细节，请参阅 USB Host Maintainers Notes (Introduction)。

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。