diff options
Diffstat (limited to 'quantum/led_matrix.c')
| -rw-r--r-- | quantum/led_matrix.c | 264 | 
1 files changed, 141 insertions, 123 deletions
| diff --git a/quantum/led_matrix.c b/quantum/led_matrix.c index 4f1f06c7ac..e133764556 100644 --- a/quantum/led_matrix.c +++ b/quantum/led_matrix.c @@ -17,15 +17,15 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#include <stdint.h> -#include <stdbool.h> -#include "quantum.h"  #include "led_matrix.h"  #include "progmem.h"  #include "config.h"  #include "eeprom.h"  #include <string.h>  #include <math.h> +#include "led_tables.h" + +#include <lib/lib8tion/lib8tion.h>  led_eeconfig_t led_matrix_eeconfig; @@ -37,20 +37,41 @@ led_eeconfig_t led_matrix_eeconfig;  #    define MIN(a, b) ((a) < (b) ? (a) : (b))  #endif -#ifndef LED_DISABLE_AFTER_TIMEOUT -#    define LED_DISABLE_AFTER_TIMEOUT 0 +#if defined(LED_DISABLE_AFTER_TIMEOUT) && !defined(LED_DISABLE_TIMEOUT) +#    define LED_DISABLE_TIMEOUT (LED_DISABLE_AFTER_TIMEOUT * 1200UL) +#endif + +#ifndef LED_DISABLE_TIMEOUT +#    define LED_DISABLE_TIMEOUT 0  #endif  #ifndef LED_DISABLE_WHEN_USB_SUSPENDED  #    define LED_DISABLE_WHEN_USB_SUSPENDED false  #endif -#ifndef EECONFIG_LED_MATRIX -#    define EECONFIG_LED_MATRIX EECONFIG_RGBLIGHT +#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX +#    undef LED_MATRIX_MAXIMUM_BRIGHTNESS +#    define LED_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX +#endif + +#if !defined(LED_MATRIX_VAL_STEP) +#    define LED_MATRIX_VAL_STEP 8 +#endif + +#if !defined(LED_MATRIX_SPD_STEP) +#    define LED_MATRIX_SPD_STEP 16 +#endif + +#if !defined(LED_MATRIX_STARTUP_MODE) +#    define LED_MATRIX_STARTUP_MODE LED_MATRIX_UNIFORM_BRIGHTNESS  #endif -#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > 255 -#    define LED_MATRIX_MAXIMUM_BRIGHTNESS 255 +#if !defined(LED_MATRIX_STARTUP_VAL) +#    define LED_MATRIX_STARTUP_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS +#endif + +#if !defined(LED_MATRIX_STARTUP_SPD) +#    define LED_MATRIX_STARTUP_SPD UINT8_MAX / 2  #endif  bool g_suspend_state = false; @@ -64,21 +85,21 @@ uint8_t g_key_hit[DRIVER_LED_TOTAL];  // Ticks since any key was last hit.  uint32_t g_any_key_hit = 0; -uint32_t eeconfig_read_led_matrix(void) { return eeprom_read_dword(EECONFIG_LED_MATRIX); } +void eeconfig_read_led_matrix(void) { eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); } -void eeconfig_update_led_matrix(uint32_t config_value) { eeprom_update_dword(EECONFIG_LED_MATRIX, config_value); } +void eeconfig_update_led_matrix(void) { eeprom_update_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }  void eeconfig_update_led_matrix_default(void) {      dprintf("eeconfig_update_led_matrix_default\n");      led_matrix_eeconfig.enable = 1; -    led_matrix_eeconfig.mode   = LED_MATRIX_UNIFORM_BRIGHTNESS; -    led_matrix_eeconfig.val    = 128; -    led_matrix_eeconfig.speed  = 0; -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +    led_matrix_eeconfig.mode   = LED_MATRIX_STARTUP_MODE; +    led_matrix_eeconfig.val    = LED_MATRIX_STARTUP_VAL; +    led_matrix_eeconfig.speed  = LED_MATRIX_STARTUP_SPD; +    eeconfig_update_led_matrix();  }  void eeconfig_debug_led_matrix(void) { -    dprintf("led_matrix_eeconfig eeprom\n"); +    dprintf("led_matrix_eeconfig EEPROM\n");      dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable);      dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode);      dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val); @@ -88,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; @@ -100,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]; @@ -120,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; @@ -129,13 +164,20 @@ 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); }  // Uniform brightness -void led_matrix_uniform_brightness(void) { led_matrix_set_index_value_all(LED_MATRIX_MAXIMUM_BRIGHTNESS / BACKLIGHT_LEVELS * led_matrix_eeconfig.val); } +void led_matrix_uniform_brightness(void) { led_matrix_set_index_value_all(led_matrix_eeconfig.val); }  void led_matrix_custom(void) {} @@ -161,7 +203,7 @@ void led_matrix_task(void) {      // Ideally we would also stop sending zeros to the LED driver PWM buffers      // while suspended and just do a software shutdown. This is a cheap hack for now. -    bool    suspend_backlight = ((g_suspend_state && LED_DISABLE_WHEN_USB_SUSPENDED) || (LED_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > LED_DISABLE_AFTER_TIMEOUT * 60 * 20)); +    bool    suspend_backlight = ((g_suspend_state && LED_DISABLE_WHEN_USB_SUSPENDED) || (LED_DISABLE_TIMEOUT > 0 && g_any_key_hit > LED_DISABLE_TIMEOUT));      uint8_t effect            = suspend_backlight ? 0 : led_matrix_eeconfig.mode;      // this gets ticked at 20 Hz. @@ -193,23 +235,6 @@ __attribute__((weak)) void led_matrix_indicators_kb(void) {}  __attribute__((weak)) void led_matrix_indicators_user(void) {} -// void led_matrix_set_indicator_index(uint8_t *index, uint8_t row, uint8_t column) -// { -//  if (row >= MATRIX_ROWS) -//  { -//      // Special value, 255=none, 254=all -//      *index = row; -//  } -//  else -//  { -//      // This needs updated to something like -//      // uint8_t led[8]; -//      // uint8_t led_count = map_row_column_to_led(row, column, led); -//      // for(uint8_t i = 0; i < led_count; i++) -//      map_row_column_to_led(row, column, index); -//  } -// } -  void led_matrix_init(void) {      led_matrix_driver.init(); @@ -227,122 +252,115 @@ void led_matrix_init(void) {          eeconfig_update_led_matrix_default();      } -    led_matrix_eeconfig.raw = eeconfig_read_led_matrix(); - +    eeconfig_read_led_matrix();      if (!led_matrix_eeconfig.mode) {          dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");          eeconfig_update_led_matrix_default(); -        led_matrix_eeconfig.raw = eeconfig_read_led_matrix();      }      eeconfig_debug_led_matrix();  // display current eeprom values  } -// Deals with the messy details of incrementing an integer -static uint8_t increment(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { -    int16_t new_value = value; -    new_value += step; -    return MIN(MAX(new_value, min), max); -} - -static uint8_t decrement(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { -    int16_t new_value = value; -    new_value -= step; -    return MIN(MAX(new_value, min), max); -} - -// void *backlight_get_custom_key_value_eeprom_address(uint8_t led) { -//     // 3 bytes per value -//     return EECONFIG_LED_MATRIX + (led * 3); -// } - -// void backlight_get_key_value(uint8_t led, uint8_t *value) { -//     void *address = backlight_get_custom_key_value_eeprom_address(led); -//     value = eeprom_read_byte(address); -// } - -// void backlight_set_key_value(uint8_t row, uint8_t column, uint8_t value) { -//     uint8_t led[8]; -//     uint8_t led_count = map_row_column_to_led(row, column, led); -//     for(uint8_t i = 0; i < led_count; i++) { -//         if (led[i] < DRIVER_LED_TOTAL) { -//             void *address = backlight_get_custom_key_value_eeprom_address(led[i]); -//             eeprom_update_byte(address, value); -//         } -//     } -// } - -uint32_t led_matrix_get_tick(void) { return g_tick; } - -void led_matrix_toggle(void) { +void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) {      led_matrix_eeconfig.enable ^= 1; -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +    if (write_to_eeprom) { +        eeconfig_update_led_matrix(); +    } +    dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable);  } +void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); } +void led_matrix_toggle(void) { led_matrix_toggle_eeprom_helper(true); }  void led_matrix_enable(void) { -    led_matrix_eeconfig.enable = 1; -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +    led_matrix_enable_noeeprom(); +    eeconfig_update_led_matrix();  }  void led_matrix_enable_noeeprom(void) { led_matrix_eeconfig.enable = 1; }  void led_matrix_disable(void) { -    led_matrix_eeconfig.enable = 0; -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +    led_matrix_disable_noeeprom(); +    eeconfig_update_led_matrix();  }  void led_matrix_disable_noeeprom(void) { led_matrix_eeconfig.enable = 0; } -void led_matrix_step(void) { -    led_matrix_eeconfig.mode++; -    if (led_matrix_eeconfig.mode >= LED_MATRIX_EFFECT_MAX) { -        led_matrix_eeconfig.mode = 1; -    } -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); -} +uint8_t led_matrix_is_enabled(void) { return led_matrix_eeconfig.enable; } -void led_matrix_step_reverse(void) { -    led_matrix_eeconfig.mode--; -    if (led_matrix_eeconfig.mode < 1) { +void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { +    if (!led_matrix_eeconfig.enable) { +        return; +    } +    if (mode < 1) { +        led_matrix_eeconfig.mode = 1; +    } else if (mode >= LED_MATRIX_EFFECT_MAX) {          led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1; +    } else { +        led_matrix_eeconfig.mode = mode;      } -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); -} - -void led_matrix_increase_val(void) { -    led_matrix_eeconfig.val = increment(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +    if (write_to_eeprom) { +        eeconfig_update_led_matrix(); +    } +    dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode);  } +void led_matrix_mode_noeeprom(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, false); } +void led_matrix_mode(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, true); } -void led_matrix_decrease_val(void) { -    led_matrix_eeconfig.val = decrement(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); -} +uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; } -void led_matrix_increase_speed(void) { -    led_matrix_eeconfig.speed = increment(led_matrix_eeconfig.speed, 1, 0, 3); -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw);  // EECONFIG needs to be increased to support this +void led_matrix_step_helper(bool write_to_eeprom) { +    uint8_t mode = led_matrix_eeconfig.mode + 1; +    led_matrix_mode_eeprom_helper((mode < LED_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom);  } +void led_matrix_step_noeeprom(void) { led_matrix_step_helper(false); } +void led_matrix_step(void) { led_matrix_step_helper(true); } -void led_matrix_decrease_speed(void) { -    led_matrix_eeconfig.speed = decrement(led_matrix_eeconfig.speed, 1, 0, 3); -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw);  // EECONFIG needs to be increased to support this +void led_matrix_step_reverse_helper(bool write_to_eeprom) { +    uint8_t mode = led_matrix_eeconfig.mode - 1; +    led_matrix_mode_eeprom_helper((mode < 1) ? LED_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom);  } +void led_matrix_step_reverse_noeeprom(void) { led_matrix_step_reverse_helper(false); } +void led_matrix_step_reverse(void) { led_matrix_step_reverse_helper(true); } -void led_matrix_mode(uint8_t mode, bool eeprom_write) { -    led_matrix_eeconfig.mode = mode; -    if (eeprom_write) { -        eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +void led_matrix_set_val_eeprom_helper(uint8_t val, bool write_to_eeprom) { +    if (!led_matrix_eeconfig.enable) { +        return;      } +    led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val; +    if (write_to_eeprom) { +        eeconfig_update_led_matrix(); +    } +    dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val);  } +void led_matrix_set_val_noeeprom(uint8_t val) { led_matrix_set_val_eeprom_helper(val, false); } +void led_matrix_set_val(uint8_t val) { led_matrix_set_val_eeprom_helper(val, true); } -uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; } +uint8_t led_matrix_get_val(void) { return led_matrix_eeconfig.val; } + +void led_matrix_increase_val_helper(bool write_to_eeprom) { 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) { led_matrix_increase_val_helper(false); } +void led_matrix_increase_val(void) { led_matrix_increase_val_helper(true); } -void led_matrix_set_value_noeeprom(uint8_t val) { led_matrix_eeconfig.val = val; } +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); } +void led_matrix_decrease_val_noeeprom(void) { led_matrix_decrease_val_helper(false); } +void led_matrix_decrease_val(void) { led_matrix_decrease_val_helper(true); } -void led_matrix_set_value(uint8_t val) { -    led_matrix_set_value_noeeprom(val); -    eeconfig_update_led_matrix(led_matrix_eeconfig.raw); +void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { +    led_matrix_eeconfig.speed = speed; +    if (write_to_eeprom) { +        eeconfig_update_led_matrix(); +    } +    dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed);  } +void led_matrix_set_speed_noeeprom(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, false); } +void led_matrix_set_speed(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, true); } + +uint8_t led_matrix_get_speed(void) { return led_matrix_eeconfig.speed; } + +void led_matrix_increase_speed_helper(bool write_to_eeprom) { led_matrix_set_speed_eeprom_helper(qadd8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); } +void led_matrix_increase_speed_noeeprom(void) { led_matrix_increase_speed_helper(false); } +void led_matrix_increase_speed(void) { led_matrix_increase_speed_helper(true); } -void backlight_set(uint8_t val) { led_matrix_set_value(val); } +void led_matrix_decrease_speed_helper(bool write_to_eeprom) { led_matrix_set_speed_eeprom_helper(qsub8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); } +void led_matrix_decrease_speed_noeeprom(void) { led_matrix_decrease_speed_helper(false); } +void led_matrix_decrease_speed(void) { led_matrix_decrease_speed_helper(true); } | 
