Skip to content
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

Experimental: Automatic power domain handling for displays/RGB #1775

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

petejohanson
Copy link
Contributor

@petejohanson petejohanson commented Apr 24, 2023

This is the initial draft of the experimental work to add automatic power domain handling to ZMK.

Ideally, this will allow for boards/shields that contain one or more power domains to have those power domains automatically enabled whenever a device on that domain (e.g. display, or RGB LEDs) is used by a particular subsystem in ZMK.

To do this:

  • One or more power domains will be added to the board/shield. Example from the nice_nano_v2.dts:
	core_power_domain: core_power_domain {
		compatible = "power-domain-gpio";
		off-on-delay-us = <50000>;
		enable-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
		zephyr,pm-device-runtime-auto;
	};
  • Complete boards might reference the power domain for other nodes explicitly, e.g.:
&arduino_spi {
	status = "okay";

	led_strip: ws2812@0 {
		compatible = "worldsemi,ws2812-spi";

               ...

		power-domain = <&rgb_power>;
		zephyr,pm-device-runtime-auto;
	};
};
  • OR for shield that build for generic boards like the nano, that board will set a new chosen node zmk,default-power-domain, and enable the ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT. This will cause subsystems like our display or RGB underglow code to auto-assign the respective peripherals to that chosen PD. By doing so, the only thing shields possible need to do is set a new higher default value for the PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM Kconfig symbol and it will "just work' if they are built with a board that supports power domains.

At runtime, the power will only be enabled when a device on that PD is requested used.

In addition, I've included the necessary driver fixes for the Zephyr ssd1306 and ls0xx drivers to add PM hooks to re-init the device when is us turned back on.

Changes

This PR encompasses:

TODO:

  • Lots of testing.
  • Docs
  • Figure out what, if anything, to do with &ext_power behavior with this new system. It may be a no-op, or maybe could be made to request the default/assigned power domain when toggled on, to force on VCC. Turning it "off" ould just release the request, and if no other device is active on the power domain, it would then turn of VCC.
  • Test experience w/ the new feature disabled, to be sure there's an escape hatch for anyone wanting the old/existing behavior.

@petejohanson petejohanson added enhancement New feature or request board PRs and issues related to boards. core Core functionality/behavior of ZMK shields PRs and issues related to shields labels Apr 24, 2023
@petejohanson petejohanson self-assigned this Apr 24, 2023
@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch 5 times, most recently from 4788427 to ac9777a Compare April 25, 2023 07:48
@jeff-comley
Copy link

jeff-comley commented May 18, 2023

Tested with Corne, n!ce nano v2, OLED and RGB. Can confirm when LEDs and OLEDs are off that VCC pin on OLED reads 0.0v. Also can toggle LEDs off and on without the OLED being disabled. Did find one issue. if you toggle the RGB off, it will turn itself back on the next time you wake the OLEDs from sleep.

@Kyle-Mendes
Copy link

Just tested with a Lily58 Pro and it worked perfectly. I'm able to have my RGBs and LEDs on now, when previously only the RGBs would work.

Kyle-Mendes/lily58@e773695

@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch from ac9777a to 15b33e2 Compare July 23, 2023 06:15
@@ -71,7 +70,7 @@
&flash0 {
/*
* For more information, see:
* http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
* http: //docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you inadvertently broke this URL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Hate when my auto formatting butchers that. Good catch. Thanks!

@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch from 15b33e2 to 9c818cf Compare July 23, 2023 07:28
@SethMilliken
Copy link
Contributor

I tried installing a nice!view display on an Aurora Corne with this PR, and the display remained blank. Is the ls0xx driver going to need explicit PM support added in zephyr as well in order for nice!view displays to work with power domains?

@petejohanson
Copy link
Contributor Author

I tried installing a nice!view display on an Aurora Corne with this PR, and the display remained blank. Is the ls0xx driver going to need explicit PM support added in zephyr as well in order for nice!view displays to work with power domains?

Yes, this still needs driver work for the ls0xx driver. I'm planning on doing that work in the next week or two.

@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch 2 times, most recently from 4ae4c54 to 1fdd8ba Compare October 21, 2023 06:01
@petejohanson
Copy link
Contributor Author

Just rebased everything, and also pushed driver changes to ls0xx driver to properly handle PM hook, and suspend/resume of the EXT COM pin toggle thread as needed.

@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch from 1fdd8ba to e6c606c Compare October 21, 2023 06:19
@ClicketySplit
Copy link
Contributor

Just rebased everything, and also pushed driver changes to ls0xx driver to properly handle PM hook, and suspend/resume of the EXT COM pin toggle thread as needed.

Hi @petejohanson!

I can confirm that the changes work on Leeloo v2.1 and Leeloo-Micro v1.1; RGB LEDs on rgb_power, and nice!view Displays on core_power_domain.

Thank you for all your work on this change!

@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch from 0a792b7 to 4dc2313 Compare February 11, 2024 16:10
@petejohanson
Copy link
Contributor Author

I've just updated this for the Zephyr 3.5 update.

@@ -83,7 +91,7 @@
&flash0 {
/*
* For more information, see:
* http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
* http: //docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* http: //docs.zephyrproject.org/latest/devices/dts/flash_partitions.html
* http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html

};

core_power_domain: core_power_domain {
// The "power-domain" compatible is needed for any PDs used for that have dynamic deps,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The "power-domain" compatible is needed for any PDs used for that have dynamic deps,
// The "power-domain" compatible is needed for any PDs which have dynamic deps,


config ZMK_EXT_POWER
bool "Enable support to control external power output"
default y
default y if !ZMK_POWER_DOMAINS
Copy link
Contributor

@lesshonor lesshonor Feb 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default y if !ZMK_POWER_DOMAINS
default y
depends on !ZMK_POWER_DOMAINS && DT_HAS_ZMK_EXT_POWER_GENERIC_ENABLED

Perhaps you know of some better way to wall this off for boards which don't have an external power cutoff? It's already a bit of a thorn in the side of STM32/RP2040.

config ZMK_RGB_UNDERGLOW_EXT_POWER
bool "RGB underglow toggling also controls external power"
default y
depends on !ZMK_POWER_DOMAINS
Copy link
Contributor

@lesshonor lesshonor Feb 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
depends on !ZMK_POWER_DOMAINS
depends on ZMK_EXT_POWER

This suggestion builds on my previous one.

@fouf96
Copy link

fouf96 commented Mar 28, 2024

Hello,

i am very interested in this feature, as i have built a keyboard that can control power to RGB and OLED/display seperately using transistors. Is there an estimate when this feature will be merged? Is there anything I can do to help/support?

Thanks, for the awesome work!

@Tworck
Copy link

Tworck commented Apr 4, 2024

Hey hey @petejohanson,

Some context:
@fouf96 and I have been testing your branch to enable OLED and underglow RGB LEDs via distinct MOSFETS and were successful so far in building and testing the general functionality (see comment from @fouf96 above). The idea is that we try to circumvent the issues with the supermini leakage using these MOSFETS to toggle OLED and LEDs completely off from the circuit, However, we are still investigating the pull down when the EXT_VCC is toggled off (will keep u all posted).

Question:
When we tried to set up the UNDERGLOW configs, we noticed that they are not picked up during the build. With the main ZMK branch they work however. It seems that there is some issue in the branch with using those settings. Do you have any idea?

the settings that do not work are:

  • CONFIG_ZMK_RGB_UNDERGLOW_EFF_START=0
  • CONFIG_ZMK_RGB_UNDERGLOW_HUE_START (unclear whether non functional)
  • CONFIG_ZMK_RGB_UNDERGLOW_SAT_START (unclear whether non functional)
  • CONFIG_ZMK_RGB_UNDERGLOW_BRT_START (unclear whether non functional)

particularly CONFIG_ZMK_RGB_UNDERGLOW_EFF_START, it keeps either breath or spectrum effect instead of a constant color. it also seems that we can not set a color at the start (but that might be due to the effect fooling us :D ). The breathing also appears if we do not specify the EFF_START in the config while it should default to 0 according to the documentation

link to the config repo:
https://github.com/fouf96/zmk-config

@caksoylar
Copy link
Contributor

When we tried to set up the UNDERGLOW configs, we noticed that they are not picked up during the build. With the main ZMK branch they work however. It seems that there is some issue in the branch with using those settings. Do you have any idea?

I would wager this has nothing to do with the power management changes here. As documented in https://zmk.dev/docs/config/underglow these settings don't have an effect if you changed them via &rgb_ug bindings and they got persisted to flash.

@fouf96
Copy link

fouf96 commented Apr 5, 2024

@petejohanson

We have investigated further. @caksoylar Regarding your remark with settings being persisted to flash: we don't have any rgb behavior on the keymap, we are just trying to modify the rgb configuration by changing the .conf/kconfig and then reflashing.
Nevertheless, we think you pointed us in the right direction:

  1. Observation (status quo): Changing some of the settings in the .conf file (https://github.com/fouf96/zmk-config/blob/main/config/west.yml) do not take effect. We are not triggering any rgb behavior by pressing keys.

  2. Observation: Building shield settings_reset for nice_nano_v2 with the same setup and flashing settings_reset before flashing new firmware -> change of settings in .conf do not take effect.

  3. Observation: Using a seperate, old repository (https://github.com/fouf96/zmk_chocofy_tukon), that builds from the main zmk branch and we know is functional -> change of settings in .conf do not take effect.

  4. Observation: Using the settings_reset firmware built from the old repository in oberservation 3: now changes take effect , but each time a .conf setting is changed, settings_reset firmware built the from the main zmk branch needs to be flashed beforehand.

I am unclear what the conclusion is...

  1. the settings_reset firmware in the power/domains-and-device-runtime branch does not work correctly?
  2. settings are persisted "wrongly" in the power/domains-and-device-runtime? ...if we change .conf and build on the main zmk branch, the we have the same issue. I think a safe conclusion is that we do not really understand how kconfigs are persisted when flashing, and especially what symbols are overwritten and which are not.
  3. we are still doing something wrong?

happy to get feedback - we are super confused :)

@caksoylar
Copy link
Contributor

the settings_reset firmware in the power/domains-and-device-runtime branch does not work correctly?

The functionality for the settings reset to reset everything (and not just BLE pairings) is recent in #2072 and that branch doesn't have that.

settings are persisted "wrongly" in the power/domains-and-device-runtime? ...if we change .conf and build on the main zmk branch, the we have the same issue. I think a safe conclusion is that we do not really understand how kconfigs are persisted when flashing, and especially what symbols are overwritten and which are not.

I don't know how the code works, but I suspect settings are maybe persisted to flash on boot (and then reused on next boot) even if you don't manually use the bindings? Then that might be considered a bug, and there are already similar issues that are reported and PRs filed for.

If it were me, at the end of the day I'd either look into PRs or understand the code and try to debug, or use the bindings/Kconfig to set a known state and not worry about the *_START settings too much.

@fouf96
Copy link

fouf96 commented May 25, 2024

Hello again,
 
We (@Tworck ) have been running this branch for the past few weeks now and want to share a few observations (which might or might not be bugs).
 
Context: We are currently running on this zmk-config https://github.com/fouf96/zmk-config/tree/manual-miryoku. We have a custom split keyboard that uses two MOSFETS to open/close the connection to Ground for the RGB backlight and the OLED screen separately. We are using the supermini as board.
Unfortunately, we had to work around from directly building from miryoku. As this caused the left/central half keyboard to freeze within a few minutes after reset. For the time being, we have manually extracted the keymap that is being generated by miryoku repo and plugged it into our .keymap file. This makes us suspect that miryoku is changing something in the device tree which is causing the issue. With our workaround, the firmware is running relatively stable. There are a few freezes, especially after not using the keyboards a few hours with certain preconditions. We are currently not able to pin point how to reliably reproduce this issue.
 
Anyways, for now we would like to focus on observation regarding the RGB backlight:
 

  1. &rgb_ug RGB_TOG does not toggle power-domain on left/central half: When turning the backlight off using the &rgb_ug RGB_TOG behavior, the backlight on both halves of the keyboard is turned off. But only the power domain pin on the right half of the keyboard is turned to 0V/off. The power domain pin on the left half stays at 3.2V/on. Note that key/behavior &rgb_ug RGB_TOG is on right half.
  2. Toggle off RGB is not persistent: When turning the backlight off using the &rgb_ug RGB_TOG behavior, the RGB backlight turns back on when waking the keyboard from sleep. We think this is what @jeff-comley meant in his comment.
  3. Automatic RGB off, when disconnecting from USB is not persistent: When disconnecting the keyboard from USB power, the RGB backlight automatically turns off. This is great, as it prevents accidentally draining the battery. Unfortunately, similar to point 2. the RGB backlight turns back on when waking the keyboard from sleep, while still running on battery. Also note that disconnecting the USB power does not toggle off the RGB power domain.
  4. Sleep turns on RGB power domain: When the keyboard goes to sleep, both the OLED and the RGB backlight turn off. When measuring the Voltage at the respective power domain pins, that switches the MOSFET off: The OLED power domain pin is 0V/off. The RGB power domain pin is 3.2V/on. The latter is not the intended behavior.
    Even more interestingly: When powering off the RGB backlight using the &rgb_ug RGB_TOG behavior the respective power domain pin measures 0V/off. When the keyboard goes to sleep the RGB power domain pin is turned on/it measures 3.2V. This is not the case for the OLED power pin.
    --> Going to sleep turns on the RGB power domain.
  5. Confusing sleep behavior: When the keyboard goes to sleep, the RGB backlight, as well as the OLED automatically turn off. This is the intended behavior. After waiting some time the RGB backlight turns back without doing anything. Effects like breathing etc. are active too. The OLED does not turn back on.
     
    Additionally sometimes the behavior becomes buggy and suddenly RGB power domain behavior is not reproducible. A reset resolves this issue.
     
    We also have the impression that testing wired vs. non-wired changes the observations. Have a spreadsheet that documents state and behavior. Its quite big, but we can share it, if there is any interest. Note that some information in the table might be faulty, due to above issue with the behavior becoming buggy.
     
    We are not sure whether the issue lies in our zmk-config or these are bugs with the power domains feature. We have not tested what the standard behavior on the zmk main branch would be (as far as this would be applicable).
     
    We would be happy to hear any kind of input and thank you for the awesome work.

Edit: We just measured power-domain behavior when starting from a wireless state, i.e.: disconnecting USB cables from both halves and then resetting each half. Now the power-domain behavior is entirely as expected. Point 1 & 4 no longer apply. Have not tested point 5 yet.
… Now we are super confused. Connecting to wired somehow breaks power-domains?
 
As a side note: we do not have any wired connection between the two keyboard halves. Instead, both halves are connected to the computer directly. Not sure whether this is causing an issue? We removed it, because it can't be used for charging purposes on a nice nano like boards anyways.

* Add main and sub power domains.
* Default necessary Kconfig settings.
* Properly get/put the display device as needed when we start/ stop
  using it as part of our high level app logic.
* Properly get/put the LED strip instance when actively using
  the LEDs, to allow automatic power domain handling to cut
  power when the LEDs are not in use.
@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch from ef36248 to 2adaeb7 Compare July 5, 2024 05:52
* High level ZMK_POWER_DOMAINS for the feature.
* ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT config setting
   to have various subsystems add their respective devices to
   the chosen `zmk,default-power-domain` on init.
* Set a chosen `zmk,default-power-domain`
* Enable the relevant Kconfig settings for PDs.
* Set a chosen `zmk,default-power-domain`
* Enable the relevant Kconfig settings for PDs.
@petejohanson petejohanson force-pushed the power/domains-and-device-runtime branch from 2adaeb7 to 5f1a1b2 Compare July 5, 2024 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
board PRs and issues related to boards. core Core functionality/behavior of ZMK enhancement New feature or request shields PRs and issues related to shields
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants