Skip to content

Commit fbc08d7

Browse files
committed
feature(usb_host): Added handling of peripheral map during install
- HUB: Added periph_idx argument to hub_root_start() and hub_root_stop()
1 parent b8147b0 commit fbc08d7

File tree

3 files changed

+72
-63
lines changed

3 files changed

+72
-63
lines changed

host/usb/private_include/hub.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,22 +111,26 @@ esp_err_t hub_uninstall(void);
111111
*
112112
* @note This function should only be called from the Host Library task
113113
*
114+
* @param[in] port_idx Root port index
115+
*
114116
* @return
115117
* - ESP_OK: Hub driver started successfully
116118
* - ESP_ERR_INVALID_STATE: Hub driver is not installed, or root port is in other state than not powered
117119
*/
118-
esp_err_t hub_root_start(void);
120+
esp_err_t hub_root_start(uint8_t port_idx);
119121

120122
/**
121123
* @brief Stops the Hub driver's root port
122124
*
123125
* This will power OFF the root port
124126
*
127+
* @param[in] port_idx Root port index
128+
*
125129
* @return
126130
* - ESP_OK: Hub driver started successfully
127131
* - ESP_ERR_INVALID_STATE: Hub driver is not installed, or root port is in not powered state
128132
*/
129-
esp_err_t hub_root_stop(void);
133+
esp_err_t hub_root_stop(uint8_t port_idx);
130134

131135
/**
132136
* @brief Indicate to the Hub driver that a device's port can be recycled

host/usb/src/hub.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -734,21 +734,11 @@ esp_err_t hub_uninstall(void)
734734
return ESP_OK;
735735
}
736736

737-
esp_err_t hub_root_start(void)
737+
esp_err_t hub_root_start(uint8_t port_idx)
738738
{
739-
/* TODO: Support hub root port selection in USB Host (higher) layer */
740-
// For now, there is only one root port powered on at any time
741-
root_port_t *root_port;
742-
743739
HUB_DRIVER_ENTER_CRITICAL();
744740
HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE);
745-
for (uint8_t port_idx = 0; port_idx < HUB_ROOT_PORTS; port_idx++) {
746-
root_port = &p_hub_driver_obj->constant.root_port_hdls[port_idx];
747-
if (root_port->constant.hdl != NULL) {
748-
break;
749-
}
750-
}
751-
HUB_DRIVER_CHECK_FROM_CRIT(root_port != NULL, ESP_ERR_NOT_FOUND);
741+
root_port_t *root_port = &p_hub_driver_obj->constant.root_port_hdls[port_idx];
752742
HUB_DRIVER_CHECK_FROM_CRIT(root_port->dynamic.state == ROOT_PORT_STATE_NOT_POWERED, ESP_ERR_INVALID_STATE);
753743
HUB_DRIVER_EXIT_CRITICAL();
754744
// Power ON the root port
@@ -762,20 +752,11 @@ esp_err_t hub_root_start(void)
762752
return ret;
763753
}
764754

765-
esp_err_t hub_root_stop(void)
755+
esp_err_t hub_root_stop(uint8_t port_idx)
766756
{
767-
/* TODO: Support hub root port selection in USB Host (higher) layer */
768-
// For now, there is only one root port powered on at any time
769-
root_port_t *root_port;
770-
771757
HUB_DRIVER_ENTER_CRITICAL();
772758
HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj != NULL, ESP_ERR_INVALID_STATE);
773-
for (uint8_t port_idx = 0; port_idx < HUB_ROOT_PORTS; port_idx++) {
774-
root_port = &p_hub_driver_obj->constant.root_port_hdls[port_idx];
775-
if (root_port->constant.hdl != NULL) {
776-
break;
777-
}
778-
}
759+
root_port_t *root_port = &p_hub_driver_obj->constant.root_port_hdls[port_idx];
779760
if (root_port->dynamic.state == ROOT_PORT_STATE_NOT_POWERED) {
780761
// The HUB was already stopped by usb_host_lib_set_root_port_power(false)
781762
HUB_DRIVER_EXIT_CRITICAL();

host/usb/src/usb_host.c

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ typedef struct {
158158
struct {
159159
SemaphoreHandle_t event_sem;
160160
SemaphoreHandle_t mux_lock;
161-
usb_phy_handle_t phy_handle; // Will be NULL if host library is installed with skip_phy_setup
161+
unsigned peripheral_map; // Peripheral map
162+
usb_phy_handle_t phy_hdls[4 /* TODO: refactor HUB_PORTS_NUM */]; // Will be NULL if host library is installed with skip_phy_setup
162163
void *enum_client; // Pointer to Enum driver (acting as a client). Used to reroute completed USBH control transfers
163164
void *hub_client; // Pointer to External Hub driver (acting as a client). Used to reroute completed USBH control transfers. NULL, when External Hub Driver not available.
164165
} constant;
@@ -463,6 +464,8 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
463464
TAILQ_INIT(&host_lib_obj->mux_protected.client_tailq);
464465
host_lib_obj->constant.event_sem = event_sem;
465466
host_lib_obj->constant.mux_lock = mux_lock;
467+
// For backward compatibility accept 0 too
468+
host_lib_obj->constant.peripheral_map = config->peripheral_map == 0 ? BIT0 : config->peripheral_map;
466469

467470
/*
468471
Install each layer of the Host stack (listed below) from the lowest layer to the highest
@@ -473,35 +476,33 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
473476
- Hub
474477
*/
475478

476-
// For backward compatibility accept 0 too
477-
const unsigned peripheral_map = config->peripheral_map == 0 ? BIT0 : config->peripheral_map;
478-
479479
// Install USB PHY (if necessary). USB PHY driver will also enable the underlying Host Controller
480480
if (!config->skip_phy_setup) {
481-
bool init_utmi_phy = false; // Default value for Linux simulation
482-
483-
#if SOC_USB_OTG_SUPPORTED // In case we run on a real target, select the PHY from usb_dwc_info description structure
484-
// Right now we support only one peripheral, can be extended in future
485-
int peripheral_index = 0;
486-
if (peripheral_map & BIT1) {
487-
peripheral_index = 1;
488-
}
489-
init_utmi_phy = (usb_dwc_info.controllers[peripheral_index].supported_phys == USB_PHY_INST_UTMI_0);
490-
#endif // SOC_USB_OTG_SUPPORTED
491-
492-
// Host Library defaults to internal PHY
481+
// Host Library defaults to install PHY
493482
usb_phy_config_t phy_config = {
494483
.controller = USB_PHY_CTRL_OTG,
495-
.target = init_utmi_phy ? USB_PHY_TARGET_UTMI : USB_PHY_TARGET_INT,
496484
.otg_mode = USB_OTG_MODE_HOST,
497485
.otg_speed = USB_PHY_SPEED_UNDEFINED, // In Host mode, the speed is determined by the connected device
498-
.ext_io_conf = NULL,
499-
.otg_io_conf = NULL,
500486
};
501-
ret = usb_new_phy(&phy_config, &host_lib_obj->constant.phy_handle);
502-
if (ret != ESP_OK) {
503-
ESP_LOGE(USB_HOST_TAG, "PHY install error: %s", esp_err_to_name(ret));
504-
goto phy_err;
487+
488+
for (unsigned idx = 0; idx < 4 /* TODO: refactor HUB_PORTS_NUM */; idx++) {
489+
if (host_lib_obj->constant.peripheral_map & (BIT0 << idx)) {
490+
#if SOC_USB_OTG_SUPPORTED // In case we run on a real target, select the PHY from usb_dwc_info description structure
491+
// TODO: Check the periph_idx in usb_dwc_info.controllers bounds
492+
// Right now we support only one peripheral, can be extended in future
493+
if (usb_dwc_info.controllers[idx].supported_phys == USB_PHY_INST_UTMI_0) {
494+
phy_config.target = USB_PHY_TARGET_UTMI;
495+
} else {
496+
phy_config.target = USB_PHY_TARGET_INT;
497+
}
498+
#endif // SOC_USB_OTG_SUPPORTED
499+
ret = usb_new_phy(&phy_config, &host_lib_obj->constant.phy_hdls[idx]);
500+
if (ret != ESP_OK) {
501+
ESP_LOGE(USB_HOST_TAG, "PHY for peripheral %d install error: %s",
502+
idx, esp_err_to_name(ret));
503+
goto phy_err;
504+
}
505+
}
505506
}
506507
}
507508

@@ -510,7 +511,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
510511
hcd_fifo_settings_t user_fifo_config;
511512
hcd_config_t hcd_config = {
512513
.intr_flags = config->intr_flags,
513-
.peripheral_map = peripheral_map,
514+
.peripheral_map = host_lib_obj->constant.peripheral_map,
514515
.fifo_config = NULL, // Default: use bias strategy from Kconfig
515516
};
516517

@@ -565,7 +566,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
565566

566567
// Install Hub
567568
hub_config_t hub_config = {
568-
.port_map = peripheral_map, // Each USB-OTG peripheral maps to a root port
569+
.port_map = host_lib_obj->constant.peripheral_map, // Each USB-OTG peripheral maps to a root port
569570
.proc_req_cb = proc_req_callback,
570571
.proc_req_cb_arg = NULL,
571572
.event_cb = hub_event_callback,
@@ -588,8 +589,12 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
588589
HOST_EXIT_CRITICAL();
589590

590591
if (!config->root_port_unpowered) {
591-
// Start the root hub
592-
ESP_ERROR_CHECK(hub_root_start());
592+
// Start the root hub according to the peripheral map
593+
for (unsigned idx = 0; idx < 4 /* TODO: refactor HUB_PORTS_NUM */; idx++) {
594+
if (p_host_lib_obj->constant.peripheral_map & (BIT0 << idx)) {
595+
ESP_ERROR_CHECK(hub_root_start(idx));
596+
}
597+
}
593598
}
594599

595600
ret = ESP_OK;
@@ -604,10 +609,13 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
604609
usbh_err:
605610
ESP_ERROR_CHECK(hcd_uninstall());
606611
hcd_err:
607-
if (host_lib_obj->constant.phy_handle) {
608-
ESP_ERROR_CHECK(usb_del_phy(host_lib_obj->constant.phy_handle));
609-
}
610612
phy_err:
613+
for (unsigned idx = 0; idx < 4 /* TODO: refactor HUB_PORTS_NUM */; idx++) {
614+
if (host_lib_obj->constant.peripheral_map & (BIT0 << idx) &&
615+
(host_lib_obj->constant.phy_hdls[idx] != NULL)) {
616+
ESP_ERROR_CHECK(usb_del_phy(host_lib_obj->constant.phy_hdls[idx]));
617+
}
618+
}
611619
alloc_err:
612620
if (mux_lock) {
613621
vSemaphoreDelete(mux_lock);
@@ -630,8 +638,12 @@ esp_err_t usb_host_uninstall(void)
630638
ESP_ERR_INVALID_STATE);
631639
HOST_EXIT_CRITICAL();
632640

633-
// Stop the root hub
634-
ESP_ERROR_CHECK(hub_root_stop());
641+
// Stop the root hub according to the peripheral map
642+
for (unsigned idx = 0; idx < 4 /* TODO: refactor HUB_PORTS_NUM */; idx++) {
643+
if (p_host_lib_obj->constant.peripheral_map & (BIT0 << idx)) {
644+
ESP_ERROR_CHECK(hub_root_stop(idx));
645+
}
646+
}
635647

636648
// Unassign the host library object
637649
HOST_ENTER_CRITICAL();
@@ -652,8 +664,11 @@ esp_err_t usb_host_uninstall(void)
652664
ESP_ERROR_CHECK(usbh_uninstall());
653665
ESP_ERROR_CHECK(hcd_uninstall());
654666
// If the USB PHY was setup, then delete it
655-
if (host_lib_obj->constant.phy_handle) {
656-
ESP_ERROR_CHECK(usb_del_phy(host_lib_obj->constant.phy_handle));
667+
for (unsigned idx = 0; idx < 4 /* TODO: refactor HUB_PORTS_NUM */; idx++) {
668+
if (host_lib_obj->constant.peripheral_map & (BIT0 << idx) &&
669+
(host_lib_obj->constant.phy_hdls[idx] != NULL)) {
670+
ESP_ERROR_CHECK(usb_del_phy(host_lib_obj->constant.phy_hdls[idx]));
671+
}
657672
}
658673

659674
// Free memory objects
@@ -747,10 +762,19 @@ esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret)
747762
esp_err_t usb_host_lib_set_root_port_power(bool enable)
748763
{
749764
esp_err_t ret;
750-
if (enable) {
751-
ret = hub_root_start();
752-
} else {
753-
ret = hub_root_stop();
765+
766+
// Set port power for every port according to the peripheral map
767+
for (unsigned idx = 0; idx < 4 /* TODO: refactor HUB_PORTS_NUM */; idx++) {
768+
if (p_host_lib_obj->constant.peripheral_map & (BIT0 << idx)) {
769+
if (enable) {
770+
ret = hub_root_start(idx);
771+
} else {
772+
ret = hub_root_stop(idx);
773+
}
774+
if (ret != ESP_OK) {
775+
return ret;
776+
}
777+
}
754778
}
755779

756780
return ret;

0 commit comments

Comments
 (0)