From ed1f20a9727ec6d56534e38daedaf40688e4a266 Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Mon, 22 Jan 2024 12:14:11 +0100 Subject: [PATCH] feat(hal/usb): Add HS PHY configuration --- components/hal/include/hal/usb_dwc_ll.h | 25 +++++++++++++++++++++---- components/hal/usb_dwc_hal.c | 15 ++++++++++++++- components/usb/hcd_dwc.c | 12 ++++++++++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/components/hal/include/hal/usb_dwc_ll.h b/components/hal/include/hal/usb_dwc_ll.h index e52e3bfa0f..44c7fca824 100644 --- a/components/hal/include/hal/usb_dwc_ll.h +++ b/components/hal/include/hal/usb_dwc_ll.h @@ -217,6 +217,20 @@ static inline void usb_dwc_ll_gusbcfg_dis_srp_cap(usb_dwc_dev_t *hw) hw->gusbcfg_reg.srpcap = 0; } +static inline void usb_dwc_ll_gusbcfg_set_timeout_cal(usb_dwc_dev_t *hw, uint8_t tout_cal) +{ + hw->gusbcfg_reg.toutcal = tout_cal; +} + +#if (OTG_HSPHY_INTERFACE != 0) +static inline void usb_dwc_ll_gusbcfg_set_utmi_phy(usb_dwc_dev_t *hw) +{ + hw->gusbcfg_reg.phyif = 1; // 16 bits interface + hw->gusbcfg_reg.ulpiutmisel = 0; // UTMI+ + hw->gusbcfg_reg.physel = 0; // HS PHY +} +#endif // (OTG_HSPHY_INTERFACE != 0) + // --------------------------- GRSTCTL Register -------------------------------- static inline bool usb_dwc_ll_grstctl_is_ahb_idle(usb_dwc_dev_t *hw) @@ -431,19 +445,20 @@ static inline void usb_dwc_ll_hcfg_set_fsls_pclk_sel(usb_dwc_dev_t *hw) /** * @brief Sets some default values to HCFG to operate in Host mode with scatter/gather DMA * - * @param hw Start address of the DWC_OTG registers - * @param speed Speed to initialize the host port at + * @param[in] hw Start address of the DWC_OTG registers + * @param[in] speed Speed to initialize the host port at */ static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed_t speed) { hw->hcfg_reg.descdma = 1; //Enable scatt/gatt - hw->hcfg_reg.fslssupp = 1; //FS/LS support only +#if (OTG_HSPHY_INTERFACE == 0) /* Indicate to the OTG core what speed the PHY clock is at - Note: It seems like our PHY has an implicit 8 divider applied when in LS mode, + Note: It seems like S2/S3 PHY has an implicit 8 divider applied when in LS mode, so the values of FSLSPclkSel and FrInt have to be adjusted accordingly. */ hw->hcfg_reg.fslspclksel = (speed == USB_DWC_SPEED_FULL) ? 1 : 2; //PHY clock on esp32-sx for FS/LS-only +#endif // (OTG_HSPHY_INTERFACE == 0) hw->hcfg_reg.perschedena = 0; //Disable perio sched } @@ -451,6 +466,7 @@ static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed_t speed) { +#if (OTG_HSPHY_INTERFACE == 0) usb_dwc_hfir_reg_t hfir; hfir.val = hw->hfir_reg.val; hfir.hfirrldctrl = 0; //Disable dynamic loading @@ -461,6 +477,7 @@ static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed */ hfir.frint = (speed == USB_DWC_SPEED_FULL) ? 48000 : 6000; //esp32-sx targets only support FS or LS hw->hfir_reg.val = hfir.val; +#endif // (OTG_HSPHY_INTERFACE == 0) } // ----------------------------- HFNUM Register -------------------------------- diff --git a/components/hal/usb_dwc_hal.c b/components/hal/usb_dwc_hal.c index 300fd6c263..7cc4ae7f83 100644 --- a/components/hal/usb_dwc_hal.c +++ b/components/hal/usb_dwc_hal.c @@ -9,6 +9,7 @@ #include #include "sdkconfig.h" #include "soc/chip_revision.h" +#include "soc/usb_dwc_cfg.h" #include "hal/usb_dwc_hal.h" #include "hal/usb_dwc_ll.h" #include "hal/efuse_hal.h" @@ -16,6 +17,14 @@ // ------------------------------------------------ Macros and Types --------------------------------------------------- +// TODO: Remove target specific section after support for multiple USB peripherals is implemented +#include "sdkconfig.h" +#if (CONFIG_IDF_TARGET_ESP32P4) +#define USB_BASE USB_DWC_HS +#else +#define USB_BASE USB_DWC +#endif + // ---------------------- Constants ------------------------ #define BENDPOINTADDRESS_NUM_MSK 0x0F //Endpoint number mask of the bEndpointAddress field of an endpoint descriptor @@ -108,6 +117,10 @@ static void set_defaults(usb_dwc_hal_context_t *hal) //GUSBCFG register usb_dwc_ll_gusbcfg_dis_hnp_cap(hal->dev); //Disable HNP usb_dwc_ll_gusbcfg_dis_srp_cap(hal->dev); //Disable SRP +#if (OTG_HSPHY_INTERFACE != 0) + usb_dwc_ll_gusbcfg_set_timeout_cal(hal->dev, 5); // 5 PHY clocks for our HS PHY + usb_dwc_ll_gusbcfg_set_utmi_phy(hal->dev); +#endif // (OTG_HSPHY_INTERFACE != 0) //Enable interruts usb_dwc_ll_gintmsk_dis_intrs(hal->dev, 0xFFFFFFFF); //Mask all interrupts first usb_dwc_ll_gintmsk_en_intrs(hal->dev, CORE_INTRS_EN_MSK); //Unmask global interrupts @@ -120,7 +133,7 @@ static void set_defaults(usb_dwc_hal_context_t *hal) void usb_dwc_hal_init(usb_dwc_hal_context_t *hal) { //Check if a peripheral is alive by reading the core ID registers - usb_dwc_dev_t *dev = &USB_DWC; + usb_dwc_dev_t *dev = &USB_BASE; uint32_t core_id = usb_dwc_ll_gsnpsid_get_id(dev); HAL_ASSERT(core_id == CORE_REG_GSNPSID); (void) core_id; //Suppress unused variable warning if asserts are disabled diff --git a/components/usb/hcd_dwc.c b/components/usb/hcd_dwc.c index aa22b31a5a..f529ff1b3e 100644 --- a/components/usb/hcd_dwc.c +++ b/components/usb/hcd_dwc.c @@ -30,6 +30,15 @@ // ----------------------------------------------------- Macros -------------------------------------------------------- +// ------------------ Target specific ---------------------- +// TODO: Remove target specific section after support for multiple USB peripherals is implemented +#include "sdkconfig.h" +#if (CONFIG_IDF_TARGET_ESP32P4) +#define USB_INTR ETS_USB_OTG_INTR_SOURCE +#else +#define USB_INTR ETS_USB_INTR_SOURCE +#endif + // --------------------- Constants ------------------------- #define INIT_DELAY_MS 30 // A delay of at least 25ms to enter Host mode. Make it 30ms to be safe @@ -1088,7 +1097,7 @@ esp_err_t hcd_install(const hcd_config_t *config) goto port_alloc_err; } // Allocate interrupt - err_ret = esp_intr_alloc(ETS_USB_INTR_SOURCE, + err_ret = esp_intr_alloc(USB_INTR, config->intr_flags | ESP_INTR_FLAG_INTRDISABLED, // The interrupt must be disabled until the port is initialized intr_hdlr_main, (void *)p_hcd_obj_dmy->port_obj, @@ -1096,7 +1105,6 @@ esp_err_t hcd_install(const hcd_config_t *config) if (err_ret != ESP_OK) { goto intr_alloc_err; } - // Assign the HCD_ENTER_CRITICAL(); if (s_hcd_obj != NULL) { HCD_EXIT_CRITICAL();