-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance timer creation constraint #671
base: main
Are you sure you want to change the base?
Conversation
ClocksManager may have been de-structured by the time a timer is created. The source of the Timer is the ref-clock (shared with the watchdog).
689496e
to
f933b0c
Compare
timer: TIMER, | ||
resets: &mut RESETS, | ||
watchdog: &Watchdog, | ||
clocks: &ReferenceClock, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the advantage of using ReferenceClock
instead of ClocksManager
? It makes the examples longer, it I'd expect the same to be true for most use cases. Do you have an example where you do have a ReferenceClock
available but not a `ClocksManager´?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
USB takes its clock by value (in order to own it).
This at least partially destructures the ClockManager making it mandatory to initialize the timer before USB. This isn't actually required (Timer can be created after UsbBus).
The actual clock chain for the Timer is:
|
| +-----------+ +------------------+
| | ref_clk | ref_clk | prescaler shared | +-------+
xtal --|-> | prescaler | ---------> | with watchdog | ---> | Timer |
| +-----------+ +------------------+ +-------+
|
where the clk_ref can be sourced from rosc, aux src (pll_usb, gpin0, gpin1) or xosc.
The timer only needs to know the prescaller shared with the watchdog and the ref_clk frequency (to figure what its actual frequency is).
Note:
I had fun hand crafting this diagram 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
USB takes its clock by value (in order to own it).
This at least partially destructures the ClockManager making it mandatory to initialize the timer before USB.
Perhaps we should change that? USB doesn't really need to own its clock. I guess it's meant as a safeguard to prevent other code from messing with the usb clock. But that's not foolproof anyway, as it's still possible to mess with the XOSC which will also affect the usb clock.
Timer can be created after UsbBus
Is there a use case where that's actually useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should change that? USB doesn't really need to own its clock. I guess it's meant as a safeguard to prevent other code from messing with the usb clock. But that's not foolproof anyway, as it's still possible to mess with the XOSC which will also affect the usb clock.
Indeed, the more I work on clocks, sleep & dormant, the more I doubt this can be that easily handled.
Taking ownership of the clock is good enough when there's no usecase where the clock speed and/or source changes but there's lots of cases where lowering clock to save power is essential.
But then, making sure things remain consistent becomes much harder to keep simple. ie orchestrating:
- clock requirements (eg on USB)
- clock speed and source change: to switch between fast processing and power-saving modes
- keeping baudrates valid on clock change: should already set rate prevent clock change if it'd bring the requested baudrate un-reachable?
All that requiring system wide power and state management. Not unrealisable but maybe out of scope for our lightweight HAL objective?
If not, then that'd be great to have and would definitely enable lots of really fancy power efficient usecases :D
Is there a use case where that's actually useful?
What's the usefulness of initializing the Timer before the UsbBus vs the other way around?
These are not related in hardware, there's no reason to have them so in software.
Co-authored-by: Jan Niehusmann <jan@gondor.com>
cabe05c
to
bc3add6
Compare
Preceding PR: