refactor(usb/phy): Start using values from usb_dwc_info in PHY driver

Add tests for PHY sanity checks
This commit is contained in:
Tomas Rezucha
2025-01-03 18:51:08 +01:00
parent b78bcaea36
commit f93e1bc43b
10 changed files with 280 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -22,7 +22,8 @@ extern "C"
* @brief USB PHY target * @brief USB PHY target
*/ */
typedef enum { typedef enum {
USB_PHY_TARGET_INT, /**< USB target is internal PHY */ USB_PHY_TARGET_INT, /**< USB target is internal FSLS PHY */
USB_PHY_TARGET_UTMI, /**< USB target is internal UTMI PHY */
USB_PHY_TARGET_EXT, /**< USB target is external PHY */ USB_PHY_TARGET_EXT, /**< USB target is external PHY */
USB_PHY_TARGET_MAX, USB_PHY_TARGET_MAX,
} usb_phy_target_t; } usb_phy_target_t;

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -109,10 +109,11 @@ typedef struct phy_context_t *usb_phy_handle_t; /**< USB PHY context handle *
* @param[out] handle_ret USB PHY context handle * @param[out] handle_ret USB PHY context handle
* *
* @return * @return
* - ESP_OK Success * - ESP_OK Success
* - ESP_FAIL USB PHY init error. * - ESP_ERR_INVALID_STATE USB PHY already initialized.
* - ESP_ERR_INVALID_STATE USB PHY not installed. * - ESP_ERR_NO_MEM USB_OTG Installation failed due to no mem.
* - ESP_ERR_NO_MEM USB_OTG installation failed due to no mem. * - ESP_ERR_NOT_SUPPORTED Selected PHY is not supported on this target.
* - ESP_ERR_INVALID_ARG Invalid input argument.
*/ */
esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_ret); esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_ret);

View File

@ -17,3 +17,21 @@ components/usb/test_apps:
- components/soc/include/soc/usb*.h - components/soc/include/soc/usb*.h
- components/soc/esp32*/include/soc/usb_dwc_*.h - components/soc/esp32*/include/soc/usb_dwc_*.h
- components/soc/esp32*/include/soc/usb_wrap_*.h - components/soc/esp32*/include/soc/usb_wrap_*.h
components/usb/test_apps/phy:
enable:
- if: SOC_USB_OTG_SUPPORTED == 1
disable_test:
- if: IDF_TARGET in ["esp32p4"]
temporary: true
reason: ESP32-P4 PHY driver not yet migrated
depends_components:
- usb
depends_filepatterns:
- components/hal/usb*.c
- components/hal/include/hal/usb*.h
- components/hal/esp32*/include/hal/usb*.h
- components/soc/esp32*/usb*.c
- components/soc/include/soc/usb*.h
- components/soc/esp32*/include/soc/usb_dwc_*.h
- components/soc/esp32*/include/soc/usb_wrap_*.h

View File

@ -0,0 +1,9 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
set(COMPONENTS main)
project(test_app_usb_phy)

View File

@ -0,0 +1,4 @@
| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- |
# USB: PHY sanity checks

View File

@ -0,0 +1,6 @@
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
REQUIRES usb unity
WHOLE_ARCHIVE)

View File

@ -0,0 +1,180 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils_memory.h"
#include "esp_private/usb_phy.h"
#include "hal/usb_wrap_ll.h" // For USB_WRAP_LL_EXT_PHY_SUPPORTED symbol
#include "soc/soc_caps.h" // For SOC_USB_UTMI_PHY_NUM symbol
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
#define EXT_PHY_SUPPORTED 1
#else
#define EXT_PHY_SUPPORTED 0
#endif
#if SOC_USB_UTMI_PHY_NUM > 0
#define UTMI_PHY_SUPPORTED 1
#else
#define UTMI_PHY_SUPPORTED 0
#endif
void setUp(void)
{
unity_utils_record_free_mem();
}
void tearDown(void)
{
unity_utils_evaluate_leaks();
}
void app_main(void)
{
// ____ ___ ___________________ __ __
// | | \/ _____/\______ \ _/ |_ ____ _______/ |_
// | | /\_____ \ | | _/ \ __\/ __ \ / ___/\ __\.
// | | / / \ | | \ | | \ ___/ \___ \ | |
// |______/ /_______ / |______ / |__| \___ >____ > |__|
// \/ \/ \/ \/
printf(" ____ ___ ___________________ __ __ \r\n");
printf("| | \\/ _____/\\______ \\ _/ |_ ____ _______/ |_ \r\n");
printf("| | /\\_____ \\ | | _/ \\ __\\/ __ \\ / ___/\\ __\\\r\n");
printf("| | / / \\ | | \\ | | \\ ___/ \\___ \\ | | \r\n");
printf("|______/ /_______ / |______ / |__| \\___ >____ > |__| \r\n");
printf(" \\/ \\/ \\/ \\/ \r\n");
unity_utils_setup_heap_record(80);
unity_utils_set_leak_level(128);
unity_run_menu();
}
/**
* Test init and deinit of internal FSLS PHY
*/
TEST_CASE("Init internal FSLS PHY", "[phy]")
{
usb_phy_handle_t phy_handle = NULL;
const usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_INT,
.otg_mode = USB_OTG_MODE_HOST,
.otg_speed = USB_PHY_SPEED_UNDEFINED,
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
TEST_ASSERT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NOT_NULL(phy_handle);
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_handle));
}
/**
* Test init and deinit of external FSLS PHY
*/
TEST_CASE("Init external FSLS PHY", "[phy]")
{
usb_phy_handle_t phy_handle = NULL;
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_EXT,
.otg_mode = USB_OTG_MODE_HOST,
.otg_speed = USB_PHY_SPEED_UNDEFINED,
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
#if EXT_PHY_SUPPORTED
// Init ext PHY without ext_io_conf -> FAIL
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NULL(phy_handle);
// Init ext PHY with ext_io_conf -> PASS
const usb_phy_ext_io_conf_t ext_io_conf = { // Some random values
.vp_io_num = 1,
.vm_io_num = 1,
.rcv_io_num = 1,
.suspend_n_io_num = 1,
.oen_io_num = 1,
.vpo_io_num = 1,
.vmo_io_num = 1,
.fs_edge_sel_io_num = 1,
};
phy_config.ext_io_conf = &ext_io_conf;
TEST_ASSERT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NOT_NULL(phy_handle);
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_handle));
#else
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NULL(phy_handle);
#endif
}
/**
* Test init and deinit of internal UTMI PHY
*/
TEST_CASE("Init internal UTMI PHY", "[phy]")
{
usb_phy_handle_t phy_handle = NULL;
const usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_UTMI,
.otg_mode = USB_OTG_MODE_HOST,
.otg_speed = USB_PHY_SPEED_UNDEFINED,
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
#if UTMI_PHY_SUPPORTED
TEST_ASSERT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NOT_NULL(phy_handle);
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_handle));
#else
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NULL(phy_handle);
#endif
}
/**
* Test init and deinit of all PHYs at the same time
*/
TEST_CASE("Init all PHYs", "[phy]")
{
usb_phy_handle_t phy_handle = NULL;
usb_phy_handle_t phy_handle_2 = NULL;
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_INT,
.otg_mode = USB_OTG_MODE_HOST,
.otg_speed = USB_PHY_SPEED_UNDEFINED,
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
TEST_ASSERT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle));
TEST_ASSERT_NOT_NULL(phy_handle);
// Our current targets support either UTMI or external PHY
// so if/else suffice here
#if UTMI_PHY_SUPPORTED
phy_config.target = USB_PHY_TARGET_UTMI;
#else
const usb_phy_ext_io_conf_t ext_io_conf = { // Some random values
.vp_io_num = 1,
.vm_io_num = 1,
.rcv_io_num = 1,
.suspend_n_io_num = 1,
.oen_io_num = 1,
.vpo_io_num = 1,
.vmo_io_num = 1,
.fs_edge_sel_io_num = 1,
};
phy_config.target = USB_PHY_TARGET_EXT;
phy_config.ext_io_conf = &ext_io_conf;
#endif
TEST_ASSERT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_handle_2));
TEST_ASSERT_NOT_NULL(phy_handle_2);
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_handle));
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_handle_2));
}

View File

@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='P4 PHY not yet migrated')
def test_usb_phy(dut: Dut) -> None:
dut.run_all_single_board_cases(group='phy')

View File

@ -0,0 +1,8 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
# CONFIG_ESP_TASK_WDT_INIT is not set
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
# CONFIG_UNITY_ENABLE_FLOAT is not set
# CONFIG_UNITY_ENABLE_DOUBLE is not set
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -76,10 +76,10 @@ static esp_err_t phy_configure_pin_output(int gpio_pin, int signal_idx)
return ESP_OK; return ESP_OK;
} }
static esp_err_t phy_external_iopins_configure(const usb_phy_ext_io_conf_t *ext_io_conf) static esp_err_t phy_external_iopins_configure(const usb_phy_ext_io_conf_t *ext_io_conf, const usb_fsls_serial_signal_conn_t *fsls_sig)
{ {
ESP_RETURN_ON_FALSE(ext_io_conf && fsls_sig, ESP_ERR_INVALID_ARG, USBPHY_TAG, "argument is invalid");
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
const usb_fsls_serial_signal_conn_t *fsls_sig = usb_dwc_info.controllers[0].fsls_signals;
// Inputs // Inputs
ret |= phy_configure_pin_input(ext_io_conf->vp_io_num, fsls_sig->rx_dp); ret |= phy_configure_pin_input(ext_io_conf->vp_io_num, fsls_sig->rx_dp);
@ -96,10 +96,10 @@ static esp_err_t phy_external_iopins_configure(const usb_phy_ext_io_conf_t *ext_
return ret; return ret;
} }
static esp_err_t phy_otg_iopins_configure(const usb_phy_otg_io_conf_t *otg_io_conf) static esp_err_t phy_otg_iopins_configure(const usb_phy_otg_io_conf_t *otg_io_conf, const usb_otg_signal_conn_t *otg_sig)
{ {
ESP_RETURN_ON_FALSE(otg_io_conf && otg_sig, ESP_ERR_INVALID_ARG, USBPHY_TAG, "argument is invalid");
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
const usb_otg_signal_conn_t *otg_sig = usb_dwc_info.controllers[0].otg_signals;
// Inputs // Inputs
ret |= phy_configure_pin_input(otg_io_conf->iddig_io_num, otg_sig->iddig); ret |= phy_configure_pin_input(otg_io_conf->iddig_io_num, otg_sig->iddig);
@ -126,11 +126,13 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
ESP_RETURN_ON_FALSE(handle->controller == USB_PHY_CTRL_OTG, ESP_FAIL, USBPHY_TAG, "phy source is not USB_OTG"); ESP_RETURN_ON_FALSE(handle->controller == USB_PHY_CTRL_OTG, ESP_FAIL, USBPHY_TAG, "phy source is not USB_OTG");
handle->otg_mode = mode; handle->otg_mode = mode;
const usb_otg_signal_conn_t *otg_sig = usb_dwc_info.controllers[0].otg_signals;
assert(otg_sig);
if (mode == USB_OTG_MODE_HOST) { if (mode == USB_OTG_MODE_HOST) {
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is A side esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, otg_sig->iddig, false); // connected connector is A side
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_SRP_BVALID_IN_IDX, false); esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, otg_sig->bvalid, false);
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from host esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, otg_sig->vbusvalid, false); // receiving a valid Vbus from host
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_AVALID_IN_IDX, false); // HIGH to force USB host mode esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, otg_sig->avalid, false);
if (handle->target == USB_PHY_TARGET_INT) { if (handle->target == USB_PHY_TARGET_INT) {
// Configure pull resistors for host // Configure pull resistors for host
usb_wrap_pull_override_vals_t vals = { usb_wrap_pull_override_vals_t vals = {
@ -142,10 +144,10 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
usb_wrap_hal_phy_enable_pull_override(&handle->wrap_hal, &vals); usb_wrap_hal_phy_enable_pull_override(&handle->wrap_hal, &vals);
} }
} else if (mode == USB_OTG_MODE_DEVICE) { } else if (mode == USB_OTG_MODE_DEVICE) {
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is mini-B side esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, otg_sig->iddig, false); // connected connector is mini-B side
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_SRP_BVALID_IN_IDX, false); // HIGH to force USB device mode esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, otg_sig->bvalid, false); // HIGH to force USB device mode
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from device esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, otg_sig->vbusvalid, false); // receiving a valid Vbus from device
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_OTG_AVALID_IN_IDX, false); esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, otg_sig->avalid, false);
} }
return ESP_OK; return ESP_OK;
@ -185,6 +187,9 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
ESP_ERR_INVALID_ARG, USBPHY_TAG, "wrong target for the action"); ESP_ERR_INVALID_ARG, USBPHY_TAG, "wrong target for the action");
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
const usb_fsls_serial_signal_conn_t *fsls_sig = usb_dwc_info.controllers[0].fsls_signals;
assert(fsls_sig);
switch (action) { switch (action) {
case USB_PHY_ACTION_HOST_ALLOW_CONN: case USB_PHY_ACTION_HOST_ALLOW_CONN:
if (handle->target == USB_PHY_TARGET_INT) { if (handle->target == USB_PHY_TARGET_INT) {
@ -198,8 +203,8 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
/* /*
Allow for connections on the external PHY by connecting the VP and VM signals to the external PHY. Allow for connections on the external PHY by connecting the VP and VM signals to the external PHY.
*/ */
esp_rom_gpio_connect_in_signal(handle->iopins->vp_io_num, USB_EXTPHY_VP_IDX, false); esp_rom_gpio_connect_in_signal(handle->iopins->vp_io_num, fsls_sig->rx_dp, false);
esp_rom_gpio_connect_in_signal(handle->iopins->vm_io_num, USB_EXTPHY_VM_IDX, false); esp_rom_gpio_connect_in_signal(handle->iopins->vm_io_num, fsls_sig->rx_dm, false);
} }
break; break;
@ -224,8 +229,8 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
/* /*
Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal. Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal.
*/ */
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_EXTPHY_VP_IDX, false); esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, fsls_sig->rx_dp, false);
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_EXTPHY_VM_IDX, false); esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, fsls_sig->rx_dm, false);
} }
break; break;
@ -272,6 +277,13 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, USBPHY_TAG, "config argument is invalid"); ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, USBPHY_TAG, "config argument is invalid");
ESP_RETURN_ON_FALSE(config->target < USB_PHY_TARGET_MAX, ESP_ERR_INVALID_ARG, USBPHY_TAG, "specified PHY argument is invalid"); ESP_RETURN_ON_FALSE(config->target < USB_PHY_TARGET_MAX, ESP_ERR_INVALID_ARG, USBPHY_TAG, "specified PHY argument is invalid");
ESP_RETURN_ON_FALSE(config->controller < USB_PHY_CTRL_MAX, ESP_ERR_INVALID_ARG, USBPHY_TAG, "specified source argument is invalid"); ESP_RETURN_ON_FALSE(config->controller < USB_PHY_CTRL_MAX, ESP_ERR_INVALID_ARG, USBPHY_TAG, "specified source argument is invalid");
ESP_RETURN_ON_FALSE(config->target != USB_PHY_TARGET_EXT || config->ext_io_conf, ESP_ERR_INVALID_ARG, USBPHY_TAG, "ext_io_conf must be provided for ext PHY");
#if !USB_WRAP_LL_EXT_PHY_SUPPORTED
ESP_RETURN_ON_FALSE(config->target != USB_PHY_TARGET_EXT, ESP_ERR_NOT_SUPPORTED, USBPHY_TAG, "Ext PHY not supported on this target");
#endif
#if !SOC_USB_UTMI_PHY_NUM
ESP_RETURN_ON_FALSE(config->target != USB_PHY_TARGET_UTMI, ESP_ERR_NOT_SUPPORTED, USBPHY_TAG, "UTMI PHY not supported on this target");
#endif
ESP_RETURN_ON_ERROR(usb_phy_install(), USBPHY_TAG, "usb_phy driver installation failed"); ESP_RETURN_ON_ERROR(usb_phy_install(), USBPHY_TAG, "usb_phy driver installation failed");
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
@ -316,7 +328,8 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
phy_context->iopins = (usb_phy_ext_io_conf_t *) calloc(1, sizeof(usb_phy_ext_io_conf_t)); phy_context->iopins = (usb_phy_ext_io_conf_t *) calloc(1, sizeof(usb_phy_ext_io_conf_t));
ESP_GOTO_ON_FALSE(phy_context->iopins, ESP_ERR_NO_MEM, cleanup, USBPHY_TAG, "no mem for storing I/O pins"); ESP_GOTO_ON_FALSE(phy_context->iopins, ESP_ERR_NO_MEM, cleanup, USBPHY_TAG, "no mem for storing I/O pins");
memcpy(phy_context->iopins, config->ext_io_conf, sizeof(usb_phy_ext_io_conf_t)); memcpy(phy_context->iopins, config->ext_io_conf, sizeof(usb_phy_ext_io_conf_t));
ESP_ERROR_CHECK(phy_external_iopins_configure(phy_context->iopins)); const usb_fsls_serial_signal_conn_t *fsls_sig = usb_dwc_info.controllers[0].fsls_signals;
ESP_ERROR_CHECK(phy_external_iopins_configure(phy_context->iopins, fsls_sig));
} }
if (config->otg_mode != USB_PHY_MODE_DEFAULT) { if (config->otg_mode != USB_PHY_MODE_DEFAULT) {
ESP_ERROR_CHECK(usb_phy_otg_set_mode(*handle_ret, config->otg_mode)); ESP_ERROR_CHECK(usb_phy_otg_set_mode(*handle_ret, config->otg_mode));
@ -325,7 +338,8 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
ESP_ERROR_CHECK(usb_phy_otg_dev_set_speed(*handle_ret, config->otg_speed)); ESP_ERROR_CHECK(usb_phy_otg_dev_set_speed(*handle_ret, config->otg_speed));
} }
if (config->otg_io_conf && (phy_context->controller == USB_PHY_CTRL_OTG)) { if (config->otg_io_conf && (phy_context->controller == USB_PHY_CTRL_OTG)) {
ESP_ERROR_CHECK(phy_otg_iopins_configure(config->otg_io_conf)); const usb_otg_signal_conn_t *otg_sig = usb_dwc_info.controllers[0].otg_signals;
ESP_ERROR_CHECK(phy_otg_iopins_configure(config->otg_io_conf, otg_sig));
} }
return ESP_OK; return ESP_OK;