refactor(backlight): code cleanup
This commit is contained in:
parent
5614a8bb80
commit
ce843825e8
7 changed files with 67 additions and 133 deletions
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
||||||
|
bool zmk_backlight_is_on() { return state.on; }
|
||||||
|
|
||||||
int zmk_backlight_set_brt(uint8_t brightness) {
|
int zmk_backlight_set_brt(uint8_t brightness) {
|
||||||
if (brightness > BRT_MAX) {
|
state.brightness = MIN(brightness, BRT_MAX);
|
||||||
brightness = BRT_MAX;
|
state.on = (state.brightness > 0);
|
||||||
|
return zmk_backlight_update_and_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.brightness = brightness;
|
uint8_t zmk_backlight_get_brt() { return state.on ? state.brightness : 0; }
|
||||||
state.on = (brightness > 0);
|
|
||||||
|
|
||||||
int rc = zmk_backlight_update();
|
|
||||||
if (rc != 0) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return zmk_backlight_save_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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…
Reference in a new issue