usb: Hub Driver Update and Refactor

Hub Driver is refactored as follows:

This commit update and refactors the Hub Driver as follows:

- Refactored enumeration state machine and stage functions
    - Enumeration stage is now incremented
    - Combined transfer stages of enumeration into common functions
- Comments updated
- Fixed usbh_hal_disable_debounce_lock() that would cause root_port_handle_events()
    to fail the HCD_PORT_CMD_RESET call because the previous port connection interrupt
    was not cleared.

The following features were added to the Hub Driver

- Enumeration config descriptor is now fetched in two separate stages
    - Header is fetched first to determine the wTotalLength of the descriptor
    - Fetching the full descriptor will request exactly wTotalLength bytes
    - This works around some non-compliant devices that will babble/return zero
        when requesting a length > wTotalLength
    - Closes https://github.com/espressif/esp-idf/issues/7799
- Enumeration now stores string descriptors
    - The Manufacturer, Product, and Serial Number string descriptors are
        now read and stored during enumeration
    - String descriptors are now part of usb_device_info_t
- Added unit test to test enumeration
This commit is contained in:
Darian Leung
2021-12-08 19:46:46 +08:00
parent 7f09fe1b23
commit ea6de613bf
14 changed files with 1020 additions and 380 deletions

View File

@@ -72,6 +72,16 @@ typedef struct {
};
} usb_host_client_event_msg_t;
// ------------------------ Info ---------------------------
/**
* @brief Current information about the USB Host Library obtained via usb_host_lib_info()
*/
typedef struct {
int num_devices; /**< Current number of connected (and enumerated) devices */
int num_clients; /**< Current number of registered clients */
} usb_host_lib_info_t;
// ---------------------- Callbacks ------------------------
/**
@@ -166,6 +176,14 @@ esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_f
*/
esp_err_t usb_host_lib_unblock(void);
/**
* @brief Get current information about the USB Host Library
*
* @param[out] info_ret USB Host Library Information
* @return esp_err_t
*/
esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret);
// ------------------------------------------------ Client Functions ---------------------------------------------------
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -217,11 +217,11 @@ _Static_assert(sizeof(usb_setup_packet_t) == USB_SETUP_PACKET_SIZE, "Size of usb
/**
* @brief Initializer for a request to get an string descriptor
*/
#define USB_SETUP_PACKET_INIT_GET_STR_DESC(setup_pkt_ptr, string_index, desc_len) ({ \
#define USB_SETUP_PACKET_INIT_GET_STR_DESC(setup_pkt_ptr, string_index, lang_id, desc_len) ({ \
(setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_IN | USB_BM_REQUEST_TYPE_TYPE_STANDARD | USB_BM_REQUEST_TYPE_RECIP_DEVICE; \
(setup_pkt_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR; \
(setup_pkt_ptr)->wValue = (USB_W_VALUE_DT_STRING << 8) | ((string_index) & 0xFF); \
(setup_pkt_ptr)->wIndex = 0; \
(setup_pkt_ptr)->wIndex = (lang_id); \
(setup_pkt_ptr)->wLength = (desc_len); \
})
@@ -465,7 +465,7 @@ _Static_assert(sizeof(usb_ep_desc_t) == USB_EP_DESC_SIZE, "Size of usb_ep_desc_t
/**
* @brief Size of a short USB string descriptor in bytes
*/
#define USB_STR_DESC_SIZE 4
#define USB_STR_DESC_SIZE 2
/**
* @brief Structure representing a USB string descriptor
@@ -474,7 +474,7 @@ typedef union {
struct {
uint8_t bLength; /**< Size of the descriptor in bytes */
uint8_t bDescriptorType; /**< STRING Descriptor Type */
uint16_t wData[1]; /**< UTF-16LE encoded */
uint16_t wData[0]; /**< UTF-16LE encoded */
} USB_DESC_ATTR;
uint8_t val[USB_STR_DESC_SIZE];
} usb_str_desc_t;

View File

@@ -49,10 +49,13 @@ typedef struct usb_device_handle_s * usb_device_handle_t;
* @brief Basic information of an enumerated device
*/
typedef struct {
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 */
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) */
} usb_device_info_t;
// ------------------------------------------------ Transfer Related ---------------------------------------------------