cpu/kinetis: implement power modes for pm_layered#13742
cpu/kinetis: implement power modes for pm_layered#13742fjmolinas merged 2 commits intoRIOT-OS:masterfrom
Conversation
cpu/kinetis/include/periph_cpu.h
Outdated
| * @name Kinetis power mode configuration | ||
| * @{ | ||
| */ | ||
| #define PM_NUM_MODES (4U) |
There was a problem hiding this comment.
Is KINETIS_PM_WAIT the default (idle) state?
If you must put #define PM_NUM_MODES (3U) here. (Yes, this is confusing… #13475)
There was a problem hiding this comment.
If I'm understanding correctly, the consensus is that we want the highest enterable state to be what ARM calls Sleep which is where everything stays on but the CPU calls wfi(). That would mean PM can't block that mode which means PM can't enter what ARM calls Run mode which is effectively a while(...){} state. Is that right?
I'm not saying it's terribly useful for PM to enter that mode. I'm just making sure I understand. I've been using it this way for years and it never occurred to me to do otherwise.
I've added comments for each power mode to try to remove any confusion from differing terminologies as I'm not certain what you mean by "idle state". Hopefully now you can tell me if it's definitely wrong the way it is.
There was a problem hiding this comment.
Hm I think there is a misunderstanding.
From what I read, the default IDLE mode should be KINETIS_PM_WAIT. You can remove case PM_NUM_MODES, that is not needed.
But PM_NUM_MODES only counts the non-IDLE modes (that is all other modes: KINETIS_PM_STOP, KINETIS_PM_VLPS, KINETIS_PM_LLS - those are 3).
Why it often still works with the 'wrong' number is that many implementations have a default: case at their normal IDLE mode, so it will also catch all 'higher' modes.
There was a problem hiding this comment.
Ok I think that satisfies my uncertainty about how it should be. I've pushed an update to change it as you said.
Why it often still works with the 'wrong' number is that many implementations have a
default:case at their normal IDLE mode, so it will also catch all 'higher' modes.
In this case it worked because there was a PM_NUM_MODES: case to handle it, but that wasn't how it was supposed to work.
|
A rebase is needed. |
fjmolinas
left a comment
There was a problem hiding this comment.
@benemorius I have some kinetis to test this and access to my office to measure this again, if you can rebase and address the couple of comments I can test!
| #define PM_BLOCK(x) pm_block(x) | ||
| /** | ||
| * @brief pm_unblock iff pm_layered is used | ||
| */ | ||
| #define PM_UNBLOCK(x) pm_unblock(x) | ||
| #else | ||
| /* ignore these calls when not using pm_layered */ | ||
| #define PM_BLOCK(x) | ||
| #define PM_UNBLOCK(x) |
There was a problem hiding this comment.
drivers/kw41zrf/include/kw41zrf_intern.h redefines these, can you adapt that to use this defintions?
There was a problem hiding this comment.
In agree. But in fact I think we probably need to generalize it further even. Unless I missed something, everything that calls pm_block() and pm_unblock() is going to need some equivalent of these defines to cover the case where pm_layered isn't built. Is that wrong?
There was a problem hiding this comment.
I think you are right, currently pm_% is only used in code for platforms that always provide pm_layered or there are a couple of ifdef MODULE_PM_LAYERED, maybe it makes sense to have empty definitions of those functions, but I think this should be in its own PR though, might spark up some unneeded discussion (in the context of this PR)
There was a problem hiding this comment.
In the mean time I removed the duplication as you indicated.
0f2dc59 to
3af6978
Compare
|
Looks good to me - feel free to squash. |
346db21 to
f15ce8b
Compare
|
@benemorius I'm trying to measure power consumption on a |
|
Unfortunately I don't have I saw this thread that might be helpful: https://community.nxp.com/thread/469967 |
Seems like the errata point 3 is getting in my way, can't do any of the two workarounds right now. I'm going to trust @benemorius on this one. |
| /* When the transceiver is not in DSM, this power mode will be blocked. | ||
| * TODO: Change this to symbolic name KINETIS_PM_VLPS when Kinetis power | ||
| * management is merged (https://github.com/RIOT-OS/RIOT/pull/7897) */ | ||
| * management is merged (https://github.com/RIOT-OS/RIOT/pull/13742) */ |
There was a problem hiding this comment.
Hmm just saw this, wrong PR number?
There was a problem hiding this comment.
But #13742 is this PR and it introduces KINETIS_PM_VLPS
There was a problem hiding this comment.
Whoops, I'm not sure why I updated the PR number instead of executing the TODO. I'll fix that.
f15ce8b to
b8ce88e
Compare
|
All good now. |
|
Thanks for the patience and contributions @benemorius! |
Contribution description
This implements the remaining power modes for Kinetis platforms. There are now 4 modes ranging from about 10uA to about 5mA depending on the board.
Testing procedure
For this PR I think it should be enough to test that each power mode changes the current consumption. As the peripheral drivers haven't yet been optimized for power in this PR, a reset is required to wake from power modes lower than 3.
I used
tests/periph_pmto set each power mode and observed the current consumption. Values will vary for each board but here's what I get with akw41z-mini:run: 10mANote that on Kinetis MCUs it is necessary after flashing to power cycle the board before measuring power consumption, else the debug hardware is forced to remain in the active state in modes 1 and 2 which will give wrong consumption readings.
Issues/PRs references
Split out of #11789