From 40c314fe5c99d6d85039e6155723d2c2506d0d7f Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 7 Apr 2021 20:06:11 +1000 Subject: [PATCH] LED Matrix: Implement CIE1931 curve (#12417) --- common_features.mk | 1 + quantum/led_matrix.c | 38 ++++++++++++++++++++++++++++--------- quantum/led_matrix.h | 45 ++++++++++++++++++++++++++------------------ 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/common_features.mk b/common_features.mk index 2e2991c648b..eb2ea2811fa 100644 --- a/common_features.mk +++ b/common_features.mk @@ -233,6 +233,7 @@ endif SRC += $(QUANTUM_DIR)/process_keycode/process_backlight.c SRC += $(QUANTUM_DIR)/led_matrix.c SRC += $(QUANTUM_DIR)/led_matrix_drivers.c + CIE1931_CURVE := yes ifeq ($(strip $(LED_MATRIX_DRIVER)), IS31FL3731) OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE diff --git a/quantum/led_matrix.c b/quantum/led_matrix.c index ec8ff852d54..e1337645561 100644 --- a/quantum/led_matrix.c +++ b/quantum/led_matrix.c @@ -23,6 +23,7 @@ #include "eeprom.h" #include #include +#include "led_tables.h" #include @@ -108,8 +109,10 @@ void eeconfig_debug_led_matrix(void) { uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255}; uint8_t g_last_led_count = 0; -uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { - uint8_t led_count = 0; +__attribute__((weak)) uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { return 0; } + +uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { + uint8_t led_count = led_matrix_map_row_column_to_led_kb(row, column, led_i); uint8_t led_index = g_led_config.matrix_co[row][column]; if (led_index != NO_LED) { led_i[led_count] = led_index; @@ -120,14 +123,26 @@ uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); } -void led_matrix_set_index_value(int index, uint8_t value) { led_matrix_driver.set_value(index, value); } +void led_matrix_set_value(int index, uint8_t value) { +#ifdef USE_CIE1931_CURVE + led_matrix_driver.set_value(index, pgm_read_byte(&CIE1931_CURVE[value])); +#else + led_matrix_driver.set_value(index, value); +#endif +} -void led_matrix_set_index_value_all(uint8_t value) { led_matrix_driver.set_value_all(value); } +void led_matrix_set_value_all(uint8_t value) { +#ifdef USE_CIE1931_CURVE + led_matrix_driver.set_value_all(pgm_read_byte(&CIE1931_CURVE[value])); +#else + led_matrix_driver.set_value_all(value); +#endif +} bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { uint8_t led[8]; - uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led); + uint8_t led_count = led_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led); if (led_count > 0) { for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) { g_last_led_hit[i - 1] = g_last_led_hit[i - 2]; @@ -140,7 +155,7 @@ bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { } else { #ifdef LED_MATRIX_KEYRELEASES uint8_t led[8]; - uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led); + uint8_t led_count = led_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led); for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 255; g_any_key_hit = 255; @@ -149,7 +164,14 @@ bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { return true; } -void led_matrix_set_suspend_state(bool state) { g_suspend_state = state; } +void led_matrix_set_suspend_state(bool state) { + if (LED_DISABLE_WHEN_USB_SUSPENDED && state) { + led_matrix_set_value_all(0); // turn off all LEDs when suspending + } + g_suspend_state = state; +} + +bool led_matrix_get_suspend_state(void) { return g_suspend_state; } // All LEDs off void led_matrix_all_off(void) { led_matrix_set_index_value_all(0); } @@ -239,8 +261,6 @@ void led_matrix_init(void) { eeconfig_debug_led_matrix(); // display current eeprom values } -uint32_t led_matrix_get_tick(void) { return g_tick; } - void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) { led_matrix_eeconfig.enable ^= 1; if (write_to_eeprom) { diff --git a/quantum/led_matrix.h b/quantum/led_matrix.h index fd7ef7d29e6..ba8f0279a6e 100644 --- a/quantum/led_matrix.h +++ b/quantum/led_matrix.h @@ -36,14 +36,36 @@ # define LED_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 #endif +#if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL +# define LED_MATRIX_USE_LIMITS(min, max) \ + uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter; \ + uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT; \ + if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL; +#else +# define LED_MATRIX_USE_LIMITS(min, max) \ + uint8_t min = 0; \ + uint8_t max = DRIVER_LED_TOTAL; +#endif + enum led_matrix_effects { LED_MATRIX_UNIFORM_BRIGHTNESS = 1, // All new effects go above this line LED_MATRIX_EFFECT_MAX }; -void led_matrix_set_index_value(int index, uint8_t value); -void led_matrix_set_index_value_all(uint8_t value); +void eeconfig_update_led_matrix_default(void); +void eeconfig_update_led_matrix(void); +void eeconfig_debug_led_matrix(void); + +uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); +uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); + +void led_matrix_set_value(int index, uint8_t value); +void led_matrix_set_value_all(uint8_t value); + +bool process_led_matrix(uint16_t keycode, keyrecord_t *record); + +void led_matrix_task(void); // This runs after another backlight effect and replaces // values already set @@ -52,23 +74,9 @@ void led_matrix_indicators_kb(void); void led_matrix_indicators_user(void); void led_matrix_init(void); -void led_matrix_setup_drivers(void); - -void led_matrix_set_suspend_state(bool state); -void led_matrix_set_indicator_state(uint8_t state); - -void led_matrix_task(void); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void led_matrix_update_pwm_buffers(void); - -bool process_led_matrix(uint16_t keycode, keyrecord_t *record); - -uint32_t led_matrix_get_tick(void); +void led_matrix_set_suspend_state(bool state); +bool led_matrix_get_suspend_state(void); void led_matrix_toggle(void); void led_matrix_toggle_noeeprom(void); void led_matrix_enable(void); @@ -114,4 +122,5 @@ extern const led_matrix_driver_t led_matrix_driver; extern led_eeconfig_t led_matrix_eeconfig; +extern bool g_suspend_state; extern led_config_t g_led_config;