esp-idf/components/hal/usb_wrap_hal.c

106 wiersze
3.3 KiB
C

/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc_caps.h"
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "hal/usb_serial_jtag_ll.h"
#endif
#include "hal/usb_wrap_ll.h"
#include "hal/usb_wrap_hal.h"
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal)
{
hal->wrap_dev = &USB_WRAP;
#if SOC_USB_SERIAL_JTAG_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG;
#endif
#if !USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_wrap_ll_phy_set_defaults(hal->wrap_dev);
#endif
}
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_wrap_ll_phy_enable_external(hal->wrap_dev, true);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_wrap_ll_phy_enable_external(hal->wrap_dev, false);
usb_wrap_ll_phy_enable_pad(hal->wrap_dev, true);
}
}
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
#if SOC_USB_SERIAL_JTAG_SUPPORTED
void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_serial_jtag_ll_phy_enable_external(true); // USJ uses external PHY
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_serial_jtag_ll_phy_enable_external(false); // USJ uses internal PHY
usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads
}
}
#endif
void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal)
{
// HOST - upstream: dp_pd = 1, dm_pd = 1
usb_wrap_pull_override_vals_t vals = {
.dp_pu = false,
.dm_pu = false,
.dp_pd = true,
.dm_pd = true,
};
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals);
}
void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed)
{
// DEVICE - downstream
if (speed == USB_PHY_SPEED_LOW) {
// LS: dm_pu = 1
usb_wrap_pull_override_vals_t vals = {
.dp_pu = false,
.dm_pu = true,
.dp_pd = false,
.dm_pd = false,
};
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals);
} else {
// FS: dp_pu = 1
usb_wrap_pull_override_vals_t vals = {
.dp_pu = true,
.dm_pu = false,
.dm_pd = false,
.dp_pd = false,
};
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals);
}
}
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn)
{
if (disconn) {
/*
We mimic a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will:
A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection.
*/
usb_wrap_test_mode_vals_t vals = {
.tx_enable_n = true,
.tx_dp = false,
.tx_dm = false,
.rx_dp = false,
.rx_dm = false,
.rx_rcv = false,
};
usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev, &vals);
usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, true);
} else {
usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, false);
}
}