Skip to content

Add DWC2 deinit support#3378

Merged
hathach merged 15 commits intomasterfrom
dwc2_deinit
Mar 5, 2026
Merged

Add DWC2 deinit support#3378
hathach merged 15 commits intomasterfrom
dwc2_deinit

Conversation

@HiFiPhile
Copy link
Copy Markdown
Collaborator

@HiFiPhile HiFiPhile commented Nov 28, 2025

@roma-jam Hi, I've added deinit support to dwc2.

A dynamic switch example is added and tested on:

  • ESP32-S3-DevKitC
  • NUCLEO-H7S3L8
  • Nucleo-U5A5ZJ-Q
  • STM32F407-DISCO
  • STM32F723E-DISCO (FS/HS)
  • J-Link V9 (STM32F205 FS)

Copilot AI review requested due to automatic review settings November 28, 2025 14:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds deinitialization support for the Synopsys DWC2 USB controller, enabling dynamic start/stop of USB host and device modes. The implementation mirrors the initialization sequence in reverse, disabling interrupts, disconnecting from the bus, and resetting the core. This was tested on STM32H7S3 with device mode toggling via button press.

Key Changes

  • Implements hcd_deinit() and dcd_deinit() functions for DWC2 host and device controllers
  • Adds common dwc2_core_deinit() function shared between host and device modes
  • Updates error handling in tuh_deinit() and tud_deinit() to use TU_ASSERT consistently
  • Fixes button active state configuration for STM32H7S3 Nucleo board

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/portable/synopsys/dwc2/hcd_dwc2.c Adds host controller deinit implementation with interrupt disable
src/portable/synopsys/dwc2/dwc2_common.h Declares dwc2_core_deinit() for shared deinitialization logic
src/portable/synopsys/dwc2/dwc2_common.c Implements common core deinit with soft disconnect and core reset
src/portable/synopsys/dwc2/dcd_dwc2.c Adds device controller deinit with disconnect and cleanup
src/host/usbh.c Changes hcd_deinit() call to use TU_ASSERT for error checking
src/device/usbd.c Changes dcd_deinit() call to use TU_ASSERT for consistency
hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.h Corrects button active state from 1 to 0 (active-low with pullup)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/portable/synopsys/dwc2/dwc2_common.c Outdated
Comment thread src/portable/synopsys/dwc2/hcd_dwc2.c
Comment thread src/portable/synopsys/dwc2/dcd_dwc2.c
Comment thread src/device/usbd.c Fixed
@HiFiPhile HiFiPhile mentioned this pull request Nov 28, 2025
1 task
@HiFiPhile HiFiPhile force-pushed the dwc2_deinit branch 2 times, most recently from 9461753 to e214976 Compare November 29, 2025 12:31
Comment thread src/device/usbd.c Fixed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hw/bsp/stm32u5/family.c Outdated
Comment thread examples/dual/dynamic_switch/README.md Outdated
Comment thread hw/bsp/stm32u5/family.c Outdated
Comment thread hw/bsp/stm32u5/family.c Outdated
Comment thread hw/bsp/stm32h7rs/family.c Outdated
Comment thread hw/bsp/stm32h7rs/family.c Outdated
Comment thread hw/bsp/stm32u5/family.c Outdated
Comment thread hw/bsp/stm32h7rs/family.c Outdated
Comment thread hw/bsp/stm32u5/family.c Outdated
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Dec 3, 2025

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Dec 13, 2025

TinyUSB Average Code Size Metrics

File .text .rodata .data .bss size %
cdc_host.c 6610 487 15 1539 8371 5.2%
ehci.c 2761 0 0 5970 7537 4.7%
ncm_device.c 1514 28 1408 5830 7358 4.6%
usbh.c 4562 55 100 964 5647 3.5%
hcd_dwc2.c 4994 33 1 513 5540 3.4%
midi_host.c 1353 7 7 3740 5097 3.2%
video_device.c 4391 5 1851 472 4855 3.0%
audio_device.c 2849 0 1248 1673 4518 2.8%
dcd_dwc2.c 4174 25 0 265 4464 2.8%
ohci.c 1942 0 0 2414 4356 2.7%
dcd_ch32_usbfs.c 1472 0 0 2444 3916 2.4%
hcd_stm32_fsdev.c 3287 0 1 420 3708 2.3%
usbd.c 3191 57 89 276 3532 2.2%
ecm_rndis_device.c 1037 0 1 2272 3310 2.1%
dcd_khci.c 1953 0 0 1290 3243 2.0%
hcd_musb.c 3073 0 0 157 3230 2.0%
dcd_ci_fs.c 1925 0 0 1290 3215 2.0%
dcd_nrf5x.c 2919 0 0 292 3211 2.0%
dcd_da146xx.c 3067 0 0 144 3211 2.0%
hcd_rusb2.c 2923 0 0 245 3168 2.0%
dcd_rusb2.c 2917 0 0 156 3073 1.9%
msc_device.c 2518 108 2286 538 3056 1.9%
hcd_ch32_usbfs.c 2484 0 0 498 2982 1.9%
hcd_khci.c 2442 0 0 449 2891 1.8%
dcd_stm32_fsdev.c 2557 0 0 291 2848 1.8%
dcd_mm32f327x_otg.c 1478 0 0 1290 2768 1.7%
dcd_musb.c 2446 0 0 160 2606 1.6%
hcd_samd.c 2220 0 0 324 2544 1.6%
dcd_ci_hs.c 1762 0 0 1280 2530 1.6%
dcd_eptri.c 2270 0 0 259 2529 1.6%
usbtmc_device.c 2176 24 69 291 2500 1.6%
hid_host.c 1206 0 0 1250 2456 1.5%
mtp_device.c 1689 22 1449 579 2275 1.4%
dcd_rp2040.c 859 20 604 655 2138 1.3%
dcd_ch32_usbhs.c 1648 0 0 448 2096 1.3%
cdc_device.c 1326 16 19 660 1985 1.2%
msc_host.c 1589 0 0 394 1984 1.2%
dcd_msp430x5xx.c 1796 0 0 176 1972 1.2%
hcd_rp2040.c 976 73 416 384 1849 1.1%
dcd_lpc17_40.c 1470 0 0 648 1794 1.1%
midi_device.c 1127 0 991 589 1714 1.1%
dcd_nuc505.c 0 0 1529 157 1686 1.0%
dcd_lpc_ip3511.c 1463 0 0 264 1639 1.0%
dcd_samg.c 1319 0 0 72 1391 0.9%
dcd_samd.c 1032 0 0 266 1298 0.8%
hub.c 1235 8 8 29 1269 0.8%
dcd_nuc121.c 1167 0 0 101 1268 0.8%
hid_device.c 1118 44 997 115 1233 0.8%
dcd_nuc120.c 1093 0 0 78 1171 0.7%
vendor_device.c 624 0 530 464 1087 0.7%
rp2040_usb.c 172 75 718 4 969 0.6%
dfu_device.c 744 28 712 183 926 0.6%
typec_stm32.c 820 8 2 12 842 0.5%
tusb_fifo.c 844 0 477 0 838 0.5%
dwc2_common.c 602 30 0 0 618 0.4%
usbc.c 420 2 20 166 608 0.4%
usbd_control.c 523 0 474 78 600 0.4%
hcd_pio_usb.c 262 0 240 0 502 0.3%
tusb.c 430 0 368 3 432 0.3%
hcd_ci_hs.c 190 0 0 0 190 0.1%
fsdev_common.c 180 0 0 0 180 0.1%
rusb2_common.c 160 0 16 0 176 0.1%
dfu_rt_device.c 156 0 134 0 156 0.1%
TOTAL 113507 1155 16780 45521 161156 100.0%
Input files
  • cmake-build/cmake-build-adafruit_clue/metrics.json
  • cmake-build/cmake-build-apard32690/metrics.json
  • cmake-build/cmake-build-at32f403a_weact_blackpill/metrics.json
  • cmake-build/cmake-build-at_start_f402/metrics.json
  • cmake-build/cmake-build-at_start_f413/metrics.json
  • cmake-build/cmake-build-at_start_f415/metrics.json
  • cmake-build/cmake-build-at_start_f423/metrics.json
  • cmake-build/cmake-build-at_start_f425/metrics.json
  • cmake-build/cmake-build-at_start_f435/metrics.json
  • cmake-build/cmake-build-at_start_f455/metrics.json
  • cmake-build/cmake-build-b_g474e_dpow1/metrics.json
  • cmake-build/cmake-build-b_u585i_iot2a/metrics.json
  • cmake-build/cmake-build-ch32v103r_r1_1v0/metrics.json
  • cmake-build/cmake-build-ch32v203c_r0_1v0/metrics.json
  • cmake-build/cmake-build-ch32v307v_r1_1v0/metrics.json
  • cmake-build/cmake-build-cynthion_d11/metrics.json
  • cmake-build/cmake-build-da14695_dk_usb/metrics.json
  • cmake-build/cmake-build-double_m33_express/metrics.json
  • cmake-build/cmake-build-ea4088_quickstart/metrics.json
  • cmake-build/cmake-build-ea4357/metrics.json
  • cmake-build/cmake-build-ek_tm4c123gxl/metrics.json
  • cmake-build/cmake-build-feather_stm32f405/metrics.json
  • cmake-build/cmake-build-fomu/metrics.json
  • cmake-build/cmake-build-frdm_k32l2a4s/metrics.json
  • cmake-build/cmake-build-frdm_k64f/metrics.json
  • cmake-build/cmake-build-frdm_kl25z/metrics.json
  • cmake-build/cmake-build-frdm_mcxa153/metrics.json
  • cmake-build/cmake-build-frdm_rw612/metrics.json
  • cmake-build/cmake-build-hpm6750evk2/metrics.json
  • cmake-build/cmake-build-lpcxpresso11u37/metrics.json
  • cmake-build/cmake-build-lpcxpresso1347/metrics.json
  • cmake-build/cmake-build-lpcxpresso1549/metrics.json
  • cmake-build/cmake-build-lpcxpresso1769/metrics.json
  • cmake-build/cmake-build-lpcxpresso18s37/metrics.json
  • cmake-build/cmake-build-lpcxpresso51u68/metrics.json
  • cmake-build/cmake-build-lpcxpresso54114/metrics.json
  • cmake-build/cmake-build-metro_m0_express/metrics.json
  • cmake-build/cmake-build-metro_m4_express/metrics.json
  • cmake-build/cmake-build-metro_m7_1011/metrics.json
  • cmake-build/cmake-build-mm32f327x_mb39/metrics.json
  • cmake-build/cmake-build-msp_exp430f5529lp/metrics.json
  • cmake-build/cmake-build-msp_exp432e401y/metrics.json
  • cmake-build/cmake-build-nutiny_nuc126v/metrics.json
  • cmake-build/cmake-build-nutiny_sdk_nuc120/metrics.json
  • cmake-build/cmake-build-nutiny_sdk_nuc121/metrics.json
  • cmake-build/cmake-build-nutiny_sdk_nuc505/metrics.json
  • cmake-build/cmake-build-portenta_c33/metrics.json
  • cmake-build/cmake-build-raspberry_pi_pico/metrics.json
  • cmake-build/cmake-build-raspberrypi_cm4/metrics.json
  • cmake-build/cmake-build-raspberrypi_zero/metrics.json
  • cmake-build/cmake-build-samg55_xplained/metrics.json
  • cmake-build/cmake-build-sipeed_longan_nano/metrics.json
  • cmake-build/cmake-build-stlinkv3mini/metrics.json
  • cmake-build/cmake-build-stm32c071nucleo/metrics.json
  • cmake-build/cmake-build-stm32f070rbnucleo/metrics.json
  • cmake-build/cmake-build-stm32f103_bluepill/metrics.json
  • cmake-build/cmake-build-stm32f207nucleo/metrics.json
  • cmake-build/cmake-build-stm32f303disco/metrics.json
  • cmake-build/cmake-build-stm32g0b1nucleo/metrics.json
  • cmake-build/cmake-build-stm32h503nucleo/metrics.json
  • cmake-build/cmake-build-stm32h743eval/metrics.json
  • cmake-build/cmake-build-stm32h7s3nucleo/metrics.json
  • cmake-build/cmake-build-stm32l052dap52/metrics.json
  • cmake-build/cmake-build-stm32l412nucleo/metrics.json
  • cmake-build/cmake-build-stm32n6570dk/metrics.json
  • cmake-build/cmake-build-stm32u083cdk/metrics.json
  • cmake-build/cmake-build-stm32wb55nucleo/metrics.json
  • cmake-build/cmake-build-stm32wba_nucleo/metrics.json
  • cmake-build/cmake-build-xmc4500_relax/metrics.json

Comment thread src/tusb.c Outdated
return phys_addr;
}

TU_ATTR_WEAK void tusb_pre_init_cb(uint8_t rhport, tusb_role_t role) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this, both init() and de-init() is called by application, they should call them before/after those accordingly ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hathach It's for host/device specific init, like STM32's GCCFG and GOTGCTL register, which need to be set to different value on host/device. Their meaning is also different across families, I haven't found a easy way to include them in the driver.

void tusb_pre_init_cb(uint8_t rhport, tusb_role_t role) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give me a bit of time, I will try to review and see if we could avoid using these callbacks

@HiFiPhile HiFiPhile force-pushed the dwc2_deinit branch 3 times, most recently from 7c4233b to f7d82a1 Compare December 15, 2025 22:01
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
@HiFiPhile
Copy link
Copy Markdown
Collaborator Author

@hathach I've rebased on master.

Comment thread src/common/tusb_fifo.h
// Suppress IAR warning
// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
#if defined(__ICCARM__)
#pragma diag_suppress = Pa082
Copy link
Copy Markdown
Owner

@hathach hathach Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HiFiPhile which compile flags to pass to IAR to enable most warning like gcc, we can enable it for tinyusb build as well.

PS: ah, I just add --warnings-are-errors then try to fix them

Comment thread src/portable/synopsys/dwc2/dwc2_common.c Outdated
@hathach
Copy link
Copy Markdown
Owner

hathach commented Mar 4, 2026

@HiFiPhile I push changes that also add mcu specific phy deinit as well (suggested by claude). Please review to see if that makes sense to you. Also I haven't tested with the dynamic_switch example (getting lazy with wiring), please re-check if you already have it setup

PS: I think we can do better with low power/suspend mode by disable clock etc, but that is for later.

Comment thread src/portable/synopsys/dwc2/dwc2_stm32.h Outdated
dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN;

// Disable HS PHY if present
#ifdef USB_HS_PHYC
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

F723 has USB_HS_PHYC but only for HS port.

Copy link
Copy Markdown
Owner

@hathach hathach Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we also need the hs_phy_type argument to de-init the right one ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think yes, also need to take care of when both HS port are used like on N6.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just update PR

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to avoid turning off PHYC on N6 when another port is still active.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right N6 has 2 instance of USB1/2_HS_PHYC_NS. We can use the dwc2 check to disale the right phy. But we didn't enable it in dwc2_phy_init(). Not sure if N6 is currently working, I don't have the board to test with

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's okay in fact, didn't notice on N6 it has 2 dedicated PHYC instance.

N6 is working with my N6570-DK.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, maybe the phy is auto enabled/disabled using dwc2 signal (physel, utmi) with latet stm config. Variant with USB_HS_PHYC seems to use stm32_gccfg to enable/disable phy. I guess that would be ok to merge now ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PHYC init code is in bsp currently:

USB1_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4);

It's okay to merge.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah thanks, I think we should move it inside our driver that will allow us to disable phy to save power later on. But that can be on its own PR later.

Copy link
Copy Markdown
Owner

@hathach hathach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect, thank you very much, I am glad that we finally merge this

@hathach hathach force-pushed the dwc2_deinit branch 2 times, most recently from a54e973 to 75a5bed Compare March 5, 2026 13:40
@hathach hathach merged commit 9747687 into master Mar 5, 2026
723 of 726 checks passed
@hathach hathach deleted the dwc2_deinit branch March 5, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants