Skip to content

Conversation

@peter-marcisovsky
Copy link
Collaborator

@peter-marcisovsky peter-marcisovsky commented Oct 1, 2025

Description

This MR adds Global Suspend/Resume functionality for USB Host.

Limitations

  • No remote wakeup (for now, as it would be too big for one MR)
  • No selective suspend/resume, same reason as above
  • Not working with external hubs (we need to add ext_hub api to stop and start ext. hub)
  • Tested by MSC, HID, CDC, UAC, UVC class drivers as each class driver must be modified to work with suspend/resume events

How it works

  • Suspending
  • Global Suspend/Resume implemented through root port - Stop/Start sending SOFs
    • A device must be connected
      • As we are not suspending the USB-OTG peripheral on the USB Host side (to save power), it does not make sense to suspend root port without any device connected
    • Check if any transfers are submitted
    • Flush and Halt all EPs of all devices
    • Both Hub and HCD Port must be in correct state (active state, with a device connected) to enter suspend mode
    • Suspend is issued via HCD Port command -> Set HPRT.PrtSusp bit
  • Resuming
    • A device must be connected
    • Both Hub and HCD Port must be in correct state (Suspended state) to exit suspended mode
    • Resume is issued via HCD Port command -> Clear HPRT.PrtSusp bit
    • Clear all previously halted EPs of all devices

Changes

Client events

  • USB_HOST_CLIENT_EVENT_DEV_SUSPENDED delivered to a client which opened a device which is now suspended
  • USB_HOST_CLIENT_EVENT_DEV_RESUMED delivered to a client which opened a device which is now resumed
  • both event messages deliver device handle of the device being suspended/resumed

USB Host lib event - unblock usb_host_lib task

  • USB_HOST_LIB_EVENT_FLAGS_AUTO_SUSPEND automatic suspend timer has expired.

Auto Suspend timer

  • usb_host_lib_set_auto_pm()
  • Can be configured as:
    • USB_HOST_LIB_PM_SUSPEND_ONE_SHOT one shot suspend timer
    • USB_HOST_LIB_PM_SUSPEND_PERIODIC periodic suspend timer

USB host public API

  • Global suspend:
    • usb_host_lib_root_port_suspend(void)
  • Resume:
    • usb_host_lib_root_port_resume(void)

USBH public API

  • Issuing actions for all devices regarding Suspend/Resume
    • usbh_devs_set_pm_actions_all()

Hub public API

  • Mark root port as ready for suspend -> processed in hub_process() -> HCD command
    • hub_root_mark_suspend()
  • Mark root port as ready for resume -> processed in hub_process() -> HCD command
    • hub_root_mark_resume()
  • Check if the root hub can be suspended (Correct hub state, no transfer in flight)
    • hub_root_can_suspend()

HCD Tests

  • HCD Port Suspend/Resume with sudden disconnect
  • HCD Port Suspend/Resume already present

USB Host Tests

  • MSC client to test Suspending/Resuming at various conditions (No client opened device, No or A transfer submitted, sudden disconnect.. )
  • Automatic timer test

Related


Checklist

Before submitting a Pull Request, please ensure the following:

  • 🚨 This PR does not introduce breaking changes.
  • All CI checks (GH Actions) pass.
  • Documentation is updated as needed.
  • Tests are updated or added as necessary.
  • Code is well-commented, especially in complex areas.
  • Git history is clean — commits are squashed to the minimum necessary.

@peter-marcisovsky peter-marcisovsky added this to the usb_host v1.0.1 milestone Oct 1, 2025
@peter-marcisovsky peter-marcisovsky self-assigned this Oct 1, 2025
@peter-marcisovsky peter-marcisovsky added Status: In Progress Issue is being worked on Component: usb_host Issue affects usb_host component labels Oct 1, 2025
@peter-marcisovsky peter-marcisovsky force-pushed the feat/usb_host_suspend branch 2 times, most recently from 6b88280 to 5ead420 Compare October 7, 2025 11:05
@peter-marcisovsky
Copy link
Collaborator Author

peter-marcisovsky commented Oct 7, 2025

@tore-espressif @roma-jam @igi540
This MR is a cherry-pick from esp-idf suspend resume MR (already reviewed and approved).

There is one change in the separate commit 6594a35.

The change is regarding USB Hal. The suspend/resume feature calls one function from HAL, which was merged to esp-idf separately in 57d48ef and will be bacported to ID 5.4 and IDF 5.5.

We decided to access ll instead of hal in this feature, to allow users of any IDF 5.4.x and IDF 5.5.x to use the suspend/resume feature in the managed USB component. Otherwise (with hal call) the feature will be limited to the current IDF 5.5.2 and newer (IDF 5.4.2 and newer)

This change will be removed (hal function will be called instead of ll after the end of support for IDF 5.5).

PTAL, Thank you.

@peter-marcisovsky peter-marcisovsky force-pushed the feat/usb_host_suspend branch 2 times, most recently from 6594a35 to 025f3a1 Compare October 9, 2025 09:29
@peter-marcisovsky peter-marcisovsky marked this pull request as ready for review October 9, 2025 12:28
@peter-marcisovsky peter-marcisovsky added Status: Reviewing Issue is being reviewed and removed Status: In Progress Issue is being worked on labels Oct 9, 2025
Copy link
Collaborator

@roma-jam roma-jam left a comment

Choose a reason for hiding this comment

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

Still LGTM.

I tried to review it from the scratch again and maybe there are more notes, that I might gave sooner.

I checked the test cases, and I didn't see the one, which handles the sudden disconnection after putting the port to suspend state (tests in the test_usb_host_plugging.c).

Basically, it is interesting to verify the following cases:

  • detaching the device, while the suspend command was triggered (device has a flag USBH_DEV_SUSPEND_EVT or any other flags, that we can set during the usbh_devs_set_pm_actions_all)
  • detaching the device, which already is in suspended mode (so the hcd_port is in suspended state).

@peter-marcisovsky
Copy link
Collaborator Author

@roma-jam Thank you very much for the review. To address your point about testing

I checked the test cases, and I didn't see the one, which handles the sudden disconnection after putting the port to suspend state (tests in the test_usb_host_plugging.c).

  • Sudden diconnect on HCD level here
  • Sudden diconnect on USB Host level here
  • Also, each of the Class drivers tests feature it's own sudden disconnect tests, for example here

I see you are mentioning test_usb_host_plugging.c file, I will check if I can move some tests there, just to be consistent with the testing hierarchy.

Copy link
Collaborator

@tore-espressif tore-espressif left a comment

Choose a reason for hiding this comment

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

@peter-marcisovsky great work. I leave only 2 nitpicky questions.
Can you also add an entry to changelog?

I want to run few experiments on HW and then we can finally merge it.

Copy link
Collaborator

@tore-espressif tore-espressif left a comment

Choose a reason for hiding this comment

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

@peter-marcisovsky I tested with P4-ECO5, no additional remarks, LGTM!

@tore-espressif
Copy link
Collaborator

@peter-marcisovsky I tested with P4-ECO5, no additional remarks, LGTM!

oh, the changelog entry is still missing!

    - Suspend/Resume of the root port (global)
    - Auto resume by transfer submit feature
    - No remote wake-up feature
    - Closes espressif/esp-idf#14805
@peter-marcisovsky
Copy link
Collaborator Author

@tore-espressif thanks for checking. Changelog added, ready to be merged.

@peter-marcisovsky peter-marcisovsky merged commit af7de6d into master Oct 22, 2025
96 of 100 checks passed
@peter-marcisovsky peter-marcisovsky deleted the feat/usb_host_suspend branch October 22, 2025 13:04
@alex-k8
Copy link

alex-k8 commented Oct 22, 2025

Hello this seems great, thank you very much for this! I have a question. Let's say I have a keyboard connected to the ESP32-S3, and I put it to sleep using this new method. Can I wake it up by pressing a key on the keyboard, or is that the No remote wakeup that was mentioned? Thanks!

@peter-marcisovsky
Copy link
Collaborator Author

Hi @alex-k8 the feature you are requesting is remote wakeup, which is not implemented in this PR.
I already started working on the remote wakeup in #298. We might release the both features (This one and the remote wake) together.

@alex-k8
Copy link

alex-k8 commented Oct 22, 2025

Thank you for the amazing work @peter-marcisovsky ! That feature will be a game changer for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: usb_host Issue affects usb_host component Status: Reviewing Issue is being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide public API for ESP32-S3 USB host suspend functionality (IDFGH-13974)

6 participants