From 541350ed0b344cc03a9610d8d76f03a654a56d45 Mon Sep 17 00:00:00 2001 From: coltontcrowe Date: Sat, 21 Aug 2021 04:05:11 +0000 Subject: [PATCH 1/3] perf: use integers to convert hsb to rgb Some values with new formatting are off by 1 --- app/src/rgb_underglow.c | 59 ++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 5f38aba7..d3a5f36a 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -27,6 +27,9 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define HUE_MAX 360 #define SAT_MAX 100 #define BRT_MAX 100 +#define RGB_MAX 255 +#define NUM_SEG 6 // Number of segments on color wheel +#define DEG_SEG (HUE_MAX / NUM_SEG) // degrees per color wheel segment enum rgb_underglow_effect { UNDERGLOW_EFFECT_SOLID, @@ -55,51 +58,47 @@ static const struct device *ext_power; #endif static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { - double r, g, b; + uint32_t i = hsb.h / DEG_SEG; + uint32_t f = hsb.h % DEG_SEG; + uint32_t v = hsb.b * RGB_MAX / BRT_MAX; + uint32_t p = v * (SAT_MAX - hsb.s) / SAT_MAX; + uint32_t q = v * (SAT_MAX * DEG_SEG - f * hsb.s) / SAT_MAX / DEG_SEG; + uint32_t t = v * (SAT_MAX * DEG_SEG - (DEG_SEG - f) * hsb.s) / SAT_MAX / DEG_SEG; + struct led_rgb rgb; - uint8_t i = hsb.h / 60; - double v = hsb.b / ((float)BRT_MAX); - double s = hsb.s / ((float)SAT_MAX); - double f = hsb.h / ((float)HUE_MAX) * 6 - i; - double p = v * (1 - s); - double q = v * (1 - f * s); - double t = v * (1 - (1 - f) * s); - - switch (i % 6) { + switch (i) { case 0: - r = v; - g = t; - b = p; + rgb.r = (uint8_t)v; + rgb.g = (uint8_t)t; + rgb.b = (uint8_t)p; break; case 1: - r = q; - g = v; - b = p; + rgb.r = (uint8_t)q; + rgb.g = (uint8_t)v; + rgb.b = (uint8_t)p; break; case 2: - r = p; - g = v; - b = t; + rgb.r = (uint8_t)p; + rgb.g = (uint8_t)v; + rgb.b = (uint8_t)t; break; case 3: - r = p; - g = q; - b = v; + rgb.r = (uint8_t)p; + rgb.g = (uint8_t)q; + rgb.b = (uint8_t)v; break; case 4: - r = t; - g = p; - b = v; + rgb.r = (uint8_t)t; + rgb.g = (uint8_t)p; + rgb.b = (uint8_t)v; break; case 5: - r = v; - g = p; - b = q; + rgb.r = (uint8_t)v; + rgb.g = (uint8_t)p; + rgb.b = (uint8_t)q; break; } - struct led_rgb rgb = {r : r * 255, g : g * 255, b : b * 255}; - return rgb; } From 63c60b689e5ec20512797e8e0c5ea97f973cf4be Mon Sep 17 00:00:00 2001 From: coltontcrowe Date: Sun, 29 Aug 2021 09:11:05 +0000 Subject: [PATCH 2/3] fix: clean up most rounding errors --- app/src/rgb_underglow.c | 53 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index d3a5f36a..31d7d9f6 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -25,8 +25,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define STRIP_NUM_PIXELS DT_PROP(DT_CHOSEN(zmk_underglow), chain_length) #define HUE_MAX 360 -#define SAT_MAX 100 -#define BRT_MAX 100 +#define SAT_MAX 101 +#define BRT_MAX 101 #define RGB_MAX 255 #define NUM_SEG 6 // Number of segments on color wheel #define DEG_SEG (HUE_MAX / NUM_SEG) // degrees per color wheel segment @@ -58,44 +58,45 @@ static const struct device *ext_power; #endif static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { - uint32_t i = hsb.h / DEG_SEG; - uint32_t f = hsb.h % DEG_SEG; - uint32_t v = hsb.b * RGB_MAX / BRT_MAX; - uint32_t p = v * (SAT_MAX - hsb.s) / SAT_MAX; - uint32_t q = v * (SAT_MAX * DEG_SEG - f * hsb.s) / SAT_MAX / DEG_SEG; - uint32_t t = v * (SAT_MAX * DEG_SEG - (DEG_SEG - f) * hsb.s) / SAT_MAX / DEG_SEG; + uint8_t i = hsb.h / DEG_SEG; + uint8_t f = hsb.h % DEG_SEG; + uint8_t v = hsb.b * RGB_MAX / BRT_MAX; + uint8_t p = hsb.b * RGB_MAX * (SAT_MAX - hsb.s) / SAT_MAX / BRT_MAX; + uint8_t q = hsb.b * RGB_MAX * (SAT_MAX * DEG_SEG - f * hsb.s) / SAT_MAX / DEG_SEG / BRT_MAX; + uint8_t t = + hsb.b * RGB_MAX * (SAT_MAX * DEG_SEG - (DEG_SEG - f) * hsb.s) / SAT_MAX / DEG_SEG / BRT_MAX; struct led_rgb rgb; switch (i) { case 0: - rgb.r = (uint8_t)v; - rgb.g = (uint8_t)t; - rgb.b = (uint8_t)p; + rgb.r = v; + rgb.g = t; + rgb.b = p; break; case 1: - rgb.r = (uint8_t)q; - rgb.g = (uint8_t)v; - rgb.b = (uint8_t)p; + rgb.r = q; + rgb.g = v; + rgb.b = p; break; case 2: - rgb.r = (uint8_t)p; - rgb.g = (uint8_t)v; - rgb.b = (uint8_t)t; + rgb.r = p; + rgb.g = v; + rgb.b = t; break; case 3: - rgb.r = (uint8_t)p; - rgb.g = (uint8_t)q; - rgb.b = (uint8_t)v; + rgb.r = p; + rgb.g = q; + rgb.b = v; break; case 4: - rgb.r = (uint8_t)t; - rgb.g = (uint8_t)p; - rgb.b = (uint8_t)v; + rgb.r = t; + rgb.g = p; + rgb.b = v; break; case 5: - rgb.r = (uint8_t)v; - rgb.g = (uint8_t)p; - rgb.b = (uint8_t)q; + rgb.r = v; + rgb.g = p; + rgb.b = q; break; } From 7dc8c8fdffb69d623186d5847dd0ff6f74d92990 Mon Sep 17 00:00:00 2001 From: coltontcrowe Date: Mon, 4 Oct 2021 02:56:21 +0000 Subject: [PATCH 3/3] feat: allow configuring fpu for rgb conversion --- app/src/rgb_underglow.c | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 31d7d9f6..983dcc40 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -57,6 +57,56 @@ static struct rgb_underglow_state state; static const struct device *ext_power; #endif +#if IS_ENABLED(CONFIG_FPU) +static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { + double r, g, b; + + uint8_t i = hsb.h / 60; + double v = hsb.b / ((float)BRT_MAX); + double s = hsb.s / ((float)SAT_MAX); + double f = hsb.h / ((float)HUE_MAX) * 6 - i; + double p = v * (1 - s); + double q = v * (1 - f * s); + double t = v * (1 - (1 - f) * s); + + switch (i % 6) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + + struct led_rgb rgb = {r : r * 255, g : g * 255, b : b * 255}; + + return rgb; +} +#else static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { uint8_t i = hsb.h / DEG_SEG; uint8_t f = hsb.h % DEG_SEG; @@ -102,6 +152,7 @@ static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { return rgb; } +#endif static void zmk_rgb_underglow_effect_solid() { for (int i = 0; i < STRIP_NUM_PIXELS; i++) {