From 6f9a411793dfc31af17ff4a48e01e628a94a3065 Mon Sep 17 00:00:00 2001 From: darknao Date: Sun, 5 May 2024 18:52:44 +0200 Subject: [PATCH] underglow-layer: use devicetree & clean up code --- app/CMakeLists.txt | 1 + app/dts/bindings/zmk,underglow-layer.yaml | 15 ++ app/include/dt-bindings/zmk/rgb_colors.h | 17 +++ app/include/zmk/rgb_underglow_layer.h | 18 +++ app/src/rgb_underglow.c | 158 ++++++---------------- app/src/rgb_underglow_layer.c | 65 +++++++++ 6 files changed, 154 insertions(+), 120 deletions(-) create mode 100644 app/dts/bindings/zmk,underglow-layer.yaml create mode 100644 app/include/dt-bindings/zmk/rgb_colors.h create mode 100644 app/include/zmk/rgb_underglow_layer.h create mode 100644 app/src/rgb_underglow_layer.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 60c502fc..3d78f066 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -101,6 +101,7 @@ add_subdirectory_ifdef(CONFIG_ZMK_SPLIT src/split) target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/usb.c) target_sources_ifdef(CONFIG_ZMK_USB app PRIVATE src/usb_hid.c) target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c) +target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow_layer.c) target_sources_ifdef(CONFIG_ZMK_BACKLIGHT app PRIVATE src/backlight.c) target_sources_ifdef(CONFIG_ZMK_LOW_PRIORITY_WORK_QUEUE app PRIVATE src/workqueue.c) target_sources(app PRIVATE src/main.c) diff --git a/app/dts/bindings/zmk,underglow-layer.yaml b/app/dts/bindings/zmk,underglow-layer.yaml new file mode 100644 index 00000000..0f59c89a --- /dev/null +++ b/app/dts/bindings/zmk,underglow-layer.yaml @@ -0,0 +1,15 @@ +description: | + Allows defining a rgbmap composed of multiple layers + +compatible: "zmk,underglow-layer" + +child-binding: + description: "A layer to be used in a rgbmap" + + properties: + bindings: + type: array + required: true + layer-id: + type: int + required: true diff --git a/app/include/dt-bindings/zmk/rgb_colors.h b/app/include/dt-bindings/zmk/rgb_colors.h new file mode 100644 index 00000000..885c82d2 --- /dev/null +++ b/app/include/dt-bindings/zmk/rgb_colors.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define GREEN 0x00ff00 +#define RED 0xff0000 +#define BLUE 0x0000ff +#define TEAL 0x008080 +#define ORANGE 0xffa500 +#define YELLOW 0xffff00 +#define GOLD 0xffd700 +#define PURPLE 0x800080 +#define PINK 0xffc0cb +#define WHITE 0xffffff +#define ______ 0x000000 \ No newline at end of file diff --git a/app/include/zmk/rgb_underglow_layer.h b/app/include/zmk/rgb_underglow_layer.h new file mode 100644 index 00000000..032714eb --- /dev/null +++ b/app/include/zmk/rgb_underglow_layer.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once +#include + + +#define ZMK_RGB_CHILD_LEN_PLUS_ONE(node) 1 + + +#define ZMK_RGBMAP_LAYERS_LEN \ + (DT_FOREACH_CHILD(DT_INST(0, zmk_underglow_layer), ZMK_RGB_CHILD_LEN_PLUS_ONE) 0) + +const int zmk_rgbmap_id(uint8_t layer); +uint32_t *rgb_underglow_get_bindings(void); +uint8_t rgb_underglow_top_layer(void); \ No newline at end of file diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index f9aba88f..7fd0d0c3 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -16,6 +16,8 @@ #include #include #include +#include + #include #include @@ -25,6 +27,7 @@ #include #include +#include #include #include @@ -55,10 +58,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define SAT_MAX 100 #define BRT_MAX 100 -#define LAYER_GAMING 1 -#define LAYER_LOWER 2 -#define LAYER_NUMERIC 3 - BUILD_ASSERT(CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN <= CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX, "ERROR: RGB underglow maximum brightness is less than minimum brightness"); @@ -199,8 +198,6 @@ static void zmk_rgb_underglow_effect_swirl(void) { state.animation_step = state.animation_step % HUE_MAX; } -static bool valdur_layer_active(int layer); - static int zmk_led_generate_status(void); static void zmk_led_write_pixels(void) { @@ -289,12 +286,7 @@ static void zmk_led_write_pixels(void) { #if !UNDERGLOW_INDICATORS_ENABLED static int zmk_led_generate_status(void) { return 0; } -static bool valdur_layer_active(int layer) { return peripheral_layer_active(layer); } - #else - -static bool valdur_layer_active(int layer) { return zmk_keymap_layer_active(layer); } - const uint8_t underglow_layer_state[] = DT_PROP(UNDERGLOW_INDICATORS, layer_state); const uint8_t underglow_ble_state[] = DT_PROP(UNDERGLOW_INDICATORS, ble_state); const uint8_t underglow_bat_lhs[] = DT_PROP(UNDERGLOW_INDICATORS, bat_lhs); @@ -444,119 +436,45 @@ static inline struct led_rgb hue_sat(int hue, int sat) { return hsb_to_rgb(hsb_scale_min_max(hsb)); } -#define MK_GREEN hue_sat(150, 100) -#define MK_RED hue_sat(348, 100) -#define MK_BLUE hue_sat(194, 100) -#define MK_ORANGE hue_sat(20, 100) -#define MK_YELLOW hue_sat(51, 100) -#define MK_PURPLE hue_sat(267, 60) -#define MK_WHITE hue_sat(0, 0); +static struct led_rgb hex_to_rgb(uint8_t r, uint8_t g, uint8_t b) { + struct zmk_led_hsb hsb = state.color; + return (struct led_rgb){ + r : (hsb.b * (r)) / 0xff, + g : (hsb.b * (g)) / 0xff, + b : (hsb.b * (b)) / 0xff + }; +} -/* - MoErgo 40 LEDs - - 34 28 22 16 10 10 16 22 28 34 - 35 29 23 17 11 6 6 11 17 23 29 35 - 36 30 24 18 12 7 7 12 18 24 30 36 - 37 31 25 19 13 8 8 13 19 25 31 37 - 38 32 26 20 14 9 9 14 20 26 32 38 - 39 33 27 21 15 15 21 27 33 39 - 0 1 2 2 1 0 - 3 4 5 5 4 3 -*/ - -static void valdur_indicate_custom_layers(void) { +static void zmk_rgb_underglow_apply_rgbmap(uint32_t rgbmap[], size_t rgbmap_len) { +// TODO: Glove80 specifics, move that part to board's devicetree +#ifdef LEFT_HALF + const uint8_t LED_MATRIX[] = {52, 53, 54, 69, 70, 71, 15, 27, 39, 51, 4, 14, 26, 38, + 50, 68, 3, 13, 25, 37, 49, 67, 2, 12, 24, 36, 48, 66, + 1, 11, 23, 35, 47, 65, 0, 10, 22, 34, 46, 64}; +#else + const uint8_t LED_MATRIX[] = {57, 56, 55, 74, 73, 72, 16, 28, 40, 58, 5, 17, 29, 41, + 59, 75, 6, 18, 30, 42, 60, 76, 7, 19, 31, 43, 61, 77, + 8, 20, 32, 44, 62, 78, 9, 21, 33, 45, 63, 79}; +#endif for (int i = 0; i < STRIP_NUM_PIXELS; i++) { - pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0}; + uint8_t midx = LED_MATRIX[i]; + if (midx >= ZMK_KEYMAP_LEN) { + LOG_DBG("out of range"); + } else { + pixels[i] = hex_to_rgb((rgbmap[midx] & 0xFF0000) >> 16, (rgbmap[midx] & 0xFF00) >> 8, + rgbmap[midx] & 0xFF); + } } - if (valdur_layer_active(LAYER_NUMERIC)) { - struct led_rgb col_green = MK_GREEN; - struct led_rgb col_yellow = MK_YELLOW; +} -#ifdef LEFT_HALF - // indicator - pixels[36] = col_green; -#endif - - // numbers - pixels[11] = col_green; - pixels[12] = col_green; - pixels[13] = col_green; -#ifdef RIGHT_HALF - pixels[14] = col_green; -#endif - - pixels[17] = col_green; - pixels[18] = col_green; - pixels[19] = col_green; - - pixels[23] = col_green; - pixels[24] = col_green; - pixels[25] = col_green; -#ifdef LEFT_HALF - pixels[26] = col_green; -#endif - - // operators - pixels[31] = col_yellow; - pixels[32] = col_yellow; - pixels[27] = col_yellow; - - pixels[7] = col_yellow; - pixels[8] = col_yellow; - pixels[9] = col_yellow; - - } else if (valdur_layer_active(LAYER_LOWER)) { - struct led_rgb col_orange = MK_ORANGE; - struct led_rgb col_blue = MK_BLUE; - -#ifdef LEFT_HALF - // indicator - pixels[37] = col_orange; -#endif - - // arrows - pixels[18] = col_orange; - pixels[25] = col_orange; - pixels[19] = col_orange; - pixels[13] = col_orange; - - // // ctrl arrows - // pixels[8] = yellow; - // pixels[31] = yellow; - - // home, end, pgup, pgdn - pixels[7] = col_blue; - pixels[8] = col_blue; - pixels[24] = col_blue; - pixels[12] = col_blue; - } else if (valdur_layer_active(LAYER_GAMING)) { - struct led_rgb col_red = MK_RED; - struct led_rgb col_blue = MK_BLUE; -#ifdef LEFT_HALF - - // indicator - pixels[38] = col_red; - - // wsad - pixels[18] = col_red; - pixels[25] = col_red; - pixels[19] = col_red; - pixels[13] = col_red; - - // enter, backspace, delete - pixels[5] = col_blue; - pixels[27] = col_blue; - pixels[33] = col_blue; -#else - pixels[6] = col_red; -#endif +static void zmk_rgb_underglow_set_layer(void) { + uint32_t *rgbmap = rgb_underglow_get_bindings(); + if (rgbmap != NULL) { + zmk_rgb_underglow_apply_rgbmap(rgbmap, ZMK_KEYMAP_LEN); } else { -#ifdef LEFT_HALF - pixels[6] = MK_PURPLE; -#else - pixels[6] = MK_PURPLE; -#endif + for (int i = 0; i < STRIP_NUM_PIXELS; i++) { + pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0}; + } } } @@ -575,7 +493,7 @@ static void zmk_rgb_underglow_tick(struct k_work *work) { zmk_rgb_underglow_effect_swirl(); break; case UNDERGLOW_EFFECT_LAYER_INDICATORS: - valdur_indicate_custom_layers(); + zmk_rgb_underglow_set_layer(); break; } diff --git a/app/src/rgb_underglow_layer.c b/app/src/rgb_underglow_layer.c new file mode 100644 index 00000000..21208b1f --- /dev/null +++ b/app/src/rgb_underglow_layer.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include + +#if !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) +#include +#endif + +#define DT_DRV_COMPAT zmk_underglow_layer + +#define LAYER_ID(node) DT_PROP(node, layer_id) +#define RGB_BINDINGS(node) DT_PROP(node, bindings) + +static uint32_t zmk_rgbmap[ZMK_RGBMAP_LAYERS_LEN][ZMK_KEYMAP_LEN] = { + DT_INST_FOREACH_CHILD_SEP(0, RGB_BINDINGS, (, )) +}; + +static int zmk_rgbmap_ids[ZMK_RGBMAP_LAYERS_LEN] = { + DT_INST_FOREACH_CHILD_SEP(0, LAYER_ID, (, ))}; + + +const int zmk_rgbmap_id(uint8_t layer) { + for (uint8_t i = 0; i < ZMK_RGBMAP_LAYERS_LEN; i++) { + if (zmk_rgbmap_ids[i] == layer) { + return i; + } + } + return -1; +} + +uint32_t *rgb_underglow_get_bindings(void) { + uint8_t layer = rgb_underglow_top_layer(); + int rgblayer = zmk_rgbmap_id(layer); + if (rgblayer == -1){ + return NULL; + } else { + return zmk_rgbmap[rgblayer]; + } +} + +uint8_t rgb_underglow_top_layer(void) { + for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) { +#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) + if (zmk_keymap_layer_active(layer)) { +#else + if (peripheral_layer_active(layer)) { +#endif + return layer; + } + } + return -1; +}