Add power domain support, device power management policy and fix display re-init bug #1300
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hey guys, here is my PR for power domain support.
Please review it in conjunction with the zephyr PR: zmkfirmware/zephyr#8
Features
Power Domains
Power Domains are basically Zephyr's notification system for when the power states of devices change.
For example, when the external power is turned off in a nice!nano, power domains allow all devices connected to it to be notified that the power is about to be removed so that they can properly turn off and un-initialize.
Similarly, when power is enabled again, devices are notified and they can re-initialize and resume their work.
The biggest benefit of this is that it's a...
Fix for the Display re-init bug
A longstanding problem was that if external power was turned off and then on again, the display would not resume working, because it needed to be re-initialized.
This PR fixes this issue.
It's currently tested and working for the popular ssd1306 OLED display, but will probably need additional work to fix ePaper and Sharp Memory Displays.
I have ordered a sharp memory display, but the delivery has been delayed and it will probably take another two or three weeks for it to arrive.
If nobody works on this by then, I will add a fix at that time.
Device Power Management Policies
This feature allows you to configure a power management automation policy for a power domain or device.
Currently, the supported policies are:
auto-off-on-idle;
, which automatically turns off a power domain when the device goes into idle state and turns it on again when it resumes.usb-auto-toggle;
, which automatically toggles a power domain off when USB is disconnected and toggles it on again when USB is connected.You can enable this feature by adding the following block to your device tree:
To disable one of the policies just comment it out or remove it.
While assigning a power domain with
device = <&pd_ext_power>;
is the most useful way to use this feature, it's also possible to assign any other device.For example, you could assign
device = <&led_strip>;
to only turn off the underglow.The use of that is somewhat limited though, since it wouldn't cut power to the underglow and it would continue to use up battery.
Multiple Power Domains
This is a feature that probably no keyboard can currently take advantage of, but that will allow us to build really cool wireless keyboards.
For example, the keyboard I am working on will have both a sharp memory display and an rgb underglow / backlight.
The memory display uses very little battery and I want it to be on at all times.
The backlight on the other hand uses a lot of power even when the LEDs are at 0% brightness. I want to be able to turn the power off to the LEDs, but without turning off the power to the display.
Support for multiple power domains allow you to achieve this.
You can add a mosfet between the nice!nano external power pin and the underglow that controls power through another pin.
Then you add a second power domain to your device tree and assign it to the underglow:
As you can see, the
pd_mosfet
is a child of thepd_ext_power
power domain. And theled_strip
is a child of thepd_mosfet
power domain.So when you turn off
pd_mosfet
, it notifies it's child deviceled_strip
and turns it off too. But it doesn't affect any other devices like displays connected to thepd_ext_power
power domain.On the other hand, when you turn off
pd_ext_power
, it notifies the display connected to it as well aspd_mosfet
, which in turn also notifies theled_strip
.In order to control the mosfet power domain, you can add the following behavior to your keymap:
This is the same behavior as the currently used
ext_power
behavior that toggles external power, but you are now able to add additional versions of it that take the optionalpower-domain = <&pd_mosfet>;
parameter that configures which power domain should be turned on or off.You can then add
&ext_power_mosfet EXT_POWER_TOGGLE_CMD
to your keymap to toggle the mosfet.Testing
1. Use the correct branch
This PR depends on changes to the zephyr code, which can be found here:
https://github.com/infused-kim/zmk-zephyr/commits/v3.0.0%2Bzmk-fixes%2Bpd-oled
You won't be able to build against the PR branch until these changes have been incorporated into zmk's zephyr fork.
This PR also depends on Nicell's fix for ext power disabling when going to sleep: #1291
The best way to currently test is to use this branch:
https://github.com/infused-kim/zmk/commits/testing/power-domain
It includes #1291 and uses my zephyr work that has all necessary changes.
If you have a local dev environment...
Just switch to that branch and you should be good to go.
If you want to use github build tools with your zmk-config...
Adjust your
west.yml
:And then run
west update
.2. Add the power domain setting to your shield
You can add these directly to your
my_keyboard.keymap
:If you are using a nice!nano that's all you need to do. If you are using a different board, then you will need to add the power domain itself to it.
Check the PD commit for a reference on how to do it.
3. Add other useful settings
You may also want to add these settings to your
my_keyboard.conf
to help with debugging:4. Build the firmware
Build the firmware as usual-- either push into github or build locally.
Follow the direction here to read the logs if necessary:
https://zmk.dev/docs/development/usb-logging
Merging
Required changes
Update shields
One of the things that is missing is that the
.dtsi
files of all keyboards need to be updated to use the power domain for displays and underglow.But I didn't want to do this until the naming conventions were locked in.
Other changes
Please let me know what other changes need to be made.
Dependencies
I suggest we merge this after merging Nicell's PR #1291.
I have also opened a separate PR for the zephyr changes: zmkfirmware/zephyr#8