USB Host CDC

[中文]

The iot_usbh_cdc component implements a simple version of the USB host CDC driver. The API is designed similar like ESP-IDF UART driver, which can be used to replace the original UART driver to realize the update from UART to USB.

User Guide

  1. Use usbh_cdc_driver_install to configure the USB CDC driver. Users can set up the driver and initialize the USB Host Driver protocol stack internally by setting the skip_init_usb_host_driver option.

/* Install the USB CDC driver and initialize the USB Host Driver protocol stack internally */
usbh_cdc_driver_config_t config = {
    .driver_task_stack_size = 1024 * 4,
    .driver_task_priority = 5,
    .xCoreID = 0,
    .skip_init_usb_host_driver = false,
    .new_dev_cb = cdc_new_dev_cb,
};
  1. Use usbh_cdc_create to configure the interface number (itf_num) and the size of the internal ring buffer. Additionally, users can configure hot-plug callbacks such as connect, disconnect, and recv_data:

/* Install the USB Host CDC driver and configure bulk endpoint addresses and internal ring buffer size */
usbh_cdc_device_config_t dev_config = {
    .vid = 0,
    .pid = 0,
    .itf_num = 1,
    /* Set to 0 to use default values */
    .rx_buffer_size = 0,
    .tx_buffer_size = 0,
    .cbs = {
        .connect = cdc_connect_cb,
        .disconnect = cdc_disconnect_cb,
        .user_data = NULL
    },
};

usbh_cdc_handle_t handle = NULL;
usbh_cdc_create(&dev_config, &handle);
/* If multiple interfaces are required, configure them like this */
#if (EXAMPLE_BULK_ITF_NUM > 1)
config.itf_num = 3;
usbh_cdc_handle_t handle2 = NULL;
usbh_cdc_create(&dev_config, &handle2);
#endif
  1. After the driver is initialized, the internal state machine will automatically handle USB hot-plug events.

  2. Once successfully connected, the host will automatically receive USB data from the CDC device into an internal ringbuffer. Users can poll the buffer size using usbh_cdc_get_rx_buffer_size or register a callback to get notified when data is ready. Data can then be read using usbh_cdc_read_bytes.

  3. usbh_cdc_write_bytes can be used to send data to the USB device. The data is first written to an internal transmission ringbuffer and then sent over the USB bus when it is idle.

  4. usbh_cdc_delete can be used to delete the USB CDC device and release the associated ring buffer and other resources.

  5. usbh_cdc_driver_uninstall can completely uninstall the USB driver and release all resources.

Examples

usb/host/usb_cdc_basic

API Reference

Header File

Functions

esp_err_t usbh_cdc_driver_install(const usbh_cdc_driver_config_t *config)

Install the USB CDC driver.

This function installs and initializes the USB CDC driver. It sets up internal data structures, creates necessary tasks, and registers the USB host client. If the USB host driver is not already initialized, it will create and initialize it.

The function performs the following steps:

  1. Verifies input arguments and state.

  2. Optionally initializes the USB host driver.

  3. Allocates memory for the USB CDC object.

  4. Creates necessary synchronization primitives (event group, mutex).

  5. Creates the driver task.

  6. Registers the USB host client with the provided configuration.

  7. Initializes the CDC driver structure and resumes the driver task.

In case of an error, the function will clean up any resources that were allocated before the failure occurred.

Note

If the skip_init_usb_host_driver flag in the config is set to true, the function will skip the USB host driver initialization.

Parameters

config – Pointer to a configuration structure (usbh_cdc_driver_config_t) that specifies the driver’s settings such as task stack size, priority, core affinity, and new device callback.

Returns

  • ESP_OK: Driver installed successfully

  • ESP_ERR_INVALID_ARG: Null configuration parameter or invalid arguments

  • ESP_ERR_INVALID_STATE: USB CDC driver already installed

  • ESP_ERR_NO_MEM: Memory allocation failed

  • ESP_FAIL: Failed to create necessary tasks or USB host installation failed

esp_err_t usbh_cdc_driver_uninstall(void)

Uninstall the USB CDC driver.

This function uninstalls the USB CDC driver, releasing any allocated resources and stopping all driver-related tasks. It ensures that all CDC devices are closed before proceeding with the uninstallation.

Returns

  • ESP_OK: Driver uninstalled successfully

  • ESP_ERR_INVALID_STATE: Driver is not installed or devices are still active

  • ESP_ERR_NOT_FINISHED: Timeout occurred while waiting for the CDC task to finish

esp_err_t usbh_cdc_create(const usbh_cdc_device_config_t *config, usbh_cdc_handle_t *cdc_handle)

Create a new USB CDC device handle.

This function allocates and initializes a new USB CDC device based on the provided configuration, including setting up the ring buffers for data transmission and reception, and searching for and opening the appropriate USB device.

Parameters
  • cdc_handle[out] Pointer to a variable that will hold the created CDC device handle upon successful creation

  • config[in] Pointer to a usbh_cdc_device_config_t structure containing the configuration for the new device, including vendor ID (VID), product ID (PID), and buffer sizes

Returns

  • ESP_OK: CDC device successfully created

  • ESP_ERR_INVALID_STATE: USB CDC driver is not installed

  • ESP_ERR_INVALID_ARG: Null cdc_handle or config parameter

  • ESP_ERR_NO_MEM: Memory allocation failed or ring buffer creation failed

  • ESP_FAIL: Failed to open the CDC device

esp_err_t usbh_cdc_delete(usbh_cdc_handle_t cdc_handle)

Delete a USB CDC device handle.

This function deletes the specified USB CDC device handle, freeing its associated resources, including ring buffers and semaphores.

Note

When deleting the device, please avoid writing or reading data.

Parameters

cdc_handle[in] The CDC device handle to delete

Returns

  • ESP_OK: CDC device deleted successfully

  • ESP_ERR_INVALID_STATE: USB CDC driver is not installed

  • ESP_ERR_INVALID_ARG: Invalid CDC handle provided

esp_err_t usbh_cdc_write_bytes(usbh_cdc_handle_t cdc_handle, const uint8_t *buf, size_t length, TickType_t ticks_to_wait)

Write data to the USB CDC device.

This function writes data to the specified USB CDC device by pushing the data into the output ring buffer. If the buffer is full or the device is not connected, the write will fail.

Parameters
  • cdc_handle[in] The CDC device handle

  • buf[in] Pointer to the data buffer to write

  • length[in] Pointer to the length of data to write. On success, it remains unchanged, otherwise set to 0.

  • ticks_to_wait[in] The maximum amount of time to wait for the write operation to complete

Returns

  • ESP_OK: Data written successfully

  • ESP_ERR_INVALID_ARG: Invalid argument (NULL handle, buffer, or length)

  • ESP_ERR_INVALID_STATE: Device is not connected

esp_err_t usbh_cdc_read_bytes(usbh_cdc_handle_t cdc_handle, const uint8_t *buf, size_t *length, TickType_t ticks_to_wait)

Read data from the USB CDC device.

This function reads data from the specified USB CDC device by popping data from the input ring buffer. If no data is available or the device is not connected, the read will fail.

Parameters
  • cdc_handle[in] The CDC device handle

  • buf[out] Pointer to the buffer where the read data will be stored

  • length[inout] Pointer to the length of data to read. On success, it is updated with the actual bytes read.

  • ticks_to_wait[in] The maximum amount of time to wait for the read operation to complete

Returns

  • ESP_OK: Data read successfully

  • ESP_FAIL: Failed to read data

  • ESP_ERR_INVALID_ARG: Invalid argument (NULL handle, buffer, or length)

  • ESP_ERR_INVALID_STATE: Device is not connected

esp_err_t usbh_cdc_flush_rx_buffer(usbh_cdc_handle_t cdc_handle)

Flush the receive buffer of the USB CDC device.

This function clears the receive buffer, discarding any data currently in the buffer.

Parameters

cdc_handle[in] The CDC device handle

Returns

  • ESP_OK: Receive buffer flushed successfully

  • ESP_ERR_INVALID_ARG: Invalid CDC handle provided

esp_err_t usbh_cdc_flush_tx_buffer(usbh_cdc_handle_t cdc_handle)

Flush the transmit buffer of the USB CDC device.

This function clears the transmit buffer, discarding any data currently in the buffer.

Parameters

cdc_handle[in] The CDC device handle

Returns

  • ESP_OK: Transmit buffer flushed successfully

  • ESP_ERR_INVALID_ARG: Invalid CDC handle provided

esp_err_t usbh_cdc_get_rx_buffer_size(usbh_cdc_handle_t cdc_handle, size_t *size)

Get the size of the receive buffer of the USB CDC device.

This function retrieves the current size of the receive buffer in bytes.

Parameters
  • cdc_handle[in] The CDC device handle

  • size[out] Pointer to store the size of the receive buffer

Returns

  • ESP_OK: Size retrieved successfully

  • ESP_ERR_INVALID_ARG: Invalid CDC handle provided

esp_err_t usbh_cdc_get_state(usbh_cdc_handle_t cdc_handle, usbh_cdc_state_t *state)

Get the connect state of given interface.

Parameters
  • cdc_handle[in] The CDC device handle

  • state[out] Pointer to store the connect state

Returns

  • ESP_OK: Size retrieved successfully

  • ESP_ERR_INVALID_ARG: Invalid CDC handle provided

esp_err_t usbh_cdc_desc_print(usbh_cdc_handle_t cdc_handle)

Print the USB CDC device descriptors.

This function retrieves and prints the USB device and configuration descriptors for the specified USB CDC device. It checks that the device is properly connected and open before retrieving and printing the descriptors.

Parameters

cdc_handle[in] The CDC device handle

Returns

  • ESP_OK: Descriptors printed successfully

  • ESP_ERR_INVALID_ARG: Invalid CDC handle provided

  • ESP_ERR_INVALID_STATE: Device is not connected or not yet open

Structures

struct usbh_cdc_driver_config_t

CDC driver configuration.

Public Members

size_t task_stack_size

Stack size of the driver’s task

unsigned task_priority

Priority of the driver’s task

int task_coreid

Core of the driver’s task, Set it to -1 to not specify the core.

bool skip_init_usb_host_driver

Skip initialization of USB host driver

usbh_cdc_new_dev_cb_t new_dev_cb

Callback function when a new device is connected

struct usbh_cdc_event_callbacks_t

Callback structure for CDC device events.

Public Members

usbh_cdc_event_cb_t connect

USB connect callback, set NULL if use

usbh_cdc_event_cb_t disconnect

USB disconnect callback, set NULL if not use

usbh_cdc_event_cb_t revc_data

USB receive data callback, set NULL if not use

void *user_data

Pointer to user data that will be passed to the callbacks

struct usbh_cdc_config

Configuration structure for initializing a USB CDC device.

Public Members

uint16_t vid

Vendor ID: If set, the pid parameter must be configured If not set, it will default to opening the first connected device

uint16_t pid

Product ID: If set, the vid parameter must be configured If not set, it will default to opening the first connected device

int itf_num

interface numbers

size_t rx_buffer_size

Size of the receive buffer, default is 1024 bytes if set to 0

size_t tx_buffer_size

Size of the transmit buffer, default is 1024 bytes if set to 0

usbh_cdc_event_callbacks_t cbs

Event callbacks for the CDC device

Macros

CDC_HOST_ANY_VID
CDC_HOST_ANY_PID

Type Definitions

typedef struct usbh_cdc_t *usbh_cdc_handle_t
typedef void (*usbh_cdc_new_dev_cb_t)(usb_device_handle_t usb_dev)

New USB device callback.

Provides already opened usb_dev, that will be closed after this callback returns. This is useful for peeking device’s descriptors, e.g. peeking VID/PID and loading proper driver.

Attention

This callback is called from USB Host context, so the CDC device can’t be opened here.

typedef void (*usbh_cdc_event_cb_t)(usbh_cdc_handle_t cdc_handle, void *user_data)

Callback structure for CDC device events.

typedef struct usbh_cdc_config usbh_cdc_device_config_t

Configuration structure for initializing a USB CDC device.

Enumerations

enum usbh_cdc_state_t

State of the USB CDC device.

Values:

enumerator USBH_CDC_CLOSE
enumerator USBH_CDC_OPEN
enumerator USBH_CDC_STATE_MAX