Browse Source

refactor(backlight): code cleanup

xmkb
Alessandro Bortolin 3 years ago committed by Pete Johanson
parent
commit
ce843825e8
  1. 2
      app/Kconfig
  2. 2
      app/dts/behaviors/backlight.dtsi
  3. 8
      app/include/dt-bindings/zmk/backlight.h
  4. 10
      app/include/zmk/backlight.h
  5. 135
      app/src/backlight.c
  6. 37
      app/src/behaviors/behavior_backlight.c
  7. 4
      docs/docs/features/backlight.md

2
app/Kconfig

@ -352,11 +352,9 @@ config ZMK_BACKLIGHT_ON_START
config ZMK_BACKLIGHT_AUTO_OFF_IDLE config ZMK_BACKLIGHT_AUTO_OFF_IDLE
bool "Turn off backlight when keyboard goes into idle state" bool "Turn off backlight when keyboard goes into idle state"
default y
config ZMK_BACKLIGHT_AUTO_OFF_USB config ZMK_BACKLIGHT_AUTO_OFF_USB
bool "Turn off backlight when USB is disconnected" bool "Turn off backlight when USB is disconnected"
default n
#ZMK_BACKLIGHT #ZMK_BACKLIGHT
endif endif

2
app/dts/behaviors/backlight.dtsi

@ -8,7 +8,7 @@
behaviors { behaviors {
/omit-if-no-ref/ bl: behavior_backlight { /omit-if-no-ref/ bl: behavior_backlight {
compatible = "zmk,behavior-backlight"; compatible = "zmk,behavior-backlight";
label = "BACKLIGHT"; label = "BCKLGHT";
#binding-cells = <2>; #binding-cells = <2>;
}; };
}; };

8
app/include/dt-bindings/zmk/backlight.h

@ -4,16 +4,16 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#define BL_TOG_CMD 0 #define BL_ON_CMD 0
#define BL_ON_CMD 1 #define BL_OFF_CMD 1
#define BL_OFF_CMD 2 #define BL_TOG_CMD 2
#define BL_INC_CMD 3 #define BL_INC_CMD 3
#define BL_DEC_CMD 4 #define BL_DEC_CMD 4
#define BL_SET_CMD 5 #define BL_SET_CMD 5
#define BL_TOG BL_TOG_CMD 0
#define BL_ON BL_ON_CMD 0 #define BL_ON BL_ON_CMD 0
#define BL_OFF BL_OFF_CMD 0 #define BL_OFF BL_OFF_CMD 0
#define BL_TOG BL_TOG_CMD 0
#define BL_INC BL_INC_CMD 0 #define BL_INC BL_INC_CMD 0
#define BL_DEC BL_DEC_CMD 0 #define BL_DEC BL_DEC_CMD 0
#define BL_SET BL_SET_CMD #define BL_SET BL_SET_CMD

10
app/include/zmk/backlight.h

@ -6,11 +6,11 @@
#pragma once #pragma once
int zmk_backlight_toggle();
bool zmk_backlight_get_on();
int zmk_backlight_on(); int zmk_backlight_on();
int zmk_backlight_off(); int zmk_backlight_off();
uint8_t zmk_backlight_calc_brt(int direction); int zmk_backlight_toggle();
bool zmk_backlight_is_on();
int zmk_backlight_set_brt(uint8_t brightness); int zmk_backlight_set_brt(uint8_t brightness);
int zmk_backlight_adjust_brt(int direction); uint8_t zmk_backlight_get_brt();
int zmk_backlight_get_brt(); uint8_t zmk_backlight_calc_brt(int direction);

135
app/src/backlight.c

@ -43,10 +43,11 @@ static struct backlight_state state = {.brightness = CONFIG_ZMK_BACKLIGHT_BRT_ST
.on = IS_ENABLED(CONFIG_ZMK_BACKLIGHT_ON_START)}; .on = IS_ENABLED(CONFIG_ZMK_BACKLIGHT_ON_START)};
static int zmk_backlight_update() { static int zmk_backlight_update() {
uint8_t brt = state.on ? state.brightness : 0; uint8_t brt = zmk_backlight_get_brt();
for (int i = 0; i < BACKLIGHT_NUM_LEDS; i++) { for (int i = 0; i < BACKLIGHT_NUM_LEDS; i++) {
int rc = led_set_brightness(backlight_dev, i, brt); int rc = led_set_brightness(backlight_dev, i, brt);
if (rc != 0) { if (rc != 0) {
LOG_ERR("Failed to update backlight LED %d: %d", i, rc);
return rc; return rc;
} }
} }
@ -54,34 +55,25 @@ static int zmk_backlight_update() {
} }
#if IS_ENABLED(CONFIG_SETTINGS) #if IS_ENABLED(CONFIG_SETTINGS)
static int backlight_settings_set(const char *name, size_t len, settings_read_cb read_cb, static int backlight_settings_load_cb(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg) { void *cb_arg, void *param) {
const char *next; const char *next;
if (settings_name_steq(name, "state", &next) && !next) { if (settings_name_steq(name, "state", &next) && !next) {
if (len != sizeof(state)) { if (len != sizeof(state)) {
return -EINVAL; return -EINVAL;
} }
int rc = read_cb(cb_arg, &state, sizeof(state)); int rc = read_cb(cb_arg, &state, sizeof(state));
if (rc < 0) { return MIN(rc, 0);
return rc;
}
return zmk_backlight_update();
} }
return -ENOENT; return -ENOENT;
} }
static struct settings_handler backlight_conf = {.name = "backlight", static void backlight_save_work_handler(struct k_work *work) {
.h_set = backlight_settings_set};
static void zmk_backlight_save_state_work() {
settings_save_one("backlight/state", &state, sizeof(state)); settings_save_one("backlight/state", &state, sizeof(state));
} }
static struct k_delayed_work backlight_save_work; static K_DELAYED_WORK_DEFINE(backlight_save_work, backlight_save_work_handler);
#endif #endif
static int zmk_backlight_init(const struct device *_arg) { static int zmk_backlight_init(const struct device *_arg) {
@ -92,22 +84,21 @@ static int zmk_backlight_init(const struct device *_arg) {
#if IS_ENABLED(CONFIG_SETTINGS) #if IS_ENABLED(CONFIG_SETTINGS)
settings_subsys_init(); settings_subsys_init();
int rc = settings_load_subtree_direct("backlight", backlight_settings_load_cb, NULL);
int err = settings_register(&backlight_conf); if (rc != 0) {
if (err) { LOG_ERR("Failed to load backlight settings: %d", rc);
LOG_ERR("Failed to register the backlight settings handler (err %d)", err);
return err;
} }
k_delayed_work_init(&backlight_save_work, zmk_backlight_save_state_work);
settings_load_subtree("backlight");
#endif #endif
return zmk_backlight_update(); return zmk_backlight_update();
} }
static int zmk_backlight_save_state() { static int zmk_backlight_update_and_save() {
int rc = zmk_backlight_update();
if (rc != 0) {
return rc;
}
#if IS_ENABLED(CONFIG_SETTINGS) #if IS_ENABLED(CONFIG_SETTINGS)
k_delayed_work_cancel(&backlight_save_work); k_delayed_work_cancel(&backlight_save_work);
return k_delayed_work_submit(&backlight_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE)); return k_delayed_work_submit(&backlight_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
@ -116,111 +107,57 @@ static int zmk_backlight_save_state() {
#endif #endif
} }
bool zmk_backlight_get_on() { return state.on; }
int zmk_backlight_on() { int zmk_backlight_on() {
if (!state.on && state.brightness == 0) { state.brightness = MAX(state.brightness, CONFIG_ZMK_BACKLIGHT_BRT_STEP);
state.brightness = CONFIG_ZMK_BACKLIGHT_BRT_STEP;
}
state.on = true; state.on = true;
return zmk_backlight_update_and_save();
int rc = zmk_backlight_update();
if (rc != 0) {
return rc;
}
return zmk_backlight_save_state();
} }
int zmk_backlight_off() { int zmk_backlight_off() {
state.on = false; state.on = false;
return zmk_backlight_update_and_save();
int rc = zmk_backlight_update();
if (rc != 0) {
return rc;
}
return zmk_backlight_save_state();
} }
int zmk_backlight_get_brt() { return state.on ? state.brightness : 0; }
int zmk_backlight_toggle() { return state.on ? zmk_backlight_off() : zmk_backlight_on(); } int zmk_backlight_toggle() { return state.on ? zmk_backlight_off() : zmk_backlight_on(); }
int zmk_backlight_set_brt(uint8_t brightness) { bool zmk_backlight_is_on() { return state.on; }
if (brightness > BRT_MAX) {
brightness = BRT_MAX;
}
state.brightness = brightness;
state.on = (brightness > 0);
int rc = zmk_backlight_update(); int zmk_backlight_set_brt(uint8_t brightness) {
if (rc != 0) { state.brightness = MIN(brightness, BRT_MAX);
return rc; state.on = (state.brightness > 0);
return zmk_backlight_update_and_save();
} }
return zmk_backlight_save_state(); uint8_t zmk_backlight_get_brt() { return state.on ? state.brightness : 0; }
}
uint8_t zmk_backlight_calc_brt(int direction) { uint8_t zmk_backlight_calc_brt(int direction) {
uint8_t brightness = state.brightness; int brt = state.brightness + (direction * CONFIG_ZMK_BACKLIGHT_BRT_STEP);
return CLAMP(brt, 0, BRT_MAX);
int b = state.brightness + (direction * CONFIG_ZMK_BACKLIGHT_BRT_STEP);
return CLAMP(b, 0, BRT_MAX);
}
int zmk_backlight_adjust_brt(int direction) {
state.brightness = zmk_backlight_calc_brt(direction);
state.on = (state.brightness > 0);
int rc = zmk_backlight_update();
if (rc != 0) {
return rc;
} }
return zmk_backlight_save_state();
}
#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE)
static bool auto_off_idle_prev_state = false;
#endif
#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB)
static bool auto_off_usb_prev_state = false;
#endif
#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) || IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB) #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) || IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB)
static int backlight_auto_state(bool *prev_state, bool *new_state) { static int backlight_auto_state(bool *prev_state, bool new_state) {
if (state.on == *new_state) { if (state.on == new_state) {
return 0; return 0;
} }
if (*new_state) { state.on = new_state && *prev_state;
state.on = *prev_state; *prev_state = !new_state;
*prev_state = false; return zmk_backlight_update();
return zmk_backlight_on();
} else {
state.on = false;
*prev_state = true;
return zmk_backlight_off();
}
} }
static int backlight_event_listener(const zmk_event_t *eh) { static int backlight_event_listener(const zmk_event_t *eh) {
#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE)
if (as_zmk_activity_state_changed(eh)) { if (as_zmk_activity_state_changed(eh)) {
bool new_state = (zmk_activity_get_state() == ZMK_ACTIVITY_ACTIVE); static bool prev_state = false;
return backlight_auto_state(&auto_off_idle_prev_state, &new_state); return backlight_auto_state(&prev_state, zmk_activity_get_state() == ZMK_ACTIVITY_ACTIVE);
} }
#endif #endif
#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB) #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB)
if (as_zmk_usb_conn_state_changed(eh)) { if (as_zmk_usb_conn_state_changed(eh)) {
bool new_state = zmk_usb_is_powered(); static bool prev_state = false;
return backlight_auto_state(&auto_off_usb_prev_state, &new_state); return backlight_auto_state(&prev_state, zmk_usb_is_powered());
} }
#endif #endif

37
app/src/behaviors/behavior_backlight.c

@ -24,24 +24,17 @@ static int
on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding, on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) { struct zmk_behavior_binding_event event) {
switch (binding->param1) { switch (binding->param1) {
case BL_TOG_CMD: { case BL_TOG_CMD:
binding->param1 = zmk_backlight_get_on() ? BL_OFF_CMD : BL_ON_CMD; binding->param1 = zmk_backlight_is_on() ? BL_OFF_CMD : BL_ON_CMD;
break; break;
} case BL_INC_CMD:
case BL_INC_CMD: {
uint8_t brightness = zmk_backlight_calc_brt(1);
binding->param1 = BL_SET_CMD; binding->param1 = BL_SET_CMD;
binding->param2 = brightness; binding->param2 = zmk_backlight_calc_brt(1);
break; break;
} case BL_DEC_CMD:
case BL_DEC_CMD: {
uint8_t brightness = zmk_backlight_calc_brt(-1);
binding->param1 = BL_SET_CMD; binding->param1 = BL_SET_CMD;
binding->param2 = brightness; binding->param2 = zmk_backlight_calc_brt(-1);
break; break;
}
default: default:
return 0; return 0;
} }
@ -54,18 +47,24 @@ on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_bin
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) { struct zmk_behavior_binding_event event) {
switch (binding->param1) { switch (binding->param1) {
case BL_TOG_CMD:
return zmk_backlight_toggle();
case BL_ON_CMD: case BL_ON_CMD:
return zmk_backlight_on(); return zmk_backlight_on();
case BL_OFF_CMD: case BL_OFF_CMD:
return zmk_backlight_off(); return zmk_backlight_off();
case BL_INC_CMD: case BL_TOG_CMD:
return zmk_backlight_adjust_brt(1); return zmk_backlight_toggle();
case BL_DEC_CMD: case BL_INC_CMD: {
return zmk_backlight_adjust_brt(-1); uint8_t brt = zmk_backlight_calc_brt(1);
return zmk_backlight_set_brt(brt);
}
case BL_DEC_CMD: {
uint8_t brt = zmk_backlight_calc_brt(-1);
return zmk_backlight_set_brt(brt);
}
case BL_SET_CMD: case BL_SET_CMD:
return zmk_backlight_set_brt(binding->param2); return zmk_backlight_set_brt(binding->param2);
default:
LOG_ERR("Unknown backlight command: %d", binding->param1);
} }
return -ENOTSUP; return -ENOTSUP;

4
docs/docs/features/backlight.md

@ -24,7 +24,7 @@ There are various Kconfig options used to configure the backlight feature. These
| `CONFIG_ZMK_BACKLIGHT_BRT_STEP` | Brightness step in percent | 20 | | `CONFIG_ZMK_BACKLIGHT_BRT_STEP` | Brightness step in percent | 20 |
| `CONFIG_ZMK_BACKLIGHT_BRT_START` | Default brightness in percent | 40 | | `CONFIG_ZMK_BACKLIGHT_BRT_START` | Default brightness in percent | 40 |
| `CONFIG_ZMK_BACKLIGHT_ON_START` | Default backlight state | y | | `CONFIG_ZMK_BACKLIGHT_ON_START` | Default backlight state | y |
| `CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE` | Turn off backlight when keyboard goes into idle state | y | | `CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE` | Turn off backlight when keyboard goes into idle state | n |
| `CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB` | Turn off backlight when USB is disconnected | n | | `CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB` | Turn off backlight when USB is disconnected | n |
## Adding Backlight to a Board ## Adding Backlight to a Board
@ -43,7 +43,7 @@ First, you need to enable PWM by adding the following lines to your `.overlay` f
}; };
``` ```
The value `ch0-pin` represents the pin that controls the LEDs. To calculate the value to use, you need a bit of math. You need the hardware port and run it through a function. The value `ch0-pin` represents the pin that controls the LEDs. With nRF52 boards, you can calculate the value to use in the following way: you need the hardware port and run it through a function.
**32 \* X + Y** = `<Pin number>` where X is first part of the hardware port "PX.01" and Y is the second part of the hardware port "P1.Y". **32 \* X + Y** = `<Pin number>` where X is first part of the hardware port "PX.01" and Y is the second part of the hardware port "P1.Y".
For example, _P1.13_ would give you _32 \* 1 + 13_ = `<45>` and _P0.15_ would give you _32 \* 0 + 15_ = `<15>`. For example, _P1.13_ would give you _32 \* 1 + 13_ = `<45>` and _P0.15_ would give you _32 \* 0 + 15_ = `<15>`.

Loading…
Cancel
Save