diff options
Diffstat (limited to 'quantum/led_matrix')
-rw-r--r-- | quantum/led_matrix/led_matrix.c | 92 | ||||
-rw-r--r-- | quantum/led_matrix/led_matrix.h | 24 | ||||
-rw-r--r-- | quantum/led_matrix/led_matrix_drivers.c | 40 |
3 files changed, 152 insertions, 4 deletions
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 577331d916..59bfbdf0db 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -83,6 +83,9 @@ const led_point_t k_led_matrix_center = LED_MATRIX_CENTER; # define LED_MATRIX_DEFAULT_SPD UINT8_MAX / 2 #endif +#if defined(LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL) && (LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL >= LED_MATRIX_MAXIMUM_BRIGHTNESS) +# pragma error("LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL must be less than LED_MATRIX_MAXIMUM_BRIGHTNESS") +#endif // globals led_eeconfig_t led_matrix_eeconfig; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr uint32_t g_led_timer; @@ -94,14 +97,18 @@ last_hit_t g_last_hit_tracker; #endif // LED_MATRIX_KEYREACTIVE_ENABLED // internals +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE +static bool driver_shutdown = false; +#endif static bool suspend_state = false; static uint8_t led_last_enable = UINT8_MAX; static uint8_t led_last_effect = UINT8_MAX; static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false}; static led_task_states led_task_state = SYNCING; -#if LED_MATRIX_TIMEOUT > 0 +#if led_matrix_timeout > 0 static uint32_t led_anykey_timer; -#endif // LED_MATRIX_TIMEOUT > 0 +static uint32_t led_matrix_timeout = LED_MATRIX_TIMEOUT; +#endif // LED_MATRIX_TIMEOUT > 0 // double buffers static uint32_t led_timer_buffer; @@ -116,6 +123,8 @@ const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig); +void led_matrix_increase_val_helper(bool write_to_eeprom); + void eeconfig_update_led_matrix(void) { eeconfig_flush_led_matrix(true); } @@ -223,12 +232,22 @@ void process_led_matrix(uint8_t row, uint8_t col, bool pressed) { #endif // defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_LED_MATRIX_TYPING_HEATMAP) } +void led_matrix_none_indicators(void) { + led_matrix_none_indicators_kb(); + led_matrix_none_indicators_user(); +} + +__attribute__((weak)) void led_matrix_none_indicators_kb(void) {} + +__attribute__((weak)) void led_matrix_none_indicators_user(void) {} + static bool led_matrix_none(effect_params_t *params) { if (!params->init) { return false; } led_matrix_set_value_all(0); + led_matrix_none_indicators(); return false; } @@ -339,10 +358,24 @@ static void led_task_flush(uint8_t effect) { // update last trackers after the first full render so we can init over several frames led_last_effect = effect; led_last_enable = led_matrix_eeconfig.enable; +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE + // exit from shutdown to if neccesary + if (driver_shutdown) { + led_matrix_driver.exit_shutdown(); + driver_shutdown = false; + } +#endif // update pwm buffers led_matrix_update_pwm_buffers(); +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE + // shutdown if neccesary + if (effect == LED_MATRIX_NONE && !driver_shutdown && led_matrix_driver_allow_shutdown()) { + led_matrix_driver_shutdown(); + } +#endif + // next task led_task_state = SYNCING; } @@ -354,8 +387,8 @@ void led_matrix_task(void) { // while suspended and just do a software shutdown. This is a cheap hack for now. bool suspend_backlight = suspend_state || #if LED_MATRIX_TIMEOUT > 0 - (led_anykey_timer > (uint32_t)LED_MATRIX_TIMEOUT) || -#endif // LED_MATRIX_TIMEOUT > 0 + (led_anykey_timer > led_matrix_timeout) || +#endif // led_matrix_timeout > 0 false; uint8_t effect = suspend_backlight || !led_matrix_eeconfig.enable ? 0 : led_matrix_eeconfig.mode; @@ -421,6 +454,9 @@ __attribute__((weak)) bool led_matrix_indicators_advanced_user(uint8_t led_min, void led_matrix_init(void) { led_matrix_driver.init(); +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE + driver_shutdown = false; +#endif #ifdef LED_MATRIX_KEYREACTIVE_ENABLED g_last_hit_tracker.count = 0; @@ -467,6 +503,11 @@ void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) { led_task_state = STARTING; eeconfig_flag_led_matrix(write_to_eeprom); dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable); +#ifdef LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL + while (led_matrix_eeconfig.enable && led_matrix_eeconfig.val <= LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL) { + led_matrix_increase_val_helper(write_to_eeprom); + } +#endif } void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); @@ -478,11 +519,21 @@ void led_matrix_toggle(void) { void led_matrix_enable(void) { led_matrix_enable_noeeprom(); eeconfig_flag_led_matrix(true); +#ifdef LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL + while (led_matrix_eeconfig.val <= LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL) { + led_matrix_increase_val_helper(true); + } +#endif } void led_matrix_enable_noeeprom(void) { if (!led_matrix_eeconfig.enable) led_task_state = STARTING; led_matrix_eeconfig.enable = 1; +#ifdef LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL + while (led_matrix_eeconfig.val <= LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL) { + led_matrix_increase_val_helper(false); + } +#endif } void led_matrix_disable(void) { @@ -567,6 +618,12 @@ uint8_t led_matrix_get_val(void) { } void led_matrix_increase_val_helper(bool write_to_eeprom) { +#ifdef LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL + if (!led_matrix_eeconfig.enable) { + led_matrix_toggle_eeprom_helper(write_to_eeprom); + return; + } +#endif led_matrix_set_val_eeprom_helper(qadd8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); } void led_matrix_increase_val_noeeprom(void) { @@ -578,6 +635,11 @@ void led_matrix_increase_val(void) { void led_matrix_decrease_val_helper(bool write_to_eeprom) { led_matrix_set_val_eeprom_helper(qsub8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); +#ifdef LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL + if (led_matrix_eeconfig.enable && led_matrix_eeconfig.val <= LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL) { + led_matrix_toggle_eeprom_helper(write_to_eeprom); + } +#endif } void led_matrix_decrease_val_noeeprom(void) { led_matrix_decrease_val_helper(false); @@ -639,3 +701,25 @@ void led_matrix_set_flags(led_flags_t flags) { void led_matrix_set_flags_noeeprom(led_flags_t flags) { led_matrix_set_flags_eeprom_helper(flags, false); } + +#if LED_MATRIX_TIMEOUT > 0 +void led_matrix_disable_timeout_set(uint32_t timeout) { + led_matrix_timeout = timeout; +} +void led_matrix_disable_time_reset(void){ + led_anykey_timer = 0; +} +#endif + +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE +void led_matrix_driver_shutdown(void) { + led_matrix_driver.shutdown(); + driver_shutdown = true; +}; + +bool led_matrix_is_driver_shutdown(void) { + return driver_shutdown; +} + +__attribute__((weak)) bool led_matrix_driver_allow_shutdown(void) { return true; }; +#endif diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h index c7d360f366..5f3088514c 100644 --- a/quantum/led_matrix/led_matrix.h +++ b/quantum/led_matrix/led_matrix.h @@ -78,6 +78,8 @@ #define LED_MATRIX_TEST_LED_FLAGS() \ if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) continue +#define LED_MATRIX_TIMEOUT_INFINITE (UINT32_MAX) + enum led_matrix_effects { LED_MATRIX_NONE = 0, @@ -117,6 +119,9 @@ void process_led_matrix(uint8_t row, uint8_t col, bool pressed); void led_matrix_task(void); +void led_matrix_none_indicators_kb(void); +void led_matrix_none_indicators_user(void); + // This runs after another backlight effect and replaces // values already set void led_matrix_indicators(void); @@ -163,6 +168,19 @@ led_flags_t led_matrix_get_flags(void); void led_matrix_set_flags(led_flags_t flags); void led_matrix_set_flags_noeeprom(led_flags_t flags); +#ifdef LED_DISABLE_TIMEOUT +# if LED_DISABLE_TIMEOUT > 0 +void led_matrix_disable_timeout_set(uint32_t timeout); +void led_matrix_disable_time_reset(void); +# endif +#endif + +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE +void led_matrix_driver_shutdown(void); +bool led_matrix_is_driver_shutdown(void); +bool led_matrix_driver_allow_shutdown(void); +#endif + typedef struct { /* Perform any initialisation required for the other driver functions to work. */ void (*init)(void); @@ -173,6 +191,12 @@ typedef struct { void (*set_value_all)(uint8_t value); /* Flush any buffered changes to the hardware. */ void (*flush)(void); +#ifdef LED_MATRIX_DRIVER_SHUTDOWN_ENABLE + /* Shutdown the driver. */ + void (*shutdown)(void); + /* Exit from shutdown state. */ + void (*exit_shutdown)(void); +#endif } led_matrix_driver_t; static inline bool led_matrix_check_finished_leds(uint8_t led_idx) { diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c index 2c09ba82b1..eb0f2e4ad5 100644 --- a/quantum/led_matrix/led_matrix_drivers.c +++ b/quantum/led_matrix/led_matrix_drivers.c @@ -237,11 +237,51 @@ static void flush(void) { # endif } +# if defined(LED_MATRIX_DRIVER_SHUTDOWN_ENABLE) +static void shutdown(void) { +# if defined(LED_DRIVER_SHUTDOWN_PIN) + writePinLow(LED_DRIVER_SHUTDOWN_PIN); +# else + CKLED2001_sw_shutdown(DRIVER_ADDR_1); +# if defined(DRIVER_ADDR_2) + CKLED2001_sw_shutdown(DRIVER_ADDR_2); +# if defined(DRIVER_ADDR_3) + CKLED2001_sw_shutdown(DRIVER_ADDR_3); +# if defined(DRIVER_ADDR_4) + CKLED2001_sw_shutdown(DRIVER_ADDR_4); +# endif +# endif +# endif +# endif +} + +static void exit_shutdown(void) { +# if defined(LED_DRIVER_SHUTDOWN_PIN) + writePinHigh(LED_DRIVER_SHUTDOWN_PIN); +# else + CKLED2001_sw_return_normal(DRIVER_ADDR_1); +# if defined(DRIVER_ADDR_2) + CKLED2001_sw_return_normal(DRIVER_ADDR_2); +# if defined(DRIVER_ADDR_3) + CKLED2001_sw_return_normal(DRIVER_ADDR_3); +# if defined(DRIVER_ADDR_4) + CKLED2001_sw_return_normal(DRIVER_ADDR_4); +# endif +# endif +# endif +# endif +} +# endif + const led_matrix_driver_t led_matrix_driver = { .init = init, .flush = flush, .set_value = CKLED2001_set_value, .set_value_all = CKLED2001_set_value_all, +# if defined(LED_MATRIX_DRIVER_SHUTDOWN_ENABLE) + .shutdown = shutdown, + .exit_shutdown = exit_shutdown +# endif }; # endif #endif |