-
Notifications
You must be signed in to change notification settings - Fork 2k
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
[Tracking] kinetis: Implement low power modes #11789
base: master
Are you sure you want to change the base?
Conversation
I realized that the solution to unbreaking I've addressed this by having the GPIO peripheral use the LLWU peripheral when it's able to, and blocking PM_LLS when it isn't. This should unbreak any off-chip radios. I tested it with an at86rf233 attached to a kw41z board. Using a randomly selected pin for at86 IRQ, it booted with PM_LLS blocked and a functioning radio. After moving at86 IRQ to one of the 16 pins that support LLWU, it booted with no modes blocked and using LLWU for the IRQ and again a functioning radio. It's really great to see pm_layered coming together like this! I'll push the commit for this shortly. |
06f71f3
to
f2d7c9d
Compare
I could start splitting things out of this PR if it would help with review. Let me know. |
|
Or @MrKevinWeiss? |
I've started splitting this PR up and I think that's the better way to do it. So far there is #13742 and I'll continue splitting after that is merged. |
I'll try to help where I can! |
It's calculated in bytes but is used to declare an array of uint32_t. sizeof(isr_map) went from 448 to 112 (in bss)
f2d7c9d
to
2963a03
Compare
Kinetis boards using LPTMR must define LPTMR.llwu
This was needed in earlier pm_layered PRs but now it will break compiling when LLWU is merged.
2963a03
to
e74eee2
Compare
Contribution description
Taken from #7897
Implements low power modes using pm_layered with blocking of modes depending on what peripherals are in use and what state they are in. Defaults to unblocking all low power modes otherwise.
The GPIO, UART, I2C, LPTMR, and PIT peripheral drivers are updated to block power modes as appropriate. Other peripherals should continue working unaffected by this PR.
Kinetis boards that have a UART or LPUART RX callback configured need to add
uart_config.llwu_rx = LLWU_WAKEUP_PIN_UNDEF
toperiph_conf.h
. I think this PR updates them allbut I didn't verify it. Missing this definition results in LLS mode being unblocked without any way to wake on UART activity.Kinetis boards using LPTMR need to add
LPTMR.llwu = LLWU_WAKEUP_MODULE_LPTMR0
toperiph_conf.h
. I think this PR updates them all.Kinetis boards using a radio driver that hasn't added calls to pm_block() / pm_unblock() will break on this PR. I only realized this just now. Which drivers are in use? kw2xrf at86rf2xx? I think at86rf2xx won't break since it has an independent clock but I'm not sure about kw2xrf. Actually, at86rf2xx will need a LLWU pin configured for at86 IRQ or if that's not available it will need LLS blocked to keep the GPIO IRQ working.I only have kw41z to test this on but hopefully with some feedback it should be working on other platforms too. I'm not sure if I2C has ever been tested. It needed a blocker since it yields until an IRQ instead of spinning like other peripherals.
Since #7897 I fixed some problems with the PM blocking logic in the UART driver and it's possible that the issues observed on
pba-d-01-kw2x
are resolved now but I don't have this board to test with.Testing procedure
#11731 could be useful to help test this.
On
frdm-kw41z
withSTDIO_UART_BAUDRATE=115200
runningtests/periph_pm
should start up with mode 0 (KINETIS_PM_LLS
) blocked and everything else unblocked:Slow the baudrate with
CFLAGS+=-DSTDIO_UART_BAUDRATE=9600 make
to allow mode 0 unblocked:mode 0 blockers: 0 mode 1 blockers: 0 mode 2 blockers: 0 mode 3 blockers: 0 lowest allowed mode: 0 >
After verifying that the shell continues working from mode 0, it should be safe to test blocking and forcing other modes and observe the current consumption in each mode without worry of breaking the shell or other bad things happening:
Take care not to unblock a mode that isn't blocked as there's an assertion for that (#11731 prints a friendly error instead).
Aside from that, the shell should remain responsive no matter what, and it's a bug if it doesn't. That's assuming that it was verified that it stayed working from mode 0 to begin with. A board with a valid UART LLWU pin defined (
uart_config.llwu_rx != LLWU_WAKEUP_PIN_UNDEF
) is required for this to work. Otherwiseuart_poweron()
will block mode 0 and if you unblock it manually or force mode 0 the shell will stop responding to input.In case of an unresponsive shell on startup, change
cpu/kinetis/include/periph_cpu.h:PM_BLOCKER_INITIAL
to{ .val_u32 = 0x01010101 }
to block all modes on startup and then manually unblock them to see which ones break.Concerning PM interfering with UART RX
Perhaps it is worth stating explicitly here that any Kinetis which is capable of uA sleeping in LLS mode and capable of waking by LLWU on the STDIO RX pin is capable of uA sleeping while maintaining a fully functioning shell with no dropped characters. If that doesn't work on this PR, it's a bug.
Concerning knowing why power modes are blocked
One known downside of the current pm_layered paradigm is that we don't keep track of who blocked what. I've experienced the confusion resulting from this lately while testing wider ranges of configurations that result in a wider variety of blocked PM states.
To address this, I've added LOG_INFO outputs that result in notices like this during (typically) startup:
I find it helpful. I made some effort to have the outputs printed during startup/init instead of each time modes are blocked/unblocked in cases where the latter might happen much more often than the former.
Perhaps we might consider enforcing a policy that any code which blocks power modes must follow this pattern? Now is a good time to start while not many calls to pm_block() have yet been added.
Issues/PRs references
This comment has current consumption reference values as well as some information about PM usage and current measurement procedures.