From 660e8b8c887091e17323c361f25e804a5d06d6df Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Oct 2021 16:08:19 +0700 Subject: [PATCH] skip snpsid check for gd32, abstract phyfs turnaround, set max timeout calibration. still has issue with gd32 with msc (does work with running with rtt as log). --- src/common/tusb_common.h | 3 + src/portable/synopsys/dwc2/dcd_dwc2.c | 193 ++++++++++++------------ src/portable/synopsys/dwc2/dwc2_bcm.h | 7 +- src/portable/synopsys/dwc2/dwc2_esp32.h | 8 +- src/portable/synopsys/dwc2/dwc2_gd32.h | 8 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 57 +++---- src/portable/synopsys/dwc2/dwc2_type.h | 13 +- 7 files changed, 143 insertions(+), 146 deletions(-) diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index e62bcde12..9b9e2b007 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -111,6 +111,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t ui32) { return (uint16_t) (ui32 >> 16); } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t ui32) { return (uint16_t) (ui32 & 0x0000ffffu); } + TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); } diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ce9b58e03..aad7e45cc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -54,16 +54,8 @@ #define DWC2_REG(_port) ((dwc2_regs_t*) DWC2_REG_BASE) -enum -{ - DCD_HIGH_SPEED = 0, // Highspeed mode - DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) - DCD_FULL_SPEED = 3, // Full speed with internal PHY -}; - -// PHYSEL, ULPISEL -// UTMI internal HS PHY -// ULPI external HS PHY +// Debug level for DWC2 +#define DWC2_DEBUG 1 static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; @@ -261,71 +253,73 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ +#if CFG_TUSB_DEBUG >= DWC2_DEBUG void print_dwc2_info(dwc2_regs_t * dwc2) { dwc2_ghwcfg2_t const * hw_cfg2 = &dwc2->ghwcfg2_bm; dwc2_ghwcfg3_t const * hw_cfg3 = &dwc2->ghwcfg3_bm; dwc2_ghwcfg4_t const * hw_cfg4 = &dwc2->ghwcfg4_bm; - TU_LOG_HEX(1, dwc2->guid); - TU_LOG_HEX(1, dwc2->gsnpsid); - TU_LOG_HEX(1, dwc2->ghwcfg1); + TU_LOG_HEX(DWC2_DEBUG, dwc2->guid); + TU_LOG_HEX(DWC2_DEBUG, dwc2->gsnpsid); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg1); // HW configure 2 - TU_LOG(1, "\r\n"); - TU_LOG_HEX(1, dwc2->ghwcfg2); - TU_LOG_INT(1, hw_cfg2->op_mode ); - TU_LOG_INT(1, hw_cfg2->arch ); - TU_LOG_INT(1, hw_cfg2->point2point ); - TU_LOG_INT(1, hw_cfg2->hs_phy_type ); - TU_LOG_INT(1, hw_cfg2->fs_phy_type ); - TU_LOG_INT(1, hw_cfg2->num_dev_ep ); - TU_LOG_INT(1, hw_cfg2->num_host_ch ); - TU_LOG_INT(1, hw_cfg2->period_channel_support ); - TU_LOG_INT(1, hw_cfg2->enable_dynamic_fifo ); - TU_LOG_INT(1, hw_cfg2->mul_cpu_int ); - TU_LOG_INT(1, hw_cfg2->nperiod_tx_q_depth ); - TU_LOG_INT(1, hw_cfg2->host_period_tx_q_depth ); - TU_LOG_INT(1, hw_cfg2->dev_token_q_depth ); - TU_LOG_INT(1, hw_cfg2->otg_enable_ic_usb ); + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg2); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->op_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->arch ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->point2point ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->hs_phy_type ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->fs_phy_type ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_dev_ep ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_host_ch ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->period_channel_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->enable_dynamic_fifo ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->mul_cpu_int ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->nperiod_tx_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->host_period_tx_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->dev_token_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->otg_enable_ic_usb ); // HW configure 3 - TU_LOG(1, "\r\n"); - TU_LOG_HEX(1, dwc2->ghwcfg3); - TU_LOG_INT(1, hw_cfg3->xfer_size_width ); - TU_LOG_INT(1, hw_cfg3->packet_size_width ); - TU_LOG_INT(1, hw_cfg3->otg_enable ); - TU_LOG_INT(1, hw_cfg3->i2c_enable ); - TU_LOG_INT(1, hw_cfg3->vendor_ctrl_itf ); - TU_LOG_INT(1, hw_cfg3->optional_feature_removed ); - TU_LOG_INT(1, hw_cfg3->synch_reset ); - TU_LOG_INT(1, hw_cfg3->otg_adp_support ); - TU_LOG_INT(1, hw_cfg3->otg_enable_hsic ); - TU_LOG_INT(1, hw_cfg3->battery_charger_support ); - TU_LOG_INT(1, hw_cfg3->lpm_mode ); - TU_LOG_INT(1, hw_cfg3->total_fifo_size ); + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg3); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->xfer_size_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->packet_size_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->i2c_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->vendor_ctrl_itf ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->optional_feature_removed ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->synch_reset ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_adp_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable_hsic ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->battery_charger_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->lpm_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->total_fifo_size ); // HW configure 4 - TU_LOG(1, "\r\n"); - TU_LOG_HEX(1, dwc2->ghwcfg4); - TU_LOG_INT(1, hw_cfg4->num_dev_period_in_ep ); - TU_LOG_INT(1, hw_cfg4->power_optimized ); - TU_LOG_INT(1, hw_cfg4->ahb_freq_min ); - TU_LOG_INT(1, hw_cfg4->hibernation ); - TU_LOG_INT(1, hw_cfg4->service_interval_mode ); - TU_LOG_INT(1, hw_cfg4->ipg_isoc_en ); - TU_LOG_INT(1, hw_cfg4->acg_enable ); - TU_LOG_INT(1, hw_cfg4->utmi_phy_data_width ); - TU_LOG_INT(1, hw_cfg4->dev_ctrl_ep_num ); - TU_LOG_INT(1, hw_cfg4->iddg_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->vbus_valid_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->a_valid_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->b_valid_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->dedicated_fifos ); - TU_LOG_INT(1, hw_cfg4->num_dev_in_eps ); - TU_LOG_INT(1, hw_cfg4->dma_desc_enable ); - TU_LOG_INT(1, hw_cfg4->dma_dynamic ); + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg4); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_period_in_ep ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->power_optimized ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ahb_freq_min ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->hibernation ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->service_interval_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ipg_isoc_en ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->acg_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->utmi_phy_data_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dev_ctrl_ep_num ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->iddg_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->vbus_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->a_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->b_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dedicated_fifos ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_in_eps ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_desc_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_dynamic ); } +#endif static void reset_core(dwc2_regs_t * dwc2) { @@ -342,14 +336,15 @@ static void reset_core(dwc2_regs_t * dwc2) // wait for device mode ? } -static bool has_hs_phy(dwc2_regs_t * dwc2) +static bool phy_hs_supported(dwc2_regs_t * dwc2) { + // note: esp32 incorrect report its hs_phy_type as utmi return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; } static void phy_fs_init(dwc2_regs_t * dwc2) { - TU_LOG1("Fullspeed PHY init\r\n"); + TU_LOG(DWC2_DEBUG, "Fullspeed PHY init\r\n"); // Select FS PHY dwc2->gusbcfg |= GUSBCFG_PHYSEL; @@ -358,11 +353,11 @@ static void phy_fs_init(dwc2_regs_t * dwc2) reset_core(dwc2); // set turn around - // The values above are calculated for the minimum AHB frequency of 30 MHz. USB turnaround - // time is critical for certification where long cables and 5-Hubs are used, so if - // you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, + // USB turnaround time is critical for certification where long cables and 5-Hubs are used. + // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, // these bits can be programmed to a larger value. - dwc2_set_turnaround(dwc2, TUSB_SPEED_FULL); + //TU_LOG_INT(DWC2_DEBUG, (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) >> GUSBCFG_TRDT_Pos ); + dwc2_phyfs_set_turnaround(dwc2); // set max speed dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); @@ -382,7 +377,7 @@ static void phy_hs_init(dwc2_regs_t * dwc2) if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { - TU_LOG1("Highspeed ULPI PHY init\r\n"); + TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; @@ -397,7 +392,7 @@ static void phy_hs_init(dwc2_regs_t * dwc2) gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); }else { - TU_LOG1("Highspeed UTMI+ PHY init\r\n"); + TU_LOG(DWC2_DEBUG, "Highspeed UTMI+ PHY init\r\n"); // Select UTMI+ with 8-bit interface gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); @@ -422,11 +417,8 @@ static void phy_hs_init(dwc2_regs_t * dwc2) reset_core(dwc2); // Set turn-around, must after core reset otherwise it will be clear - // 9 if UTMI interface is 8-bit, 5 if 16-bit - // The values above are calculated for the minimum AHB frequency of 30 MHz. USB turnaround - // time is critical for certification where long cables and 5-Hubs are used, so if - // you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, - // these bits can be programmed to a larger value. + // - 9 if using 8-bit PHY interface + // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // Apply config @@ -435,31 +427,45 @@ static void phy_hs_init(dwc2_regs_t * dwc2) dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_HS << DCFG_DSPD_Pos); } +static bool check_dwc2(dwc2_regs_t * dwc2) +{ + // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) +#if !TU_CHECK_MCU(OPT_MCU_GD32VF103) + uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; + TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID); +#endif + +#if CFG_TUSB_DEBUG >= DWC2_DEBUG + print_dwc2_info(dwc2); +#endif + + return true; +} + void dcd_init (uint8_t rhport) { // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. dwc2_regs_t * dwc2 = DWC2_REG(rhport); - // Check Synopsys ID, failed if controller is not enabled - uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; - TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID, ); - - print_dwc2_info(dwc2); + // Check Synopsys ID register, failed if controller clock/power is not enabled + TU_VERIFY(check_dwc2(dwc2), ); // Force device mode dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; - if( !has_hs_phy(dwc2) ) - { - // core does not support highspeed or hs-phy is not present - phy_fs_init(dwc2); - }else + if( phy_hs_supported(dwc2) ) { // Highspeed phy_hs_init(dwc2); + }else + { + // core does not support highspeed or hs-phy is not present + phy_fs_init(dwc2); } + TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg); + /* Set HS/FS Timeout Calibration to 7 (max available value). * The number of PHY clocks that the application programs in * this field is added to the high/full speed interpacket timeout @@ -468,7 +474,7 @@ void dcd_init (uint8_t rhport) * introduced by the PHY in generating the linestate condition * can vary from one PHY to another. */ - // dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); + dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); // Restart PHY clock dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE); @@ -617,7 +623,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) _allocated_fifo_words_tx += fifo_size; - TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4); + TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4); // DIEPTXF starts at FIFO #1. // Both TXFD and TXSA are in unit of 32-bit words. @@ -1110,14 +1116,15 @@ void dcd_int_handler(uint8_t rhport) speed = TUSB_SPEED_HIGH; break; - case DSTS_ENUMSPD_FS_HSPHY: - case DSTS_ENUMSPD_FS: - speed = TUSB_SPEED_FULL; - break; - case DSTS_ENUMSPD_LS: speed = TUSB_SPEED_LOW; break; + + case DSTS_ENUMSPD_FS_HSPHY: + case DSTS_ENUMSPD_FS: + default: + speed = TUSB_SPEED_FULL; + break; } dcd_event_bus_reset(rhport, speed, true); @@ -1204,7 +1211,7 @@ void dcd_int_handler(uint8_t rhport) // // Check for Incomplete isochronous IN transfer // if(int_status & GINTSTS_IISOIXFR) { // printf(" IISOIXFR!\r\n"); - //// TU_LOG2(" IISOIXFR!\r\n"); + //// TU_LOG(DWC2_DEBUG, " IISOIXFR!\r\n"); // } } diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index da1f23ae0..c064946cf 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -58,11 +58,10 @@ static inline void dwc2_remote_wakeup_delay(void) // TODO implement later } -static inline void dwc2_set_turnaround(dwc2_regs_t * core, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - // TODO implement later - (void) core; - (void) speed; + (void) dwc2; + // do nothing since bcm alwyas use HS PHY } #ifdef __cplusplus diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index b8a040041..af5d5f093 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -67,12 +67,10 @@ static inline void dwc2_remote_wakeup_delay(void) vTaskDelay(pdMS_TO_TICKS(1)); } -static inline void dwc2_set_turnaround(dwc2_regs_t * core, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - (void) core; - (void) speed; - - // keep the reset value + (void) dwc2; + // keep the reset value which is 5 on this port } #ifdef __cplusplus diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h index de3ccb3b0..15e73ad1e 100644 --- a/src/portable/synopsys/dwc2/dwc2_gd32.h +++ b/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -76,12 +76,10 @@ static inline void dwc2_remote_wakeup_delay(void) while ( count-- ) __asm volatile ("nop"); } -static inline void dwc2_set_turnaround(dwc2_regs_t * core, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - (void) core; - (void) speed; - - // keep the reset value + // use recommeded value 6 by stm32 for mcu with AHB clock > 32Mhz + dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (6u << GUSBCFG_TRDT_Pos); } diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index b77cda2ca..4d0ed3f0a 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -113,44 +113,33 @@ static inline void dwc2_remote_wakeup_delay(void) } // Set turn-around timeout according to link speed -static inline void dwc2_set_turnaround(dwc2_regs_t * dwc2, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - dwc2->gusbcfg &= ~GUSBCFG_TRDT; + // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual + uint32_t turnaround; - if ( speed == TUSB_SPEED_HIGH ) - { - // Use fixed 0x09 for Highspeed - dwc2->gusbcfg |= (0x09 << GUSBCFG_TRDT_Pos); - } + if ( SystemCoreClock >= 32000000U ) + turnaround = 0x6u; + else if ( SystemCoreClock >= 27500000U ) + turnaround = 0x7u; + else if ( SystemCoreClock >= 24000000U ) + turnaround = 0x8u; + else if ( SystemCoreClock >= 21800000U ) + turnaround = 0x9u; + else if ( SystemCoreClock >= 20000000U ) + turnaround = 0xAu; + else if ( SystemCoreClock >= 18500000U ) + turnaround = 0xBu; + else if ( SystemCoreClock >= 17200000U ) + turnaround = 0xCu; + else if ( SystemCoreClock >= 16000000U ) + turnaround = 0xDu; + else if ( SystemCoreClock >= 15000000U ) + turnaround = 0xEu; else - { - // Turnaround timeout depends on the MCU clock - uint32_t turnaround; + turnaround = 0xFu; - if ( SystemCoreClock >= 32000000U ) - turnaround = 0x6U; - else if ( SystemCoreClock >= 27500000U ) - turnaround = 0x7U; - else if ( SystemCoreClock >= 24000000U ) - turnaround = 0x8U; - else if ( SystemCoreClock >= 21800000U ) - turnaround = 0x9U; - else if ( SystemCoreClock >= 20000000U ) - turnaround = 0xAU; - else if ( SystemCoreClock >= 18500000U ) - turnaround = 0xBU; - else if ( SystemCoreClock >= 17200000U ) - turnaround = 0xCU; - else if ( SystemCoreClock >= 16000000U ) - turnaround = 0xDU; - else if ( SystemCoreClock >= 15000000U ) - turnaround = 0xEU; - else - turnaround = 0xFU; - - // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz - dwc2->gusbcfg |= (turnaround << GUSBCFG_TRDT_Pos); - } + dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos); } #if defined(USB_HS_PHYC) diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 7e472310f..7b3db4dd9 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -59,12 +59,19 @@ typedef struct #endif enum { - HS_PHY_TYPE_NONE = 0 , + HS_PHY_TYPE_NONE = 0 , // not supported HS_PHY_TYPE_UTMI , // internal PHY (mostly) HS_PHY_TYPE_ULPI , // external PHY HS_PHY_TYPE_UTMI_ULPI , }; +enum { + FS_PHY_TYPE_NONE = 0, // not supported + FS_PHY_TYPE_DEDICATED, + FS_PHY_TYPE_UTMI, + FS_PHY_TYPE_ULPI, +}; + typedef struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP @@ -531,10 +538,6 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GUSBCFG_TRDT_Pos (10U) #define GUSBCFG_TRDT_Msk (0xFUL << GUSBCFG_TRDT_Pos) // 0x00003C00 */ #define GUSBCFG_TRDT GUSBCFG_TRDT_Msk // USB turnaround time */ -#define GUSBCFG_TRDT_0 (0x1UL << GUSBCFG_TRDT_Pos) // 0x00000400 */ -#define GUSBCFG_TRDT_1 (0x2UL << GUSBCFG_TRDT_Pos) // 0x00000800 */ -#define GUSBCFG_TRDT_2 (0x4UL << GUSBCFG_TRDT_Pos) // 0x00001000 */ -#define GUSBCFG_TRDT_3 (0x8UL << GUSBCFG_TRDT_Pos) // 0x00002000 */ #define GUSBCFG_PHYLPCS_Pos (15U) #define GUSBCFG_PHYLPCS_Msk (0x1UL << GUSBCFG_PHYLPCS_Pos) // 0x00008000 */ #define GUSBCFG_PHYLPCS GUSBCFG_PHYLPCS_Msk // PHY Low-power clock select */