Skip to content

Commit 47c5fad

Browse files
feat(hub): Added support for multiple root ports
This will allow having both FS and HS root ports active at the same time and connected devices working properly.
1 parent ce33f71 commit 47c5fad

File tree

7 files changed

+304
-110
lines changed

7 files changed

+304
-110
lines changed

host/usb/private_include/ext_hub.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -97,6 +97,15 @@ void *ext_hub_get_client(void);
9797
*/
9898
esp_err_t ext_hub_get_speed(ext_hub_handle_t ext_hub_hdl, usb_speed_t *speed);
9999

100+
/**
101+
* @brief Get the root port handle of an External Hub device
102+
*
103+
* @param[in] ext_hub_hdl External Hub device handle
104+
*
105+
* @return Root port handle on success, NULL on error
106+
*/
107+
hcd_port_handle_t ext_hub_get_root_port(ext_hub_handle_t ext_hub_hdl);
108+
100109
/**
101110
* @brief Add new device
102111
*

host/usb/private_include/hcd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ extern "C" {
1414
#include <stdbool.h>
1515
#include <sys/queue.h>
1616
#include "esp_err.h"
17+
#include "soc/soc_caps.h"
1718
#include "esp_idf_version.h"
1819
#include "usb_private.h"
1920
#include "usb/usb_types_ch9.h"
2021

2122
// ------------------------------------------------- Macros & Types ----------------------------------------------------
2223

24+
// ----------------------- Configs -------------------------
25+
26+
#define HCD_NUM_PORTS SOC_USB_OTG_PERIPH_NUM // Each peripheral is a root port
27+
2328
// --------------------- IDF Versioning compatibility -------------------------
2429

2530
// Remote wakeup HAL changes are present
@@ -315,6 +320,8 @@ esp_err_t hcd_port_recover(hcd_port_handle_t port_hdl);
315320
/**
316321
* @brief Get the context variable of a port
317322
*
323+
* @note Used only in tests
324+
*
318325
* @param[in] port_hdl Port handle
319326
*
320327
* @return

host/usb/private_include/usbh.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -395,6 +395,18 @@ esp_err_t usbh_dev_get_addr(usb_device_handle_t dev_hdl, uint8_t *dev_addr);
395395
*/
396396
esp_err_t usbh_dev_get_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_info);
397397

398+
/**
399+
* @brief Get the root port handle of a device
400+
*
401+
* @param[in] dev_hdl Device handle
402+
* @param[out] root_port_hdl Root port handle
403+
*
404+
* @return
405+
* - ESP_OK: Root port handle obtained successfully
406+
* - ESP_ERR_INVALID_ARG: Invalid argument
407+
*/
408+
esp_err_t usbh_dev_get_root_port_hdl(usb_device_handle_t dev_hdl, hcd_port_handle_t *root_port_hdl);
409+
398410
/**
399411
* @brief Get a device's device descriptor
400412
*

host/usb/src/ext_hub.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -1298,6 +1298,18 @@ esp_err_t ext_hub_get_speed(ext_hub_handle_t ext_hub_hdl, usb_speed_t *speed)
12981298
return ESP_OK;
12991299
}
13001300

1301+
hcd_port_handle_t ext_hub_get_root_port(ext_hub_handle_t ext_hub_hdl)
1302+
{
1303+
EXT_HUB_CHECK(ext_hub_hdl != NULL, NULL);
1304+
EXT_HUB_CHECK(dev_is_in_list(ext_hub_hdl), NULL);
1305+
ext_hub_dev_t *ext_hub_dev = (ext_hub_dev_t *)ext_hub_hdl;
1306+
hcd_port_handle_t root_port_hdl = NULL;
1307+
if (usbh_dev_get_root_port_hdl(ext_hub_dev->constant.dev_hdl, &root_port_hdl) != ESP_OK) {
1308+
return NULL;
1309+
}
1310+
return root_port_hdl;
1311+
}
1312+
13011313
esp_err_t ext_hub_new_dev(uint8_t dev_addr)
13021314
{
13031315
EXT_HUB_ENTER_CRITICAL();

host/usb/src/hcd_dwc.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "esp_err.h"
1818
#include "esp_log.h"
1919

20-
#include "soc/soc_caps.h"
2120
#include "hal/usb_dwc_hal.h"
2221
#include "hcd.h"
2322
#include "usb_private.h"
@@ -51,8 +50,6 @@
5150
#define CTRL_EP_MAX_MPS_LS 8 // Largest Maximum Packet Size for Low Speed control endpoints
5251
#define CTRL_EP_MAX_MPS_HSFS 64 // Largest Maximum Packet Size for High & Full Speed control endpoints
5352

54-
#define NUM_PORTS SOC_USB_OTG_PERIPH_NUM // Each peripheral is a root port
55-
5653
// ----------------------- Configs -------------------------
5754

5855
#ifdef CONFIG_USB_HOST_DWC_DMA_CAP_MEMORY_IN_PSRAM // In esp32p4, the USB-DWC internal DMA can access external RAM
@@ -269,7 +266,7 @@ struct port_obj {
269266

270267
// With s_port_inited[] we can check if a port has been initialized -> to provide singleton handle for each root port
271268
// Each peripheral is a root port
272-
static bool s_port_inited[NUM_PORTS] = {0};
269+
static bool s_port_inited[HCD_NUM_PORTS] = {0};
273270

274271
// ------------------------------------------------- Forward Declare ---------------------------------------------------
275272

@@ -1447,7 +1444,7 @@ static esp_err_t _port_cmd_disable(port_t *port)
14471444
esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, hcd_port_handle_t *port_hdl)
14481445
{
14491446
HCD_CHECK(port_number >= 0 && port_config != NULL && port_hdl != NULL, ESP_ERR_INVALID_ARG);
1450-
HCD_CHECK(port_number < NUM_PORTS, ESP_ERR_NOT_FOUND);
1447+
HCD_CHECK(port_number < HCD_NUM_PORTS, ESP_ERR_NOT_FOUND);
14511448

14521449
HCD_ENTER_CRITICAL();
14531450
HCD_CHECK_FROM_CRIT(!s_port_inited[port_number], ESP_ERR_INVALID_STATE);

0 commit comments

Comments
 (0)