Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upUSBDevice: add documentation on USB suspend/resume to enter deep sleep #11635
Conversation
This comment has been minimized.
This comment has been minimized.
@hugueskamba, thank you for your changes. |
bf2be08
to
1e1b67d
core_util_critical_section_enter(); | ||
if (_phy_enabled != enabled) { | ||
if (enabled) { | ||
USBDevice::connect(); |
This comment has been minimized.
This comment has been minimized.
bulislaw
Oct 7, 2019
Member
So it seems that deinit
calls disconnect
and connect
calls init
so we should be good there. But i'm not 100% sure it will restore the state. Is calling disconnect
and phy->deinit
legal in every state? Basically if I call enable_phy(false)
, go to sleep, wake up, call enable_phy(true)
and try to continue using USB will it work?
This comment has been minimized.
This comment has been minimized.
hugueskamba
Oct 8, 2019
•
Author
Contributor
I programmed a K64F with a firmware that allowed me to call enable_phy()
by pressing a button to enable/disable USB phy.
After enable_phy(false)
, nothing can be received on the USB interface and the device goes to deep sleep. After enable_phy(true)
, bytes can once again be received on the USB interface.
Is that what you were not sure about?
This comment has been minimized.
This comment has been minimized.
bulislaw
Oct 8, 2019
Member
Yeah, the test you performed is a good one, but I'm not sure it's definitive for all implementation based on the specification. Could you check that it's actually mandated by the spec? Russ would be able to help I'm sure.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
c1728p9
Oct 9, 2019
Contributor
Unlike some of the other peripherals, the USB code to disable deep sleep is target specific and in a subclass of USBPhy. There is no code common to all targets which locks deep sleep. Depending on implementation, targets could unlock deep sleep on a call to disconnect(), or even do it automatically when USB power is lost. Currently all the implementation I'm aware of only unlock deep sleep in deinit() though.
Is calling disconnect and phy->deinit legal in every state?
Yes, this is equivalent to the user unplugging the device. This may have negative side effects though, such as corrupting a mass storage drive if disconnecting in the middle of a write.
But i'm not 100% sure it will restore the state.
The call to enable_phy(true) can make the device re-enumerate, but can't directly restore the state. The USB host controls the enumeration process so it chooses when and how the device will be restored. Even if the device state is returned to what it was before the disconnect, the host PC software may not be where it left off - for example a serial port may need to be re-opended by the user.
The safest thing to do would be only deinit() when USB power is lost and init() and connect() when it is detected. That way there isn't any state to restore.
Finally, one thing to note is that suspend/resume is already terminology used by the USB standard. It referrs to a USB host initiated low power mode. This may add some confusion to users. I'm not sure of a good way to avoid this though.
This comment has been minimized.
This comment has been minimized.
bulislaw
Oct 9, 2019
Member
If it's also not guaranteed to be clean operation in terms of state being preserved I would say suspend and resume doesn't necessarily work. Is directly calling init/deinit or connect/disconnect a viable solution? Documentation can be clear that it's up to the user to make sure all the transfers have concluded?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@hugueskamba Could you please update your description to give some context and put it in the right place? Thanks |
1e1b67d
to
0ee70e1
This comment has been minimized.
This comment has been minimized.
@bulislaw |
0ee70e1
to
8d29adf
This comment has been minimized.
This comment has been minimized.
This force-push removes the |
8d29adf
to
52e6e30
This comment has been minimized.
This comment has been minimized.
This force-push removes the remnants of the removed |
It is possible to temporarily suspend USB and safely preserve its configuration. This is needed to allow a device to enter deep sleep as a USBDevice instance prevents deep sleep. USB operation can be suspended with `deinit` and restored with `connect`.
52e6e30
to
a3f20f8
LGTM |
I am fine with this PR which adds documentation on how to achieve power saving. On a side note, I find confusing the fact that connect() calls init() (although the init() documentation says that "This function must be called before calling any other functions of this class" and deinit() calls disconnect(). It would have been a cleaner API if each function only did one thing (at the expense of the users doing the right thing). But this is not someting I would like to change now. |
This comment has been minimized.
This comment has been minimized.
CI started |
This comment has been minimized.
This comment has been minimized.
mbed-ci
commented
Oct 16, 2019
Test run: SUCCESSSummary: 11 of 11 test jobs passed |
hugueskamba commentedOct 4, 2019
•
edited
Description
It is now possible to temporarily suspend a USB Component and safely preserve its state. This functionality is needed to allow a device to enter deep sleep as a USBDevice instance prevents deep sleep.
Pull request type
Reviewers
@bulislaw @c1728p9 @evedon
Release Notes