diff options
| author | Ha Thach <[email protected]> | 2026-03-05 21:47:41 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-05 21:47:41 +0700 |
| commit | 97476872aa841fcd9cd622e4082d6c57b183c67f (patch) | |
| tree | 232aca150cd4c890457b363bfcbfba9ff9a656cd /src | |
| parent | ae3864d21f2b206ae41d1d424b96fea0ac7e0dc6 (diff) | |
| parent | 75a5bedf357342762688a3fecc90739f58bbff0e (diff) | |
Merge pull request #3378 from hathach/dwc2_deinit
Add DWC2 deinit support
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/tusb_fifo.h | 10 | ||||
| -rw-r--r-- | src/device/usbd.c | 2 | ||||
| -rw-r--r-- | src/host/usbh.c | 2 | ||||
| -rw-r--r-- | src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c | 8 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dcd_dwc2.c | 6 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_at32.h | 6 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_bcm.h | 7 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_common.c | 30 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_common.h | 2 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_efm32.h | 8 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_esp32.h | 7 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_gd32.h | 7 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_nrf.h | 6 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_stm32.h | 16 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/dwc2_xmc.h | 7 | ||||
| -rw-r--r-- | src/portable/synopsys/dwc2/hcd_dwc2.c | 46 | ||||
| -rw-r--r-- | src/tusb.c | 6 |
17 files changed, 146 insertions, 30 deletions
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 86ba59059..a3829e38e 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -289,6 +289,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_empty(const tu_fifo_t *f) { return wr_idx == rd_idx; } +// Suppress IAR warning +// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement +#if defined(__ICCARM__) +#pragma diag_suppress = Pa082 +#endif + // return number of items in fifo, capped to fifo's depth TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_count(const tu_fifo_t *f) { return tu_min16(tu_ff_overflow_count(f->depth, f->wr_idx, f->rd_idx), f->depth); @@ -303,6 +309,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_remaining(const tu_fifo_t * return tu_ff_remaining_local(f->depth, f->wr_idx, f->rd_idx); } +#if defined(__ICCARM__) + #pragma diag_default=Pa082 +#endif + #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index cca4169d7..127a7bd62 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -585,7 +585,7 @@ bool tud_deinit(uint8_t rhport) { // Deinit device controller driver dcd_int_disable(rhport); dcd_disconnect(rhport); - TU_VERIFY(dcd_deinit(rhport)); + TU_ASSERT(dcd_deinit(rhport)); // Deinit class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { diff --git a/src/host/usbh.c b/src/host/usbh.c index 20791340e..33d74862f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -571,7 +571,7 @@ bool tuh_deinit(uint8_t rhport) { // deinit host controller hcd_int_disable(rhport); - hcd_deinit(rhport); + TU_ASSERT(hcd_deinit(rhport)); _usbh_data.controller_id = TUSB_INDEX_INVALID_8; // remove all devices on this rhport (hub_addr = 0, hub_port = 0) diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c index acdeccf6d..1813ef70b 100644 --- a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c @@ -223,9 +223,13 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_hcd_data, sizeof(_hcd_data)); + // Clear pending interrupts + // Normally no interrupts should be pending here since we just reset the core, + // but device mode suspend needs to cleared by WKUP flag + FSDEV_REG->ISTR = 0; + // Enable interrupts for host mode - FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SOFM | USB_CNTR_SUSPM | - USB_CNTR_WKUPM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM; + FSDEV_REG->CNTR |= USB_CNTR_DCON | USB_CNTR_CTRM | USB_CNTR_SOFM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM; // Initialize port state _hcd_data.connected = false; diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index b52646a5d..8685ec6dc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -492,6 +492,12 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; } +bool dcd_deinit(uint8_t rhport) { + dcd_disconnect(rhport); + dwc2_core_deinit(rhport); + return true; +} + void dcd_int_enable(uint8_t rhport) { dwc2_dcd_int_enable(rhport); } diff --git a/src/portable/synopsys/dwc2/dwc2_at32.h b/src/portable/synopsys/dwc2/dwc2_at32.h index 10824ae92..fa6d10c12 100644 --- a/src/portable/synopsys/dwc2/dwc2_at32.h +++ b/src/portable/synopsys/dwc2/dwc2_at32.h @@ -112,6 +112,12 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t *dwc2, uint8_ } } +// MCU specific PHY deinit, disable PHY power +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { + (void) hs_phy_type; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_PWRDWN | STM32_GCCFG_DCDEN | STM32_GCCFG_PDEN); +} + // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { (void) dwc2; diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index df6d4a852..00842bba2 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -73,6 +73,13 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) // nothing to do } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { + (void) dwc2; + (void) hs_phy_type; + // nothing to do +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 27dda44ee..33eabaeab 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -39,14 +39,11 @@ static void reset_core(dwc2_regs_t* dwc2) { while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) { } - // load gsnpsid (it is not readable after reset is asserted) - const uint32_t gsnpsid = dwc2->gsnpsid; - - // reset core - dwc2->grstctl |= GRSTCTL_CSRST; + const uint32_t gsnpsid = dwc2->gsnpsid; // preload gsnpsid which is not readable while resetting + dwc2->grstctl |= GRSTCTL_CSRST; // reset core if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { - // prior v4.20a: CSRST is self-clearing and the core clears this bit after all the necessary logic is reset in + // prior v4.20a: CSRST is self-clearing, and the core clears this bit after all the necessary logic is reset in // the core, which can take several clocks, depending on the current state of the core. Once this bit has been // cleared, the software must wait at least 3 PHY clocks before accessing the PHY domain (synchronization delay). while (dwc2->grstctl & GRSTCTL_CSRST) {} @@ -88,8 +85,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { } /* dwc2 has 2 highspeed PHYs options - * - UTMI+ is internal highspeed PHY, can be clocked at 30/60 Mhz for fullspeed or 60 Mhz for highspeed. Can be either - * 8 or 16-bit interface. + * - UTMI+ is internal highspeed PHY, can be clocked at 30 Mhz (8-bit) or 60 Mhz (16-bit). * - ULPI is external highspeed PHY, clocked at 60Mhz with 8-bit interface. * * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz @@ -247,6 +243,24 @@ bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma) { return true; } +void dwc2_core_deinit(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Disable global interrupt + dwc2->gahbcfg &= ~GAHBCFG_GINT; + + // Reset core: this also flushes FIFOs and clears all interrupt registers + reset_core(dwc2); + + // Stop PHY clock and gate HCLK for power saving (per databook chapter 14) + dwc2->pcgcctl |= PCGCCTL_STOPPCLK | PCGCCTL_GATEHCLK; + + // MCU-specific PHY deinit (disable PHY power) + const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; + const uint8_t hs_phy_type = (dwc2->gusbcfg & GUSBCFG_PHYSEL) ? GHWCFG2_HSPHY_NOT_SUPPORTED : ghwcfg2.hs_phy_type; + dwc2_phy_deinit(dwc2, hs_phy_type); +} + // void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr) { // (void) in_isr; // dwc2_regs_t * const dwc2 = DWC2_REG(rhport); diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index 1947173b2..9f28ab2e0 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -42,6 +42,7 @@ // - _dwc2_controller[]: array of controllers // - DWC2_EP_MAX: largest EP counts of all controllers // - dwc2_phy_init/dwc2_phy_update: phy init called before and after core reset +// - dwc2_phy_deinit(dwc2, hs_phy_type): phy deinit to disable PHY power, only deinit the phy used by core // - dwc2_dcd_int_enable/dwc2_dcd_int_disable // - dwc2_remote_wakeup_delay @@ -87,6 +88,7 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { // check if highspeed phy should be used bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy); bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma); +void dwc2_core_deinit(uint8_t rhport); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dwc2_efm32.h b/src/portable/synopsys/dwc2/dwc2_efm32.h index 0e3570cbb..e1cb7c769 100644 --- a/src/portable/synopsys/dwc2/dwc2_efm32.h +++ b/src/portable/synopsys/dwc2/dwc2_efm32.h @@ -72,6 +72,14 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) USB->ROUTE = USB_ROUTE_PHYPEN; } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { + (void) dwc2; + (void) hs_phy_type; + // Disable PHY pin + USB->ROUTE = 0; +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index a4e0d1770..ff9f216bd 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -121,6 +121,13 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ } +// MCU specific PHY deinit, disable PHY power +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + (void)dwc2; + (void)hs_phy_type; + // PHY managed by ESP-IDF +} + // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h index 0375fffe4..ccbf93a76 100644 --- a/src/portable/synopsys/dwc2/dwc2_gd32.h +++ b/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -85,6 +85,13 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) // nothing to do } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { + (void) dwc2; + (void) hs_phy_type; + // nothing to do +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/dwc2_nrf.h b/src/portable/synopsys/dwc2/dwc2_nrf.h index b93571f16..51f2d684f 100644 --- a/src/portable/synopsys/dwc2/dwc2_nrf.h +++ b/src/portable/synopsys/dwc2/dwc2_nrf.h @@ -52,6 +52,12 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ (void)hs_phy_type; } +// MCU specific PHY deinit, disable PHY power +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + (void)dwc2; + (void)hs_phy_type; +} + // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 753917a20..259ad21b9 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -264,6 +264,22 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { } } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { + // Disable on-chip FS PHY + dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; + } else { + // Disable HS PHY + #ifdef USB_HS_PHYC + dwc2->stm32_gccfg &= ~STM32_GCCFG_PHYHSEN; + // Disable PLL and LDO + USB_HS_PHYC->USB_HS_PHYC_PLL &= ~USB_HS_PHYC_PLL_PLLEN; + USB_HS_PHYC->USB_HS_PHYC_LDO &= ~USB_HS_PHYC_LDO_ENABLE; + #endif + } +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // used to set turnaround time for fullspeed, nothing to do in highspeed mode diff --git a/src/portable/synopsys/dwc2/dwc2_xmc.h b/src/portable/synopsys/dwc2/dwc2_xmc.h index 63419abf7..aca3873df 100644 --- a/src/portable/synopsys/dwc2/dwc2_xmc.h +++ b/src/portable/synopsys/dwc2/dwc2_xmc.h @@ -71,6 +71,13 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) //USB->ROUTE = USB_ROUTE_PHYPEN; } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { + (void) dwc2; + (void) hs_phy_type; + // nothing to do +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 0fd60b35d..e12e44a41 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -416,11 +416,6 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // force host mode and wait for mode switch dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FDMOD) | GUSBCFG_FHMOD; - #if CFG_TUSB_MCU == OPT_MCU_STM32N6 - // No hardware detection of Vbus B-session is available on the STM32N6 - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBVALOVAL; - #endif - while ((dwc2->gintsts & GINTSTS_CMOD) != GINTSTS_CMODE_HOST) {} #ifdef TUP_USBIP_DWC2_STM32 @@ -440,7 +435,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dwc2->hprt = HPRT_POWER; // turn on VBUS // Enable required interrupts - dwc2->gintmsk |= GINTSTS_OTGINT | GINTSTS_CONIDSTSCHNG | GINTSTS_HPRTINT | GINTSTS_HCINT | GINTSTS_DISCINT; + dwc2->gintmsk |= GINTSTS_OTGINT | GINTSTS_HPRTINT | GINTSTS_HCINT | GINTSTS_DISCINT; // NPTX can hold at least 2 packet, change interrupt level to half-empty uint32_t gahbcfg = dwc2->gahbcfg & ~GAHBCFG_TX_FIFO_EPMTY_LVL; @@ -450,6 +445,17 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; } +bool hcd_deinit(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Turn off VBUS + dwc2->hprt = HPRT_W1_MASK; // clear w1c bits without side effects + // HPRT_POWER is not set -> VBUS off + + dwc2_core_deinit(rhport); + return true; +} + // Enable USB interrupt void hcd_int_enable (uint8_t rhport) { dwc2_int_set(rhport, TUSB_ROLE_HOST, true); @@ -874,7 +880,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { break; case GRXSTS_PKTSTS_HOST_DATATOGGLE_ERR: - TU_ASSERT(0, ); // maybe try to change DToggle + // handle in channel interrupt break; case GRXSTS_PKTSTS_HOST_CHANNEL_HALTED: @@ -1014,8 +1020,11 @@ static bool handle_channel_in_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t h channel_xfer_in_retry(dwc2, ch_id, hcint); } } else if (hcint & HCINT_DATATOGGLE_ERR) { + channel->hcintmsk &= ~HCINT_DATATOGGLE_ERR; xfer->err_count = 0; - TU_ASSERT(false); + hcsplt.split_compl = 0; // restart with start-split + channel->hcsplt = hcsplt.value; + channel_disable(dwc2, channel); } else { // nothing to do } @@ -1351,6 +1360,17 @@ static bool handle_sof_irq(uint8_t rhport, bool in_isr) { } // Config HCFG FS/LS clock and HFIR for SOF interval according to link speed (value is in PHY clock unit) +// Databook Table 2-2: System Clock Speeds +// +-----------+------------------+----------+-----------+-------------------+ +// | PHY | PHY Clock (MHz) | Width | HCFG.Sel | HFIR (clk cycles) | +// +-----------+------------------+----------+-----------+-------------------+ +// | HS UTMI+ | 30 | 16-bit | 30_60 | HS:3749 FS:29999 | +// | HS UTMI+ | 60 | 8-bit | 30_60 | HS:7499 FS:59999 | +// | HS ULPI | 60 | 8-bit | 30_60 | HS:7499 FS:59999 | +// | FS (dead.) | 48 | internal | 48 | FS:47999 | +// | LS via FS | 48 (6 effective) | internal | 6 | LS:47999 | +// +-----------+------------------+----------+-----------+-------------------+ +// HFIR = (interval_us * phy_clock) - 1, where interval is 125us (HS) or 1000us (FS/LS) static void port0_enable(dwc2_regs_t* dwc2, tusb_speed_t speed) { uint32_t hcfg = dwc2->hcfg & ~HCFG_FSLS_PHYCLK_SEL; @@ -1443,16 +1463,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // TU_LOG1_HEX(gintsts); - if (gintsts & GINTSTS_CONIDSTSCHNG) { - // Connector ID status change - dwc2->gintsts = GINTSTS_CONIDSTSCHNG; - - //if (dwc2->gotgctl) - // dwc2->hprt = HPRT_POWER; // power on port to turn on VBUS - //dwc2->gintmsk |= GINTMSK_PRTIM; - // TODO wait for SRP if OTG - } - if (gintsts & GINTSTS_SOF) { const bool more_sof = handle_sof_irq(rhport, in_isr); if (!more_sof) { diff --git a/src/tusb.c b/src/tusb.c index 37aecf693..5241fcf3d 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -39,6 +39,12 @@ #include "host/usbh_pvt.h" #endif +// Suppress IAR warning +// Warning[Pe111]: statement is unreachable +#if defined(__ICCARM__) +#pragma diag_suppress = Pe111 +#endif + tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM] = { TUSB_ROLE_INVALID }; //-------------------------------------------------------------------- |
