Skip to content

Commit

Permalink
Experimental: Automatic power domain handling for displays/RGB zmkfir…
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian König committed Oct 21, 2023
1 parent 01eab79 commit b866d40
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 68 deletions.
31 changes: 22 additions & 9 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ config SPI

config ZMK_RGB_UNDERGLOW_EXT_POWER
bool "RGB underglow toggling also controls external power"
default y
default y if !POWER_DOMAIN

config ZMK_RGB_UNDERGLOW_BRT_MIN
int "RGB underglow minimum brightness in percent"
Expand Down Expand Up @@ -323,22 +323,35 @@ config ZMK_IDLE_TIMEOUT
config ZMK_SLEEP
bool "Enable deep sleep support"
imply USB

if ZMK_SLEEP

config PM_DEVICE
default y
select PM_DEVICE

config ZMK_IDLE_SLEEP_TIMEOUT
int "Milliseconds of inactivity before entering deep sleep"
depends on ZMK_SLEEP
default 900000

#ZMK_SLEEP
endif
config ZMK_POWER_DOMAINS
bool "Enable automatic power domain handling"
default n
select PM_DEVICE
select PM_DEVICE_POWER_DOMAIN
select PM_DEVICE_RUNTIME
select POWER_DOMAIN
select POWER_DOMAIN_GPIO

config ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
bool "Enable assigning peripherals to the chosen default power domain"
default n
depends on ZMK_POWER_DOMAINS
select PM_DEVICE_POWER_DOMAIN_DYNAMIC

# Default this to 2, the most common scenario for this for ZMK is RGB + OLED
config PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
default 2

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

#Power Management
endmenu
Expand Down
4 changes: 4 additions & 0 deletions app/boards/arm/nice_nano/Kconfig.board
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

config BOARD_NICE_NANO
bool "nice!nano"
imply ZMK_POWER_DOMAINS
imply ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
depends on SOC_NRF52840_QIAA

config BOARD_NICE_NANO_V2
bool "nice!nano v2"
imply ZMK_POWER_DOMAINS
imply ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
depends on SOC_NRF52840_QIAA

61 changes: 32 additions & 29 deletions app/boards/arm/nice_nano/arduino_pro_micro_pins.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map
= <0 0 &gpio0 8 0> /* D0 */
, <1 0 &gpio0 6 0> /* D1 */
, <2 0 &gpio0 17 0> /* D2 */
, <3 0 &gpio0 20 0> /* D3 */
, <4 0 &gpio0 22 0> /* D4/A6 */
, <5 0 &gpio0 24 0> /* D5 */
, <6 0 &gpio1 0 0> /* D6/A7 */
, <7 0 &gpio0 11 0> /* D7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
, <16 0 &gpio0 10 0> /* D16 */
, <14 0 &gpio1 11 0> /* D14 */
, <15 0 &gpio1 13 0> /* D15 */
, <18 0 &gpio1 15 0> /* D18/A0 */
, <19 0 &gpio0 2 0> /* D19/A1 */
, <20 0 &gpio0 29 0> /* D20/A2 */
, <21 0 &gpio0 31 0> /* D21/A3 */
;
= <0 0 &gpio0 8 0> /* D0 */
, <1 0 &gpio0 6 0> /* D1 */
, <2 0 &gpio0 17 0> /* D2 */
, <3 0 &gpio0 20 0> /* D3 */
, <4 0 &gpio0 22 0> /* D4/A6 */
, <5 0 &gpio0 24 0> /* D5 */
, <6 0 &gpio1 0 0> /* D6/A7 */
, <7 0 &gpio0 11 0> /* D7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
, <16 0 &gpio0 10 0> /* D16 */
, <14 0 &gpio1 11 0> /* D14 */
, <15 0 &gpio1 13 0> /* D15 */
, <18 0 &gpio1 15 0> /* D18/A0 */
, <19 0 &gpio0 2 0> /* D19/A1 */
, <20 0 &gpio0 29 0> /* D20/A2 */
, <21 0 &gpio0 31 0> /* D21/A3 */
;
};

pro_micro_a: connector_a {
Expand All @@ -38,20 +38,23 @@
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map
= <0 0 &gpio1 15 0> /* D18/A0 */
, <1 0 &gpio0 2 0> /* D19/A1 */
, <2 0 &gpio0 29 0> /* D20/A2 */
, <3 0 &gpio0 31 0> /* D21/A3 */
, <6 0 &gpio0 22 0> /* D4/A6 */
, <7 0 &gpio1 0 0> /* D6/A7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
;
= <0 0 &gpio1 15 0> /* D18/A0 */
, <1 0 &gpio0 2 0> /* D19/A1 */
, <2 0 &gpio0 29 0> /* D20/A2 */
, <3 0 &gpio0 31 0> /* D21/A3 */
, <6 0 &gpio0 22 0> /* D4/A6 */
, <7 0 &gpio1 0 0> /* D6/A7 */
, <8 0 &gpio1 4 0> /* D8/A8 */
, <9 0 &gpio1 6 0> /* D9/A9 */
, <10 0 &gpio0 9 0> /* D10/A10 */
;
};
};

pro_micro_d: &pro_micro {};
pro_micro_i2c: &i2c0 {};
pro_micro_spi: &spi0 {};
pro_micro_serial: &uart0 {};

pro_micro_power_domain: &core_power_domain {};

13 changes: 9 additions & 4 deletions app/boards/arm/nice_nano/nice_nano.dts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
/ {
chosen {
zmk,battery = &vbatt;
zmk,default-power-domain = &core_power_domain;
};

ext-power {
compatible = "zmk,ext-power-generic";
label = "EXT_POWER";
control-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
core_power_domain: core_power_domain {
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <50000>;
off-on-delay-us = <50000>;
enable-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
zephyr,pm-device-runtime-auto;
};

vbatt: vbatt {
Expand All @@ -26,3 +29,5 @@
full-ohms = <(2000000 + 806000)>;
};
};

#include "arduino_pro_micro_pins.dtsi"
1 change: 0 additions & 1 deletion app/boards/arm/nice_nano/nice_nano.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include <nordic/nrf52840_qiaa.dtsi>
#include "nice_nano-pinctrl.dtsi"
#include "arduino_pro_micro_pins.dtsi"

/ {
model = "nice!nano";
Expand Down
14 changes: 9 additions & 5 deletions app/boards/arm/nice_nano/nice_nano_v2.dts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
/ {
chosen {
zmk,battery = &vbatt;
zmk,default-power-domain = &core_power_domain;
};

ext-power {
compatible = "zmk,ext-power-generic";
label = "EXT_POWER";
control-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
init-delay-ms = <50>;
core_power_domain: core_power_domain {
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <50000>;
off-on-delay-us = <50000>;
enable-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
zephyr,pm-device-runtime-auto;
};

vbatt: vbatt {
compatible = "zmk,battery-nrf-vddh";
label = "BATTERY";
};
};

#include "arduino_pro_micro_pins.dtsi"
2 changes: 2 additions & 0 deletions app/boards/arm/puchi_ble/Kconfig.board
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

config BOARD_PUCHI_BLE_v1
bool "puchi_ble_v1"
imply ZMK_POWER_DOMAINS
imply ZMK_POWER_DOMAINS_DYNAMIC_DEFAULT
depends on SOC_NRF52840_QIAA
2 changes: 2 additions & 0 deletions app/boards/arm/puchi_ble/arduino_pro_micro_pins.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ pro_micro_d: &pro_micro {};
pro_micro_i2c: &i2c0 {};
pro_micro_spi: &spi0 {};
pro_micro_serial: &uart0 {};

pro_micro_power_domain: &core_power_domain {};
15 changes: 13 additions & 2 deletions app/boards/arm/puchi_ble/puchi_ble_v1.dts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "arduino_pro_micro_pins.dtsi"
#include "puchi_ble_v1-pinctrl.dtsi"

/ {
Expand All @@ -19,6 +18,7 @@
zephyr,flash = &flash0;
zephyr,console = &cdc_acm_uart;
zmk,battery = &vbatt;
zmk,default-power-domain = &core_power_domain;
};

leds {
Expand All @@ -35,6 +35,14 @@
control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};

core_power_domain: core_power_domain {
compatible = "power-domain-gpio", "power-domain";
startup-delay-us = <50000>;
off-on-delay-us = <50000>;
enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
zephyr,pm-device-runtime-auto;
};

vbatt: vbatt {
compatible = "zmk,battery-voltage-divider";
label = "BATTERY";
Expand Down Expand Up @@ -86,7 +94,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
*/
partitions {
compatible = "fixed-partitions";
Expand Down Expand Up @@ -122,3 +130,6 @@
};
};
};

// Included at the end to ensure the power domain DTS node exists
#include "arduino_pro_micro_pins.dtsi"
9 changes: 9 additions & 0 deletions app/boards/shields/zmk_uno/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@

if SHIELD_ZMK_UNO

config SHIELD_ZMK_UNO_PM
bool "ZMK Uno Automatic Power Management"
default y
select PM_DEVICE
select PM_DEVICE_POWER_DOMAIN
select PM_DEVICE_RUNTIME
select POWER_DOMAIN
select POWER_DOMAIN_GPIO

config ZMK_KEYBOARD_NAME
default "ZMK Uno"

Expand Down
1 change: 1 addition & 0 deletions app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_ZMK_POWER_DOMAINS=y
11 changes: 10 additions & 1 deletion app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
bias-pull-up;
};
};

qdec_sleep: qdec_sleep {
group1 {
psels = <NRF_PSEL(QDEC_A, 1, 11)>,
<NRF_PSEL(QDEC_B, 1, 10)>;
low-power-enable;
};
};
};

// Set up the QDEC hardware based driver and give it the same label as the deleted node.
Expand All @@ -20,5 +28,6 @@ encoder: &qdec0 {
led-pre = <0>;
steps = <80>;
pinctrl-0 = <&qdec_default>;
pinctrl-names = "default";
pinctrl-1 = <&qdec_sleep>;
pinctrl-names = "default", "sleep";
};
51 changes: 37 additions & 14 deletions app/boards/shields/zmk_uno/zmk_uno.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@

&arduino_i2c {
status = "okay";

oled: ssd1306@3c {
compatible = "solomon,ssd1306fb";
reg = <0x3c>;
label = "DISPLAY";
width = <128>;
height = <64>;
segment-offset = <0>;
page-offset = <0>;
display-offset = <0>;
multiplex-ratio = <63>;
prechargep = <0x22>;

power-domain = <&core_power_domain>;
zephyr,pm-device-runtime-auto;
};
};

nice_view_spi: &arduino_spi {
Expand All @@ -20,6 +36,8 @@ nice_view_spi: &arduino_spi {
// on the bus, properly picking up the first `cs-gpios` specifier.
ls0xx@0 {
reg = <0>;
power-domain = <&core_power_domain>;
zephyr,pm-device-runtime-auto;
};

led_strip: ws2812@0 {
Expand All @@ -35,6 +53,9 @@ nice_view_spi: &arduino_spi {
spi-zero-frame = <0x40>;

color-mapping = <LED_COLOR_ID_GREEN LED_COLOR_ID_RED LED_COLOR_ID_BLUE>;

power-domain = <&rgb_power>;
zephyr,pm-device-runtime-auto;
};
};

Expand All @@ -44,22 +65,24 @@ nice_view_spi: &arduino_spi {
zmk,backlight = &backlight;
zmk,underglow = &led_strip;
zmk,matrix-transform = &matrix_transform;
zephyr,display = &oled;
};

core_power_domain: core_power_domain {
compatible = "power-domain-gpio";
startup-delay-us = <2000>;
off-on-delay-us = <2000>;
enable-gpios = <&arduino_header 0 GPIO_ACTIVE_LOW>;
zephyr,pm-device-runtime-auto;
};

// Commented out until we add more powerful power domain support
// external_power {
// compatible = "zmk,ext-power-generic";
// label = "EXT_POWER";
// init-delay-ms = <200>;
// control-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>;
// };

rgb_power {
compatible = "zmk,ext-power-generic";
label = "EXT_POWER";
// label = "RGB_POWER";
init-delay-ms = <200>;
control-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>;
rgb_power: rgb_power {
compatible = "power-domain-gpio";
startup-delay-us = <200>;
off-on-delay-us = <2000>;
enable-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>;
power-domain = <&core_power_domain>;
zephyr,pm-device-runtime-auto;
};

backlight: gpioleds {
Expand Down
Loading

0 comments on commit b866d40

Please sign in to comment.