From 5796aa0104b792e05edbe31a5a4b84a7a44a2f50 Mon Sep 17 00:00:00 2001 From: urob <978080+urob@users.noreply.github.com> Date: Fri, 9 Feb 2024 21:17:21 -0500 Subject: [PATCH] Zen display & battery tweaks --- app/boards/arm/corneish_zen/CMakeLists.txt | 5 +- app/boards/arm/corneish_zen/Kconfig.defconfig | 20 +++++++ .../corneish_zen_v2_left_defconfig | 1 + .../corneish_zen_v2_right_defconfig | 1 + .../arm/corneish_zen/custom_status_screen.c | 36 +++++++++++- .../arm/corneish_zen/widgets/battery_status.c | 55 +++++++++++++++---- .../arm/corneish_zen/widgets/icons/lpkblogo.c | 45 +++++++++++++++ .../corneish_zen/widgets/icons/miryokulogo.c | 37 +++++++++++++ .../arm/corneish_zen/widgets/icons/zmklogo.c | 40 ++++++++++++++ .../arm/corneish_zen/widgets/layer_status.c | 10 ++++ app/include/zmk/keymap.h | 4 +- app/module/drivers/display/Kconfig.il0323 | 10 +++- app/module/drivers/display/il0323.c | 12 +++- app/src/behaviors/behavior_momentary_layer.c | 2 +- app/src/conditional_layer.c | 11 +++- app/src/display/Kconfig | 11 ++++ app/src/display/main.c | 18 ++++++ app/src/keymap.c | 23 ++++++-- 18 files changed, 314 insertions(+), 27 deletions(-) create mode 100644 app/boards/arm/corneish_zen/widgets/icons/lpkblogo.c create mode 100644 app/boards/arm/corneish_zen/widgets/icons/miryokulogo.c create mode 100644 app/boards/arm/corneish_zen/widgets/icons/zmklogo.c diff --git a/app/boards/arm/corneish_zen/CMakeLists.txt b/app/boards/arm/corneish_zen/CMakeLists.txt index afaaf6bf19b..be921d1686e 100644 --- a/app/boards/arm/corneish_zen/CMakeLists.txt +++ b/app/boards/arm/corneish_zen/CMakeLists.txt @@ -48,7 +48,10 @@ if(CONFIG_ZMK_DISPLAY) zephyr_library_sources(widgets/icons/layers2.c) endif() if(NOT CONFIG_ZMK_SPLIT_ROLE_CENTRAL) - zephyr_library_sources(widgets/icons/zenlogo.c) + target_sources_ifdef(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_ZEN app PRIVATE widgets/icons/zenlogo.c) + target_sources_ifdef(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_LPKB app PRIVATE widgets/icons/lpkblogo.c) + target_sources_ifdef(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_ZMK app PRIVATE widgets/icons/zmklogo.c) + target_sources_ifdef(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_MIRYOKU app PRIVATE widgets/icons/miryokulogo.c) endif() endif() diff --git a/app/boards/arm/corneish_zen/Kconfig.defconfig b/app/boards/arm/corneish_zen/Kconfig.defconfig index 11f932b5302..d8ce46d61cb 100644 --- a/app/boards/arm/corneish_zen/Kconfig.defconfig +++ b/app/boards/arm/corneish_zen/Kconfig.defconfig @@ -78,6 +78,26 @@ menuconfig CUSTOM_WIDGET_LAYER_STATUS menuconfig CUSTOM_WIDGET_PERIPHERAL_STATUS bool "custom peripheral status widget" +config CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING + bool "Hide heading strip for layer widget and center widgets on 1/3rds" + +choice CUSTOM_WIDGET_LOGO_IMAGE + prompt "custom logo widget image" + + config CUSTOM_WIDGET_LOGO_IMAGE_ZEN + bool "Corne-ish Zen" + + config CUSTOM_WIDGET_LOGO_IMAGE_LPKB + bool "LPKB" + + config CUSTOM_WIDGET_LOGO_IMAGE_ZMK + bool "ZMK" + + config CUSTOM_WIDGET_LOGO_IMAGE_MIRYOKU + bool "Miryoku" + +endchoice + endif # BOARD_CORNEISH_ZEN_LEFT || BOARD_CORNEISH_ZEN_RIGHT if BOARD_CORNEISH_ZEN_V1_LEFT || BOARD_CORNEISH_ZEN_V1_RIGHT diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig index b6670fd8df5..37e4319cb3f 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig @@ -60,6 +60,7 @@ CONFIG_CUSTOM_WIDGET_OUTPUT_STATUS=y CONFIG_ZMK_WIDGET_OUTPUT_STATUS=n CONFIG_CUSTOM_WIDGET_LAYER_STATUS=y CONFIG_ZMK_WIDGET_LAYER_STATUS=n +CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_ZEN=y # Turn on logging, and set ZMK logging to debug output #CONFIG_LOG=y diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig index 90cfe7698d1..cf0ae49c74f 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig @@ -58,6 +58,7 @@ CONFIG_CUSTOM_WIDGET_BATTERY_STATUS=y CONFIG_ZMK_WIDGET_BATTERY_STATUS=n CONFIG_CUSTOM_WIDGET_PERIPHERAL_STATUS=y CONFIG_ZMK_WIDGET_PERIPHERAL_STATUS=n +CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_ZEN=y # Turn on logging, and set ZMK logging to debug output #CONFIG_LOG=y diff --git a/app/boards/arm/corneish_zen/custom_status_screen.c b/app/boards/arm/corneish_zen/custom_status_screen.c index 492239c8a57..19b0c21b5c6 100644 --- a/app/boards/arm/corneish_zen/custom_status_screen.c +++ b/app/boards/arm/corneish_zen/custom_status_screen.c @@ -14,7 +14,6 @@ #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -LV_IMG_DECLARE(zenlogo); LV_IMG_DECLARE(layers2); #if IS_ENABLED(CONFIG_CUSTOM_WIDGET_BATTERY_STATUS) @@ -40,37 +39,72 @@ lv_obj_t *zmk_display_status_screen() { #if IS_ENABLED(CONFIG_CUSTOM_WIDGET_BATTERY_STATUS) zmk_widget_battery_status_init(&battery_status_widget, screen); +#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING) + lv_obj_align(zmk_widget_battery_status_obj(&battery_status_widget), LV_ALIGN_CENTER, 0, -43); +#else lv_obj_align(zmk_widget_battery_status_obj(&battery_status_widget), LV_ALIGN_TOP_MID, 0, 2); #endif +#endif #if IS_ENABLED(CONFIG_CUSTOM_WIDGET_OUTPUT_STATUS) zmk_widget_output_status_init(&output_status_widget, screen); +#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING) + lv_obj_align(zmk_widget_output_status_obj(&output_status_widget), LV_ALIGN_CENTER, 0, 0); +#else lv_obj_align(zmk_widget_output_status_obj(&output_status_widget), LV_ALIGN_TOP_MID, 0, 41); #endif +#endif #if IS_ENABLED(CONFIG_CUSTOM_WIDGET_PERIPHERAL_STATUS) zmk_widget_peripheral_status_init(&peripheral_status_widget, screen); +#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING) + lv_obj_align(zmk_widget_peripheral_status_obj(&peripheral_status_widget), LV_ALIGN_CENTER, 0, + 0); +#else lv_obj_align(zmk_widget_peripheral_status_obj(&peripheral_status_widget), LV_ALIGN_TOP_MID, 0, 41); #endif +#endif #if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS) +#if !IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING) lv_obj_t *LayersHeading; LayersHeading = lv_img_create(screen); lv_obj_align(LayersHeading, LV_ALIGN_BOTTOM_MID, 0, -30); lv_img_set_src(LayersHeading, &layers2); +#endif zmk_widget_layer_status_init(&layer_status_widget, screen); lv_obj_set_style_text_font(zmk_widget_layer_status_obj(&layer_status_widget), &lv_font_montserrat_16, LV_PART_MAIN); +#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING) + lv_obj_align(zmk_widget_layer_status_obj(&layer_status_widget), LV_ALIGN_CENTER, 0, 43); +#else lv_obj_align(zmk_widget_layer_status_obj(&layer_status_widget), LV_ALIGN_BOTTOM_MID, 0, -5); #endif +#endif #if !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) lv_obj_t *zenlogo_icon; zenlogo_icon = lv_img_create(screen); +#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_ZEN) + LV_IMG_DECLARE(zenlogo); lv_img_set_src(zenlogo_icon, &zenlogo); +#elif IS_ENABLED(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_LPKB) + LV_IMG_DECLARE(lpkblogo); + lv_img_set_src(zenlogo_icon, &lpkblogo); +#elif IS_ENABLED(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_ZMK) + LV_IMG_DECLARE(zmklogo); + lv_img_set_src(zenlogo_icon, &zmklogo); +#elif IS_ENABLED(CONFIG_CUSTOM_WIDGET_LOGO_IMAGE_MIRYOKU) + LV_IMG_DECLARE(miryokulogo); + lv_img_set_src(zenlogo_icon, &miryokulogo); +#endif +#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING) + lv_obj_align(zenlogo_icon, LV_ALIGN_CENTER, 0, 43); +#else lv_obj_align(zenlogo_icon, LV_ALIGN_BOTTOM_MID, 0, -5); +#endif #endif return screen; diff --git a/app/boards/arm/corneish_zen/widgets/battery_status.c b/app/boards/arm/corneish_zen/widgets/battery_status.c index 39b811b53f3..5a42b1078da 100644 --- a/app/boards/arm/corneish_zen/widgets/battery_status.c +++ b/app/boards/arm/corneish_zen/widgets/battery_status.c @@ -41,21 +41,52 @@ LV_IMG_DECLARE(batt_0); LV_IMG_DECLARE(batt_0_chg); static void set_battery_symbol(lv_obj_t *icon, struct battery_status_state state) { - uint8_t level = state.level; - #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - if (level > 95) { - lv_img_set_src(icon, state.usb_present ? &batt_100_chg : &batt_100); - } else if (level > 74) { - lv_img_set_src(icon, state.usb_present ? &batt_75_chg : &batt_75); - } else if (level > 49) { - lv_img_set_src(icon, state.usb_present ? &batt_50_chg : &batt_50); - } else if (level > 24) { - lv_img_set_src(icon, state.usb_present ? &batt_25_chg : &batt_25); + static uint8_t stage_prev = 255; + static bool usb_prev = false; + + uint8_t level = state.level; + bool usb_present = state.usb_present; + uint8_t stage; + + if (level > 87) { + stage = 5; + } else if (level > 62) { + stage = 4; + } else if (level > 37) { + stage = 3; + } else if (level > 12) { + stage = 2; } else if (level > 5) { - lv_img_set_src(icon, state.usb_present ? &batt_5_chg : &batt_5); + stage = 1; } else { - lv_img_set_src(icon, state.usb_present ? &batt_0_chg : &batt_0); + stage = 0; + } + + // check if there is a change requiring an update + if (usb_present != usb_prev || stage != stage_prev) { + switch (stage) { + case 5: + lv_img_set_src(icon, usb_present ? &batt_100_chg : &batt_100); + break; + case 4: + lv_img_set_src(icon, usb_present ? &batt_75_chg : &batt_75); + break; + case 3: + lv_img_set_src(icon, usb_present ? &batt_50_chg : &batt_50); + break; + case 2: + lv_img_set_src(icon, usb_present ? &batt_25_chg : &batt_25); + break; + case 1: + lv_img_set_src(icon, usb_present ? &batt_5_chg : &batt_5); + break; + default: + lv_img_set_src(icon, usb_present ? &batt_0_chg : &batt_0); + break; + } + usb_prev = usb_present; + stage_prev = stage; } #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ } diff --git a/app/boards/arm/corneish_zen/widgets/icons/lpkblogo.c b/app/boards/arm/corneish_zen/widgets/icons/lpkblogo.c new file mode 100644 index 00000000000..7809ce20142 --- /dev/null +++ b/app/boards/arm/corneish_zen/widgets/icons/lpkblogo.c @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2021 Darryl deHaan + * SPDX-License-Identifier: MIT + * + */ + +#include + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_LPKBLOGO +#define LV_ATTRIBUTE_IMG_LPKBLOGO +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_LPKBLOGO uint8_t + lpkblogo_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x7f, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0xe0, + 0xc0, 0x00, 0x00, 0x00, 0x60, 0xc7, 0x83, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, + 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, + 0xcf, 0xc3, 0xff, 0xfc, 0x60, 0xcf, 0xc0, 0x00, 0xfc, 0x60, 0xcf, 0xc0, 0x00, 0xfc, 0x60, + 0xcf, 0xc0, 0x00, 0xfc, 0x60, 0xcf, 0xc0, 0x00, 0xfc, 0x60, 0xcf, 0xc3, 0xff, 0xfc, 0x60, + 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, + 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc3, 0xff, 0xfc, 0x60, 0xcf, 0xc0, 0x00, 0x00, 0x60, + 0xcf, 0xc0, 0x00, 0x00, 0x60, 0xcf, 0xc0, 0x00, 0x00, 0x60, 0xcf, 0xc0, 0x00, 0x00, 0x60, + 0xcf, 0xc0, 0x00, 0x00, 0x60, 0xcf, 0xc3, 0xff, 0xf8, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, + 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, 0xcf, 0xc7, 0xff, 0xfc, 0x60, + 0xc7, 0x83, 0xff, 0xf8, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x60, 0xe0, 0x00, 0x00, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xc0, +}; + +const lv_img_dsc_t lpkblogo = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 35, + .header.h = 35, + .data_size = 183, + .data = lpkblogo_map, +}; diff --git a/app/boards/arm/corneish_zen/widgets/icons/miryokulogo.c b/app/boards/arm/corneish_zen/widgets/icons/miryokulogo.c new file mode 100644 index 00000000000..496d9f50415 --- /dev/null +++ b/app/boards/arm/corneish_zen/widgets/icons/miryokulogo.c @@ -0,0 +1,37 @@ +// Copyright 2022 Manna Harbour +// https://github.com/manna-harbour/miryoku + +#include "lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_MIRYOKULOGO +#define LV_ATTRIBUTE_IMG_MIRYOKULOGO +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_MIRYOKULOGO uint8_t + miryokulogo_map[] = { + 0x04, 0x02, 0x04, 0xff, /*Color of index 0*/ + 0xfc, 0xfe, 0xfc, 0xff, /*Color of index 1*/ + + 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x9f, 0xff, 0xff, + 0xf9, 0x9f, 0xff, 0xff, 0xf9, 0x98, 0x01, 0x99, 0x99, 0x98, 0x01, 0x99, 0x99, 0x99, 0x99, + 0x80, 0x19, 0x99, 0x99, 0x80, 0x19, 0x98, 0x01, 0xf9, 0xf9, 0x98, 0x01, 0xf9, 0xf9, 0x99, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x01, 0x80, 0x19, 0x98, 0x01, 0x80, 0x19, + 0x9f, 0x9f, 0xf9, 0xf9, 0x9f, 0x9f, 0xf9, 0xf9, 0x98, 0x01, 0x80, 0x19, 0x98, 0x01, 0x80, + 0x19, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x81, 0x99, 0x99, 0x99, 0x81, + 0x99, 0x99, 0x99, 0x9f, 0x99, 0x99, 0x99, 0x9f, 0x99, 0x99, 0x99, 0x80, 0x19, 0x99, 0x99, + 0x80, 0x19, 0x99, 0x9f, 0xff, 0xff, 0xf9, 0x9f, 0xff, 0xff, 0xf9, 0x80, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, +}; + +const lv_img_dsc_t miryokulogo = { + .header.always_zero = 0, + .header.w = 32, + .header.h = 32, + .data_size = 136, + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .data = miryokulogo_map, +}; diff --git a/app/boards/arm/corneish_zen/widgets/icons/zmklogo.c b/app/boards/arm/corneish_zen/widgets/icons/zmklogo.c new file mode 100644 index 00000000000..41cc7967c1e --- /dev/null +++ b/app/boards/arm/corneish_zen/widgets/icons/zmklogo.c @@ -0,0 +1,40 @@ +#include "lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_ZMKLOGO +#define LV_ATTRIBUTE_IMG_ZMKLOGO +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_ZMKLOGO uint8_t + zmklogo_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xfe, /*Color of index 1*/ + + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0e, 0x7e, 0x73, 0xc7, 0xe0, 0x04, 0x3c, 0x31, 0x87, + 0xf0, 0x0c, 0x18, 0x31, 0x0f, 0xff, 0x0c, 0x18, 0x30, 0x1f, 0xff, 0x1c, 0x00, 0x30, 0x3f, + 0xfe, 0x3c, 0x00, 0x30, 0x7f, 0xfe, 0x3c, 0x42, 0x30, 0xff, 0xfc, 0x7c, 0x66, 0x30, 0xff, + 0xf8, 0x7c, 0x7e, 0x30, 0x7f, 0xf8, 0xfc, 0x7e, 0x30, 0x3f, 0xf0, 0xfc, 0x7e, 0x30, 0x1f, + 0xf0, 0x0c, 0x7e, 0x31, 0x0f, 0xe0, 0x04, 0x7e, 0x31, 0x87, 0xf0, 0x0e, 0xff, 0x73, 0xc7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +const lv_img_dsc_t zmklogo = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 40, + .header.h = 40, + .data_size = 208, + .data = zmklogo_map, +}; diff --git a/app/boards/arm/corneish_zen/widgets/layer_status.c b/app/boards/arm/corneish_zen/widgets/layer_status.c index 86418318092..f84767da92a 100644 --- a/app/boards/arm/corneish_zen/widgets/layer_status.c +++ b/app/boards/arm/corneish_zen/widgets/layer_status.c @@ -27,6 +27,16 @@ static void set_layer_symbol(lv_obj_t *label, struct layer_status_state state) { const char *layer_label = state.label; uint8_t active_layer_index = state.index; +#if IS_ENABLED(CONFIG_ZMK_DISPLAY_HIDE_MOMENTARY_LAYERS) + static uint8_t last_perm_index = 255; + if (!zmk_keymap_layer_momentary(active_layer_index) && last_perm_index != active_layer_index) { + last_perm_index = active_layer_index; + LOG_DBG("Last perm layer index updated to %i", active_layer_index); + } else { + return; + } +#endif + if (layer_label == NULL) { char text[6] = {}; diff --git a/app/include/zmk/keymap.h b/app/include/zmk/keymap.h index 0d7dbaf33b3..b6bcf6f2356 100644 --- a/app/include/zmk/keymap.h +++ b/app/include/zmk/keymap.h @@ -17,8 +17,10 @@ typedef uint32_t zmk_keymap_layers_state_t; uint8_t zmk_keymap_layer_default(void); zmk_keymap_layers_state_t zmk_keymap_layer_state(void); bool zmk_keymap_layer_active(uint8_t layer); +bool zmk_keymap_layer_momentary(uint8_t layer); +bool zmk_keymap_layers_any_momentary(zmk_keymap_layers_state_t layers_mask); uint8_t zmk_keymap_highest_layer_active(void); -int zmk_keymap_layer_activate(uint8_t layer); +int zmk_keymap_layer_activate(uint8_t layer, bool momentary); int zmk_keymap_layer_deactivate(uint8_t layer); int zmk_keymap_layer_toggle(uint8_t layer); int zmk_keymap_layer_to(uint8_t layer); diff --git a/app/module/drivers/display/Kconfig.il0323 b/app/module/drivers/display/Kconfig.il0323 index f3308c1650d..2704023ce9e 100644 --- a/app/module/drivers/display/Kconfig.il0323 +++ b/app/module/drivers/display/Kconfig.il0323 @@ -8,4 +8,12 @@ config IL0323 depends on SPI depends on HEAP_MEM_POOL_SIZE != 0 help - Enable driver for IL0323 compatible controller. \ No newline at end of file + Enable driver for IL0323 compatible controller. + +config IL0323_INVERT + bool "Invert display" + default n + +config IL0323_ALTERNATIVE_REFRESH + bool "Use an alternative approach for partial refreshes" + default n diff --git a/app/module/drivers/display/il0323.c b/app/module/drivers/display/il0323.c index c9d72fc529b..4eef5cfd36b 100644 --- a/app/module/drivers/display/il0323.c +++ b/app/module/drivers/display/il0323.c @@ -124,7 +124,11 @@ static int il0323_write(const struct device *dev, const uint16_t x, const uint16 ptl[IL0323_PTL_HRED_IDX] = x_end_idx; ptl[IL0323_PTL_VRST_IDX] = y; ptl[IL0323_PTL_VRED_IDX] = y_end_idx; +#if IS_ENABLED(CONFIG_IL0323_ALTERNATIVE_REFRESH) + ptl[sizeof(ptl) - 1] = 0; // limits fading outside of refresh window +#else ptl[sizeof(ptl) - 1] = IL0323_PTL_PT_SCAN; +#endif LOG_HEXDUMP_DBG(ptl, sizeof(ptl), "ptl"); il0323_busy_wait(cfg); @@ -243,8 +247,12 @@ static void il0323_get_capabilities(const struct device *dev, struct display_cap memset(caps, 0, sizeof(struct display_capabilities)); caps->x_resolution = EPD_PANEL_WIDTH; caps->y_resolution = EPD_PANEL_HEIGHT; - caps->supported_pixel_formats = PIXEL_FORMAT_MONO10; + caps->supported_pixel_formats = PIXEL_FORMAT_MONO10 | PIXEL_FORMAT_MONO01; +#if IS_ENABLED(CONFIG_IL0323_INVERT) + caps->current_pixel_format = PIXEL_FORMAT_MONO01; +#else caps->current_pixel_format = PIXEL_FORMAT_MONO10; +#endif caps->screen_info = SCREEN_INFO_MONO_MSB_FIRST | SCREEN_INFO_EPD; } @@ -255,7 +263,7 @@ static int il0323_set_orientation(const struct device *dev, } static int il0323_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) { - if (pf == PIXEL_FORMAT_MONO10) { + if ((pf == PIXEL_FORMAT_MONO10) || (pf == PIXEL_FORMAT_MONO10)) { return 0; } diff --git a/app/src/behaviors/behavior_momentary_layer.c b/app/src/behaviors/behavior_momentary_layer.c index 0c86e605b55..5d9ec30b90a 100644 --- a/app/src/behaviors/behavior_momentary_layer.c +++ b/app/src/behaviors/behavior_momentary_layer.c @@ -23,7 +23,7 @@ static int behavior_mo_init(const struct device *dev) { return 0; }; static int mo_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d layer %d", event.position, binding->param1); - return zmk_keymap_layer_activate(binding->param1); + return zmk_keymap_layer_activate(binding->param1, true); } static int mo_keymap_binding_released(struct zmk_behavior_binding *binding, diff --git a/app/src/conditional_layer.c b/app/src/conditional_layer.c index 9ba02a5ce4c..f575205a163 100644 --- a/app/src/conditional_layer.c +++ b/app/src/conditional_layer.c @@ -49,12 +49,12 @@ static const struct conditional_layer_cfg CONDITIONAL_LAYER_CFGS[] = { static const int32_t NUM_CONDITIONAL_LAYER_CFGS = sizeof(CONDITIONAL_LAYER_CFGS) / sizeof(*CONDITIONAL_LAYER_CFGS); -static void conditional_layer_activate(int8_t layer) { +static void conditional_layer_activate(int8_t layer, bool momentary) { // This may trigger another event that could, in turn, activate additional then-layers. However, // the process will eventually terminate (at worst, when every layer is active). if (!zmk_keymap_layer_active(layer)) { LOG_DBG("layer %d", layer); - zmk_keymap_layer_activate(layer); + zmk_keymap_layer_activate(layer, momentary); } } @@ -84,6 +84,7 @@ static int layer_state_changed_listener(const zmk_event_t *ev) { int8_t max_then_layer = -1; uint32_t then_layers = 0; uint32_t then_layer_state = 0; + uint32_t momentariness_state = 0; conditional_layer_updates_needed = false; @@ -100,13 +101,17 @@ static int layer_state_changed_listener(const zmk_event_t *ev) { // also trigger activation of another. if ((zmk_keymap_layer_state() & mask) == mask) { then_layer_state |= BIT(cfg->then_layer); + if (zmk_keymap_layers_any_momentary(mask)) { + momentariness_state |= BIT(cfg->then_layer); + } } } for (uint8_t layer = 0; layer <= max_then_layer; layer++) { if ((BIT(layer) & then_layers) != 0U) { if ((BIT(layer) & then_layer_state) != 0U) { - conditional_layer_activate(layer); + bool momentary = BIT(layer) & momentariness_state; + conditional_layer_activate(layer, momentary); } else { conditional_layer_deactivate(layer); } diff --git a/app/src/display/Kconfig b/app/src/display/Kconfig index 1cde0fe4e29..d138accfddb 100644 --- a/app/src/display/Kconfig +++ b/app/src/display/Kconfig @@ -172,6 +172,17 @@ choice ZMK_LV_FONT_DEFAULT_SMALL select LV_FONT_UNSCII_16 endchoice +config ZMK_DISPLAY_FULL_REFRESH_PERIOD + int "(Optional) Period to issue a full refresh to the display (in seconds)" + default 0 + help + Period in seconds for how often to completely refresh/redraw the whole screen. + Most useful for e-ink/EPD displays that require occasional full redraws. + +config ZMK_DISPLAY_HIDE_MOMENTARY_LAYERS + bool "Do not update layer widget for momentary layer changes" + default n + rsource "widgets/Kconfig" endif diff --git a/app/src/display/main.c b/app/src/display/main.c index e15e2de0c9a..7666784b452 100644 --- a/app/src/display/main.c +++ b/app/src/display/main.c @@ -50,6 +50,17 @@ struct k_work_q *zmk_display_work_q() { #endif } +#if CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD > 0 +void full_refresh_work_cb(struct k_work *work) { lv_obj_invalidate(lv_scr_act()); } + +K_WORK_DEFINE(full_refresh_work, full_refresh_work_cb); + +void full_refresh_timer_cb() { k_work_submit_to_queue(zmk_display_work_q(), &full_refresh_work); } + +K_TIMER_DEFINE(full_refresh_timer, full_refresh_timer_cb, NULL); + +#endif + void display_timer_cb() { k_work_submit_to_queue(zmk_display_work_q(), &display_tick_work); } K_TIMER_DEFINE(display_timer, display_timer_cb, NULL); @@ -57,6 +68,10 @@ K_TIMER_DEFINE(display_timer, display_timer_cb, NULL); void unblank_display_cb(struct k_work *work) { display_blanking_off(display); k_timer_start(&display_timer, K_MSEC(TICK_MS), K_MSEC(TICK_MS)); +#if CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD > 0 + k_timer_start(&full_refresh_timer, K_SECONDS(CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD), + K_SECONDS(CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD)); +#endif } #if IS_ENABLED(CONFIG_ZMK_DISPLAY_BLANK_ON_IDLE) @@ -64,6 +79,9 @@ void unblank_display_cb(struct k_work *work) { void blank_display_cb(struct k_work *work) { k_timer_stop(&display_timer); display_blanking_on(display); +#if CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD > 0 + k_timer_stop(&full_refresh_timer); +#endif } K_WORK_DEFINE(blank_display_work, blank_display_cb); K_WORK_DEFINE(unblank_display_work, unblank_display_cb); diff --git a/app/src/keymap.c b/app/src/keymap.c index 94bd12048cf..b081cb43ea3 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -27,6 +27,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include static zmk_keymap_layers_state_t _zmk_keymap_layer_state = 0; +static zmk_keymap_layers_state_t _zmk_keymap_layer_momentary = 0; static uint8_t _zmk_keymap_layer_default = 0; #define DT_DRV_COMPAT zmk_keymap @@ -81,7 +82,7 @@ static struct zmk_behavior_binding #endif /* ZMK_KEYMAP_HAS_SENSORS */ -static inline int set_layer_state(uint8_t layer, bool state) { +static inline int set_layer_state(uint8_t layer, bool state, bool momentary) { int ret = 0; if (layer >= ZMK_KEYMAP_LAYERS_LEN) { return -EINVAL; @@ -97,6 +98,7 @@ static inline int set_layer_state(uint8_t layer, bool state) { // Don't send state changes unless there was an actual change if (old_state != _zmk_keymap_layer_state) { LOG_DBG("layer_changed: layer %d state %d", layer, state); + WRITE_BIT(_zmk_keymap_layer_momentary, layer, momentary); ret = raise_layer_state_changed(layer, state); if (ret < 0) { LOG_WRN("Failed to raise layer state changed (%d)", ret); @@ -120,6 +122,15 @@ bool zmk_keymap_layer_active(uint8_t layer) { return zmk_keymap_layer_active_with_state(layer, _zmk_keymap_layer_state); }; +bool zmk_keymap_layer_momentary(uint8_t layer) { + return layer != _zmk_keymap_layer_default && + (_zmk_keymap_layer_momentary & (BIT(layer))) == (BIT(layer)); +}; + +bool zmk_keymap_layers_any_momentary(zmk_keymap_layers_state_t layers_mask) { + return (_zmk_keymap_layer_momentary & layers_mask) > 0; +}; + uint8_t zmk_keymap_highest_layer_active(void) { for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) { if (zmk_keymap_layer_active(layer)) { @@ -129,16 +140,18 @@ uint8_t zmk_keymap_highest_layer_active(void) { return zmk_keymap_layer_default(); } -int zmk_keymap_layer_activate(uint8_t layer) { return set_layer_state(layer, true); }; +int zmk_keymap_layer_activate(uint8_t layer, bool momentary) { + return set_layer_state(layer, true, momentary); +}; -int zmk_keymap_layer_deactivate(uint8_t layer) { return set_layer_state(layer, false); }; +int zmk_keymap_layer_deactivate(uint8_t layer) { return set_layer_state(layer, false, false); }; int zmk_keymap_layer_toggle(uint8_t layer) { if (zmk_keymap_layer_active(layer)) { return zmk_keymap_layer_deactivate(layer); } - return zmk_keymap_layer_activate(layer); + return zmk_keymap_layer_activate(layer, false); }; int zmk_keymap_layer_to(uint8_t layer) { @@ -146,7 +159,7 @@ int zmk_keymap_layer_to(uint8_t layer) { zmk_keymap_layer_deactivate(i); } - zmk_keymap_layer_activate(layer); + zmk_keymap_layer_activate(layer, false); return 0; }