summaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/audio/audio.c37
-rw-r--r--quantum/audio/audio.h3
-rw-r--r--quantum/backlight/backlight.c21
-rw-r--r--quantum/backlight/backlight.h2
-rw-r--r--quantum/dip_switch.c57
-rw-r--r--quantum/dip_switch.h27
-rw-r--r--quantum/eeconfig.c2
-rw-r--r--quantum/keyboard.c2
-rw-r--r--quantum/keyboard.h13
-rw-r--r--quantum/keymap_common.c12
-rw-r--r--quantum/keymap_extras/keymap_canadian_french.h122
-rw-r--r--quantum/keymap_extras/keymap_spanish_latin_america.h105
-rw-r--r--quantum/keymap_extras/sendstring_canadian_french.h120
-rw-r--r--quantum/keymap_extras/sendstring_spanish_latin_america.h120
-rw-r--r--quantum/keymap_introspection.c18
-rw-r--r--quantum/keymap_introspection.h12
-rw-r--r--quantum/led_matrix/led_matrix.c41
-rw-r--r--quantum/led_matrix/led_matrix.h41
-rw-r--r--quantum/led_matrix/led_matrix_drivers.c36
-rw-r--r--quantum/led_matrix/led_matrix_drivers.h44
-rw-r--r--quantum/pointing_device/pointing_device.c11
-rw-r--r--quantum/pointing_device/pointing_device_auto_mouse.c15
-rw-r--r--quantum/pointing_device/pointing_device_auto_mouse.h10
-rw-r--r--quantum/process_keycode/process_caps_word.c4
-rw-r--r--quantum/process_keycode/process_midi.c23
-rw-r--r--quantum/process_keycode/process_space_cadet.c6
-rw-r--r--quantum/process_keycode/process_space_cadet.h1
-rw-r--r--quantum/process_keycode/process_tap_dance.c6
-rw-r--r--quantum/process_keycode/process_tap_dance.h4
-rw-r--r--quantum/quantum_keycodes.h4
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_anim.h2
-rw-r--r--quantum/rgb_matrix/rgb_matrix.c27
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h36
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.c44
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.h47
-rw-r--r--quantum/rgblight/rgblight.c71
-rw-r--r--quantum/rgblight/rgblight.h9
-rw-r--r--quantum/rgblight/rgblight_drivers.c20
-rw-r--r--quantum/rgblight/rgblight_drivers.h13
-rw-r--r--quantum/split_common/split_util.c6
40 files changed, 939 insertions, 255 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index 28c8267517..c1a1500493 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -17,6 +17,7 @@
#include "audio.h"
#include "eeconfig.h"
#include "timer.h"
+#include "debug.h"
#include "wait.h"
#include "util.h"
@@ -62,6 +63,13 @@
* the internal state of the audio system does its calculations with the later - ms
*/
+#ifndef AUDIO_DEFAULT_ON
+# define AUDIO_DEFAULT_ON true
+#endif
+#ifndef AUDIO_DEFAULT_CLICKY_ON
+# define AUDIO_DEFAULT_CLICKY_ON true
+#endif
+
#ifndef AUDIO_TONE_STACKSIZE
# define AUDIO_TONE_STACKSIZE 8
#endif
@@ -117,32 +125,31 @@ void eeconfig_update_audio_current(void) {
eeconfig_update_audio(audio_config.raw);
}
+void eeconfig_update_audio_default(void) {
+ audio_config.valid = true;
+ audio_config.enable = AUDIO_DEFAULT_ON;
+ audio_config.clicky_enable = AUDIO_DEFAULT_CLICKY_ON;
+ eeconfig_update_audio(audio_config.raw);
+}
+
void audio_init(void) {
if (audio_initialized) {
return;
}
- // Check EEPROM
-#ifdef EEPROM_ENABLE
- if (!eeconfig_is_enabled()) {
- eeconfig_init();
- }
audio_config.raw = eeconfig_read_audio();
-#else // EEPROM settings
- audio_config.enable = true;
-# ifdef AUDIO_CLICKY_ON
- audio_config.clicky_enable = true;
-# endif
-#endif // EEPROM settings
+ if (!audio_config.valid) {
+ dprintf("audio_init audio_config.valid = 0. Write default values to EEPROM.\n");
+ eeconfig_update_audio_default();
+ }
for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) {
tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
}
- if (!audio_initialized) {
- audio_driver_initialize();
- audio_initialized = true;
- }
+ audio_driver_initialize();
+ audio_initialized = true;
+
stop_all_notes();
#ifndef AUDIO_INIT_DELAY
audio_startup();
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index a4a908b43c..eb0bedc6f9 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -33,7 +33,8 @@ typedef union {
struct {
bool enable : 1;
bool clicky_enable : 1;
- uint8_t level : 6;
+ bool valid : 1;
+ uint8_t reserved : 5;
};
} audio_config_t;
diff --git a/quantum/backlight/backlight.c b/quantum/backlight/backlight.c
index e89b34696c..eb64dd71e8 100644
--- a/quantum/backlight/backlight.c
+++ b/quantum/backlight/backlight.c
@@ -42,20 +42,26 @@ backlight_config_t backlight_config;
static uint8_t breathing_period = BREATHING_PERIOD;
#endif
+static void backlight_check_config(void) {
+ /* Add some out of bound checks for backlight config */
+
+ if (backlight_config.level > BACKLIGHT_LEVELS) {
+ backlight_config.level = BACKLIGHT_LEVELS;
+ }
+}
+
/** \brief Backlight initialization
*
* FIXME: needs doc
*/
void backlight_init(void) {
- /* check signature */
- if (!eeconfig_is_enabled()) {
- eeconfig_init();
- eeconfig_update_backlight_default();
- }
backlight_config.raw = eeconfig_read_backlight();
- if (backlight_config.level > BACKLIGHT_LEVELS) {
- backlight_config.level = BACKLIGHT_LEVELS;
+ if (!backlight_config.valid) {
+ dprintf("backlight_init backlight_config.valid = 0. Write default values to EEPROM.\n");
+ eeconfig_update_backlight_default();
}
+ backlight_check_config();
+
backlight_set(backlight_config.enable ? backlight_config.level : 0);
}
@@ -183,6 +189,7 @@ void eeconfig_update_backlight_current(void) {
}
void eeconfig_update_backlight_default(void) {
+ backlight_config.valid = true;
backlight_config.enable = BACKLIGHT_DEFAULT_ON;
backlight_config.breathing = BACKLIGHT_DEFAULT_BREATHING;
backlight_config.level = BACKLIGHT_DEFAULT_LEVEL;
diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h
index 85812bff3a..c34fb5858d 100644
--- a/quantum/backlight/backlight.h
+++ b/quantum/backlight/backlight.h
@@ -39,7 +39,7 @@ typedef union {
struct {
bool enable : 1;
bool breathing : 1;
- uint8_t reserved : 1; // Reserved for possible future backlight modes
+ bool valid : 1;
uint8_t level : 5;
};
} backlight_config_t;
diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c
index 6e254578d1..e901f3e0c4 100644
--- a/quantum/dip_switch.c
+++ b/quantum/dip_switch.c
@@ -19,8 +19,6 @@
#include <string.h> // for memcpy
#include "dip_switch.h"
-#include "gpio.h"
-#include "util.h"
#ifdef SPLIT_KEYBOARD
# include "split_common/split_util.h"
@@ -35,24 +33,17 @@
#endif
#ifdef DIP_SWITCH_PINS
-# define NUMBER_OF_DIP_SWITCHES (ARRAY_SIZE(dip_switch_pad))
static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
#endif
#ifdef DIP_SWITCH_MATRIX_GRID
-typedef struct matrix_index_t {
- uint8_t row;
- uint8_t col;
-} matrix_index_t;
-
-# define NUMBER_OF_DIP_SWITCHES (ARRAY_SIZE(dip_switch_pad))
-static matrix_index_t dip_switch_pad[] = DIP_SWITCH_MATRIX_GRID;
-extern bool peek_matrix(uint8_t row_index, uint8_t col_index, bool read_raw);
-static uint16_t scan_count;
+static matrix_intersection_t dip_switch_pad[] = DIP_SWITCH_MATRIX_GRID;
+extern bool peek_matrix(uint8_t row_index, uint8_t col_index, bool read_raw);
+static uint16_t scan_count;
#endif /* DIP_SWITCH_MATRIX_GRID */
-static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
-static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
+static bool dip_switch_state[NUM_DIP_SWITCHES] = {0};
+static bool last_dip_switch_state[NUM_DIP_SWITCHES] = {0};
__attribute__((weak)) bool dip_switch_update_user(uint8_t index, bool active) {
return true;
@@ -70,17 +61,39 @@ __attribute__((weak)) bool dip_switch_update_mask_kb(uint32_t state) {
return dip_switch_update_mask_user(state);
}
+#ifdef DIP_SWITCH_MAP_ENABLE
+# include "keymap_introspection.h"
+# include "action.h"
+
+# ifndef DIP_SWITCH_MAP_KEY_DELAY
+# define DIP_SWITCH_MAP_KEY_DELAY TAP_CODE_DELAY
+# endif
+
+static void dip_switch_exec_mapping(uint8_t index, bool on) {
+ // The delays below cater for Windows and its wonderful requirements.
+ action_exec(on ? MAKE_DIPSWITCH_ON_EVENT(index, true) : MAKE_DIPSWITCH_OFF_EVENT(index, true));
+# if DIP_SWITCH_MAP_KEY_DELAY > 0
+ wait_ms(DIP_SWITCH_MAP_KEY_DELAY);
+# endif // DIP_SWITCH_MAP_KEY_DELAY > 0
+
+ action_exec(on ? MAKE_DIPSWITCH_ON_EVENT(index, false) : MAKE_DIPSWITCH_OFF_EVENT(index, false));
+# if DIP_SWITCH_MAP_KEY_DELAY > 0
+ wait_ms(DIP_SWITCH_MAP_KEY_DELAY);
+# endif // DIP_SWITCH_MAP_KEY_DELAY > 0
+}
+#endif // DIP_SWITCH_MAP_ENABLE
+
void dip_switch_init(void) {
#ifdef DIP_SWITCH_PINS
# if defined(SPLIT_KEYBOARD) && defined(DIP_SWITCH_PINS_RIGHT)
if (!isLeftHand) {
const pin_t dip_switch_pad_right[] = DIP_SWITCH_PINS_RIGHT;
- for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
+ for (uint8_t i = 0; i < NUM_DIP_SWITCHES; i++) {
dip_switch_pad[i] = dip_switch_pad_right[i];
}
}
# endif
- for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
+ for (uint8_t i = 0; i < NUM_DIP_SWITCHES; i++) {
setPinInputHigh(dip_switch_pad[i]);
}
dip_switch_read(true);
@@ -108,7 +121,7 @@ void dip_switch_read(bool forced) {
}
#endif
- for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
+ for (uint8_t i = 0; i < NUM_DIP_SWITCHES; i++) {
#ifdef DIP_SWITCH_PINS
dip_switch_state[i] = !readPin(dip_switch_pad[i]);
#endif
@@ -118,11 +131,21 @@ void dip_switch_read(bool forced) {
dip_switch_mask |= dip_switch_state[i] << i;
if (last_dip_switch_state[i] != dip_switch_state[i] || forced) {
has_dip_state_changed = true;
+#ifndef DIP_SWITCH_MAP_ENABLE
dip_switch_update_kb(i, dip_switch_state[i]);
+#else
+ dip_switch_exec_mapping(i, dip_switch_state[i]);
+#endif
}
}
if (has_dip_state_changed) {
+#ifndef DIP_SWITCH_MAP_ENABLE
dip_switch_update_mask_kb(dip_switch_mask);
+#endif
memcpy(last_dip_switch_state, dip_switch_state, sizeof(dip_switch_state));
}
}
+
+void dip_switch_task(void) {
+ dip_switch_read(false);
+}
diff --git a/quantum/dip_switch.h b/quantum/dip_switch.h
index 6e79dcb0bf..7629859359 100644
--- a/quantum/dip_switch.h
+++ b/quantum/dip_switch.h
@@ -20,11 +20,36 @@
#include <stdbool.h>
#include <stdint.h>
+#include "gpio.h"
+#include "util.h"
+
+#if defined(DIP_SWITCH_PINS)
+# define NUM_DIP_SWITCHES ARRAY_SIZE(((pin_t[])DIP_SWITCH_PINS))
+#elif defined(DIP_SWITCH_MATRIX_GRID)
+typedef struct matrix_intersection_t {
+ uint8_t row;
+ uint8_t col;
+} matrix_intersection_t;
+# define NUM_DIP_SWITCHES ARRAY_SIZE(((matrix_intersection_t[])DIP_SWITCH_MATRIX_GRID))
+#endif
+
+#ifndef NUM_DIP_SWITCHES
+# define NUM_DIP_SWITCHES 0
+#endif
bool dip_switch_update_kb(uint8_t index, bool active);
bool dip_switch_update_user(uint8_t index, bool active);
bool dip_switch_update_mask_user(uint32_t state);
bool dip_switch_update_mask_kb(uint32_t state);
-void dip_switch_init(void);
void dip_switch_read(bool forced);
+
+void dip_switch_init(void);
+void dip_switch_task(void);
+
+#ifdef DIP_SWITCH_MAP_ENABLE
+# define NUM_DIP_STATES 2
+# define DIP_SWITCH_OFF_ON(off, on) \
+ { (off), (on) }
+extern const uint16_t dip_switch_map[NUM_DIP_SWITCHES][NUM_DIP_STATES];
+#endif // DIP_SWITCH_MAP_ENABLE
diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c
index d9eea13758..2d2180b4b4 100644
--- a/quantum/eeconfig.c
+++ b/quantum/eeconfig.c
@@ -54,7 +54,7 @@ void eeconfig_init_quantum(void) {
// Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000
eeprom_update_word(EECONFIG_KEYMAP, 0x1400);
eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
- eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
+ eeprom_update_byte(EECONFIG_AUDIO, 0);
eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, 0);
eeprom_update_byte(EECONFIG_UNUSED, 0);
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index 86a1a9fea3..b5fa1a6e2e 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -615,7 +615,7 @@ void quantum_task(void) {
#endif
#ifdef DIP_SWITCH_ENABLE
- dip_switch_read(false);
+ dip_switch_task();
#endif
#ifdef AUTO_SHIFT_ENABLE
diff --git a/quantum/keyboard.h b/quantum/keyboard.h
index 5ea57815a7..0f39fde682 100644
--- a/quantum/keyboard.h
+++ b/quantum/keyboard.h
@@ -32,7 +32,7 @@ typedef struct {
uint8_t row;
} keypos_t;
-typedef enum keyevent_type_t { TICK_EVENT = 0, KEY_EVENT = 1, ENCODER_CW_EVENT = 2, ENCODER_CCW_EVENT = 3, COMBO_EVENT = 4 } keyevent_type_t;
+typedef enum keyevent_type_t { TICK_EVENT = 0, KEY_EVENT = 1, ENCODER_CW_EVENT = 2, ENCODER_CCW_EVENT = 3, COMBO_EVENT = 4, DIP_SWITCH_ON_EVENT = 5, DIP_SWITCH_OFF_EVENT = 6 } keyevent_type_t;
/* key event */
typedef struct {
@@ -48,6 +48,8 @@ typedef struct {
/* special keypos_t entries */
#define KEYLOC_ENCODER_CW 253
#define KEYLOC_ENCODER_CCW 252
+#define KEYLOC_DIP_SWITCH_ON 251
+#define KEYLOC_DIP_SWITCH_OFF 250
static inline bool IS_NOEVENT(const keyevent_t event) {
return event.type == TICK_EVENT;
@@ -64,6 +66,9 @@ static inline bool IS_COMBOEVENT(const keyevent_t event) {
static inline bool IS_ENCODEREVENT(const keyevent_t event) {
return event.type == ENCODER_CW_EVENT || event.type == ENCODER_CCW_EVENT;
}
+static inline bool IS_DIPSWITCHEVENT(const keyevent_t event) {
+ return event.type == DIP_SWITCH_ON_EVENT || event.type == DIP_SWITCH_OFF_EVENT;
+}
/* Common keypos_t object factory */
#define MAKE_KEYPOS(row_num, col_num) ((keypos_t){.row = (row_num), .col = (col_num)})
@@ -92,6 +97,12 @@ static inline bool IS_ENCODEREVENT(const keyevent_t event) {
# define MAKE_ENCODER_CCW_EVENT(enc_id, press) MAKE_EVENT(KEYLOC_ENCODER_CCW, (enc_id), (press), ENCODER_CCW_EVENT)
#endif // ENCODER_MAP_ENABLE
+#ifdef DIP_SWITCH_MAP_ENABLE
+/* Dip Switch events */
+# define MAKE_DIPSWITCH_ON_EVENT(switch_id, press) MAKE_EVENT(KEYLOC_DIP_SWITCH_ON, (switch_id), (press), DIP_SWITCH_ON_EVENT)
+# define MAKE_DIPSWITCH_OFF_EVENT(switch_id, press) MAKE_EVENT(KEYLOC_DIP_SWITCH_OFF, (switch_id), (press), DIP_SWITCH_OFF_EVENT)
+#endif // DIP_SWITCH_MAP_ENABLE
+
/* it runs once at early stage of startup before keyboard_init. */
void keyboard_setup(void);
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 91e47a72ee..abdcd5c7ba 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -29,6 +29,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "encoder.h"
#endif
+#ifdef DIP_SWITCH_MAP_ENABLE
+# include "dip_switch.h"
+#endif
+
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
@@ -204,5 +208,13 @@ __attribute__((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key
return keycode_at_encodermap_location(layer, key.col, false);
}
#endif // ENCODER_MAP_ENABLE
+#ifdef DIP_SWITCH_MAP_ENABLE
+ else if (key.row == KEYLOC_DIP_SWITCH_ON && key.col < NUM_DIP_SWITCHES) {
+ return keycode_at_dip_switch_map_location(key.col, true);
+ } else if (key.row == KEYLOC_DIP_SWITCH_OFF && key.col < NUM_DIP_SWITCHES) {
+ return keycode_at_dip_switch_map_location(key.col, false);
+ }
+#endif // DIP_SWITCH_MAP_ENABLE
+
return KC_NO;
}
diff --git a/quantum/keymap_extras/keymap_canadian_french.h b/quantum/keymap_extras/keymap_canadian_french.h
new file mode 100644
index 0000000000..63c9166a31
--- /dev/null
+++ b/quantum/keymap_extras/keymap_canadian_french.h
@@ -0,0 +1,122 @@
+// Copyright 2024 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*******************************************************************************
+ 88888888888 888 d8b .d888 d8b 888 d8b
+ 888 888 Y8P d88P" Y8P 888 Y8P
+ 888 888 888 888
+ 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
+ 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
+ 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
+ 888 888 888 888 X88 888 888 888 Y8b. 888 X88
+ 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
+ 888 888
+ 888 888
+ 888 888
+ .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
+ d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
+ 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
+ Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
+ "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
+ 888
+ Y8b d88P
+ "Y88P"
+*******************************************************************************/
+
+#pragma once
+#include "keycodes.h"
+// clang-format off
+
+// Aliases
+#define FR_HASH KC_GRV // #
+#define FR_1 KC_1 // 1
+#define FR_2 KC_2 // 2
+#define FR_3 KC_3 // 3
+#define FR_4 KC_4 // 4
+#define FR_5 KC_5 // 5
+#define FR_6 KC_6 // 6
+#define FR_7 KC_7 // 7
+#define FR_8 KC_8 // 8
+#define FR_9 KC_9 // 9
+#define FR_0 KC_0 // 0
+#define FR_MINS KC_MINS // -
+#define FR_EQL KC_EQL // =
+#define FR_Q KC_Q // Q
+#define FR_W KC_W // W
+#define FR_E KC_E // E
+#define FR_R KC_R // R
+#define FR_T KC_T // T
+#define FR_Y KC_Y // Y
+#define FR_U KC_U // U
+#define FR_I KC_I // I
+#define FR_O KC_O // O
+#define FR_P KC_P // P
+#define FR_DCIR KC_LBRC // ^ (dead)
+#define FR_CEDL KC_RBRC // ¸ (dead)
+#define FR_A KC_A // A
+#define FR_S KC_S // S
+#define FR_D KC_D // D
+#define FR_F KC_F // F
+#define FR_G KC_G // G
+#define FR_H KC_H // H
+#define FR_J KC_J // J
+#define FR_K KC_K // K
+#define FR_L KC_L // L
+#define FR_SCLN KC_SCLN // ;
+#define FR_DGRV KC_QUOT // ` (dead)
+#define FR_LABK KC_NUHS // <
+#define FR_LDAQ KC_NUBS // «
+#define FR_Z KC_Z // Z
+#define FR_X KC_X // X
+#define FR_C KC_C // C
+#define FR_V KC_V // V
+#define FR_B KC_B // B
+#define FR_N KC_N // N
+#define FR_M KC_M // M
+#define FR_COMM KC_COMM // ,
+#define FR_DOT KC_DOT // .
+#define FR_EACU KC_SLSH // É
+#define FR_PIPE S(FR_HASH) // |
+#define FR_EXLM S(FR_1) // !
+#define FR_DQUO S(FR_2) // "
+#define FR_SLSH S(FR_3) // /
+#define FR_DLR S(FR_4) // $
+#define FR_PERC S(FR_5) // %
+#define FR_QUES S(FR_6) // ?
+#define FR_AMPR S(FR_7) // &
+#define FR_ASTR S(FR_8) // *
+#define FR_LPRN S(FR_9) // (
+#define FR_RPRN S(FR_0) // )
+#define FR_UNDS S(FR_MINS) // _
+#define FR_PLUS S(FR_EQL) // +
+#define FR_DIAE S(FR_CEDL) // ¨ (dead)
+#define FR_COLN S(FR_SCLN) // :
+#define FR_RABK S(FR_LABK) // >
+#define FR_RDAQ S(FR_LDAQ) // »
+#define FR_QUOT S(FR_COMM) // '
+#define FR_BSLS ALGR(FR_HASH) // (backslash)
+#define FR_PLMN ALGR(FR_1) // ±
+#define FR_AT ALGR(FR_2) // @
+#define FR_PND ALGR(FR_3) // £
+#define FR_CENT ALGR(FR_4) // ¢
+#define FR_CURR ALGR(FR_5) // ¤
+#define FR_NOT ALGR(FR_6) // ¬
+#define FR_BRKP ALGR(FR_7) // ¦
+#define FR_SUP2 ALGR(FR_8) // ²
+#define FR_SUP3 ALGR(FR_9) // ³
+#define FR_QRTR ALGR(FR_0) // ¼
+#define FR_HALF ALGR(FR_MINS) // ½
+#define FR_TQTR ALGR(FR_EQL) // ¾
+#define FR_SECT ALGR(FR_O) // §
+#define FR_PARA ALGR(FR_P) // ¶
+#define FR_LBRC ALGR(FR_DCIR) // [
+#define FR_RBRC ALGR(FR_CEDL) // ]
+#define FR_TILD ALGR(FR_SCLN) // ~
+#define FR_LCBR ALGR(FR_DGRV) // {
+#define FR_RCBR ALGR(FR_LABK) // }
+#define FR_DEG ALGR(FR_LDAQ) // °
+#define FR_MICR ALGR(FR_M) // µ
+#define FR_MACR ALGR(FR_COMM) // ¯
+#define FR_SHYP ALGR(FR_DOT) // ­ (soft hyphen)
+#define FR_ACUT ALGR(FR_EACU) // ´ (dead)
+
diff --git a/quantum/keymap_extras/keymap_spanish_latin_america.h b/quantum/keymap_extras/keymap_spanish_latin_america.h
new file mode 100644
index 0000000000..0ade828793
--- /dev/null
+++ b/quantum/keymap_extras/keymap_spanish_latin_america.h
@@ -0,0 +1,105 @@
+// Copyright 2024 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*******************************************************************************
+ 88888888888 888 d8b .d888 d8b 888 d8b
+ 888 888 Y8P d88P" Y8P 888 Y8P
+ 888 888 888 888
+ 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
+ 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
+ 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
+ 888 888 888 888 X88 888 888 888 Y8b. 888 X88
+ 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
+ 888 888
+ 888 888
+ 888 888
+ .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
+ d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
+ 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
+ Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
+ "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
+ 888
+ Y8b d88P
+ "Y88P"
+*******************************************************************************/
+
+#pragma once
+#include "keycodes.h"
+// clang-format off
+
+// Aliases
+#define ES_PIPE KC_GRV // |
+#define ES_1 KC_1 // 1
+#define ES_2 KC_2 // 2
+#define ES_3 KC_3 // 3
+#define ES_4 KC_4 // 4
+#define ES_5 KC_5 // 5
+#define ES_6 KC_6 // 6
+#define ES_7 KC_7 // 7
+#define ES_8 KC_8 // 8
+#define ES_9 KC_9 // 9
+#define ES_0 KC_0 // 0
+#define ES_QUOT KC_MINS // '
+#define ES_IQUE KC_EQL // ¿
+#define ES_Q KC_Q // Q
+#define ES_W KC_W // W
+#define ES_E KC_E // E
+#define ES_R KC_R // R
+#define ES_T KC_T // T
+#define ES_Y KC_Y // Y
+#define ES_U KC_U // U
+#define ES_I KC_I // I
+#define ES_O KC_O // O
+#define ES_P KC_P // P
+#define ES_ACUT KC_LBRC // ´ (dead)
+#define ES_PLUS KC_RBRC // +
+#define ES_A KC_A // A
+#define ES_S KC_S // S
+#define ES_D KC_D // D
+#define ES_F KC_F // F
+#define ES_G KC_G // G
+#define ES_H KC_H // H
+#define ES_J KC_J // J
+#define ES_K KC_K // K
+#define ES_L KC_L // L
+#define ES_NTIL KC_SCLN // Ñ
+#define ES_LCBR KC_QUOT // {
+#define ES_RCBR KC_NUHS // }
+#define ES_LABK KC_NUBS // <
+#define ES_Z KC_Z // Z
+#define ES_X KC_X // X
+#define ES_C KC_C // C
+#define ES_V KC_V // V
+#define ES_B KC_B // B
+#define ES_N KC_N // N
+#define ES_M KC_M // M
+#define ES_COMM KC_COMM // ,
+#define ES_DOT KC_DOT // .
+#define ES_MINS KC_SLSH // -
+#define ES_MORD S(ES_PIPE) // °
+#define ES_EXLM S(ES_1) // !
+#define ES_DQUO S(ES_2) // "
+#define ES_NUMB S(ES_3) // #
+#define ES_DLR S(ES_4) // $
+#define ES_PERC S(ES_5) // %
+#define ES_AMPR S(ES_6) // &
+#define ES_SLSH S(ES_7) // /
+#define ES_LPRN S(ES_8) // (
+#define ES_RPRN S(ES_9) // )
+#define ES_EQL S(ES_0) // =
+#define ES_QUES S(ES_QUOT) // ?
+#define ES_IEXL S(ES_IQUE) // ¡
+#define ES_DIAE S(ES_ACUT) // ¨ (dead)
+#define ES_ASTR S(ES_PLUS) // *
+#define ES_LBRC S(ES_LCBR) // [
+#define ES_RBRC S(ES_RCBR) // ]
+#define ES_RABK S(ES_LABK) // >
+#define ES_SCLN S(ES_COMM) // ;
+#define ES_COLN S(ES_DOT) // :
+#define ES_UNDS S(ES_MINS) // _
+#define ES_NOT ALGR(ES_PIPE) // ¬
+#define ES_BSLS ALGR(ES_QUOT) // (backslash)
+#define ES_AT ALGR(ES_Q) // @
+#define ES_TILD ALGR(ES_PLUS) // ~
+#define ES_CIRC ALGR(ES_LCBR) // ^
+
diff --git a/quantum/keymap_extras/sendstring_canadian_french.h b/quantum/keymap_extras/sendstring_canadian_french.h
new file mode 100644
index 0000000000..2abba3a9d3
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_canadian_french.h
@@ -0,0 +1,120 @@
+/* Copyright 2023 Nebuleon
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Sendstring lookup tables for Canadian French layouts
+
+#pragma once
+
+#include "keymap_canadian_french.h"
+#include "send_string.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0)
+};
+
+const uint8_t ascii_to_dead_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, FR_1, FR_2, FR_HASH, FR_4, FR_5, FR_7, FR_COMM,
+ // ( ) * + , - . /
+ FR_9, FR_0, FR_8, FR_EQL, FR_COMM, FR_MINS, FR_DOT, FR_3,
+ // 0 1 2 3 4 5 6 7
+ FR_0, FR_1, FR_2, FR_3, FR_4, FR_5, FR_6, FR_7,
+ // 8 9 : ; < = > ?
+ FR_8, FR_9, FR_SCLN, FR_SCLN, FR_LABK, FR_EQL, FR_LABK, FR_6,
+ // @ A B C D E F G
+ FR_2, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
+ // H I J K L M N O
+ FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O,
+ // P Q R S T U V W
+ FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W,
+ // X Y Z [ \ ] ^ _
+ FR_X, FR_Y, FR_Z, FR_DCIR, FR_HASH, FR_CEDL, FR_DCIR, FR_MINS,
+ // ` a b c d e f g
+ FR_DGRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
+ // h i j k l m n o
+ FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O,
+ // p q r s t u v w
+ FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W,
+ // x y z { | } ~ DEL
+ FR_X, FR_Y, FR_Z, FR_DGRV, FR_HASH, FR_LABK, FR_SCLN, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_spanish_latin_america.h b/quantum/keymap_extras/sendstring_spanish_latin_america.h
new file mode 100644
index 0000000000..3bfdf7d5cb
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_spanish_latin_america.h
@@ -0,0 +1,120 @@
+/* Copyright 2023 Juan David Díaz
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Sendstring lookup tables for Latam Spanish layouts
+
+#pragma once
+
+#include "send_string.h"
+#include "keymap_spanish_latin_america.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 0, 1, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0)
+};
+
+const uint8_t ascii_to_dead_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, ES_1, ES_2, ES_3, ES_4, ES_5, ES_6, ES_QUOT,
+ // ( ) * + , - . /
+ ES_8, ES_9, ES_PLUS, ES_PLUS, ES_COMM, ES_MINS, ES_DOT, ES_7,
+ // 0 1 2 3 4 5 6 7
+ ES_0, ES_1, ES_2, ES_3, ES_4, ES_5, ES_6, ES_7,
+ // 8 9 : ; < = > ?
+ ES_8, ES_9, ES_DOT, ES_COMM, ES_LABK, ES_0, ES_LABK, ES_QUOT,
+ // @ A B C D E F G
+ ES_Q, ES_A, ES_B, ES_C, ES_D, ES_E, ES_F, ES_G,
+ // H I J K L M N O
+ ES_H, ES_I, ES_J, ES_K, ES_L, ES_M, ES_N, ES_O,
+ // P Q R S T U V W
+ ES_P, ES_Q, ES_R, ES_S, ES_T, ES_U, ES_V, ES_W,
+ // X Y Z [ \ ] ^ _
+ ES_X, ES_Y, ES_Z, ES_LCBR, ES_QUOT, ES_RCBR, ES_LCBR, ES_MINS,
+ // ` a b c d e f g
+ ES_RCBR, ES_A, ES_B, ES_C, ES_D, ES_E, ES_F, ES_G,
+ // h i j k l m n o
+ ES_H, ES_I, ES_J, ES_K, ES_L, ES_M, ES_N, ES_O,
+ // p q r s t u v w
+ ES_P, ES_Q, ES_R, ES_S, ES_T, ES_U, ES_V, ES_W,
+ // x y z { | } ~ DEL
+ ES_X, ES_Y, ES_Z, ES_LCBR, ES_PIPE, ES_RCBR, ES_PLUS, KC_DEL
+};
diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c
index e4a01d2e9a..71e3b429ea 100644
--- a/quantum/keymap_introspection.c
+++ b/quantum/keymap_introspection.c
@@ -72,6 +72,24 @@ __attribute__((weak)) uint16_t keycode_at_encodermap_location(uint8_t layer_num,
#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Dip Switch mapping
+
+#if defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+uint16_t keycode_at_dip_switch_map_location_raw(uint8_t switch_idx, bool on) {
+ if (switch_idx < NUM_DIP_SWITCHES) {
+ return pgm_read_word(&dip_switch_map[switch_idx][!!on]);
+ }
+ return KC_TRNS;
+}
+
+uint16_t keycode_at_dip_switch_map_location(uint8_t switch_idx, bool on) {
+ return keycode_at_dip_switch_map_location_raw(switch_idx, on);
+}
+
+#endif // defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Combos
#if defined(COMBO_ENABLE)
diff --git a/quantum/keymap_introspection.h b/quantum/keymap_introspection.h
index 2012a2b8cc..f7516bf42a 100644
--- a/quantum/keymap_introspection.h
+++ b/quantum/keymap_introspection.h
@@ -36,6 +36,18 @@ uint16_t keycode_at_encodermap_location(uint8_t layer_num, uint8_t encoder_idx,
#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Dip Switch mapping
+
+#if defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+// Get the keycode for the dip_switch mapping location, stored in firmware rather than any other persistent storage
+uint16_t keycode_at_dip_switch_map_location_raw(uint8_t switch_idx, bool on);
+// Get the keycode for the dip_switch mapping location, potentially stored dynamically
+uint16_t keycode_at_dip_switch_map_location(uint8_t switch_idx, bool on);
+
+#endif // defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Combos
#if defined(COMBO_ENABLE)
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c
index 4d67a295df..760a8b7484 100644
--- a/quantum/led_matrix/led_matrix.c
+++ b/quantum/led_matrix/led_matrix.c
@@ -74,9 +74,6 @@ 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
-static uint32_t led_anykey_timer;
-#endif // LED_MATRIX_TIMEOUT > 0
// double buffers
static uint32_t led_timer_buffer;
@@ -114,6 +111,16 @@ void eeconfig_debug_led_matrix(void) {
dprintf("led_matrix_eeconfig.flags = %d\n", led_matrix_eeconfig.flags);
}
+void led_matrix_reload_from_eeprom(void) {
+ led_matrix_disable_noeeprom();
+ /* Reset back to what we have in eeprom */
+ eeconfig_init_led_matrix();
+ eeconfig_debug_led_matrix(); // display current eeprom values
+ if (led_matrix_eeconfig.enable) {
+ led_matrix_mode_noeeprom(led_matrix_eeconfig.mode);
+ }
+}
+
__attribute__((weak)) uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) {
return 0;
}
@@ -156,9 +163,6 @@ void process_led_matrix(uint8_t row, uint8_t col, bool pressed) {
#ifndef LED_MATRIX_SPLIT
if (!is_keyboard_master()) return;
#endif
-#if LED_MATRIX_TIMEOUT > 0
- led_anykey_timer = 0;
-#endif // LED_MATRIX_TIMEOUT > 0
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
uint8_t led[LED_HITS_TO_REMEMBER];
@@ -208,22 +212,11 @@ static bool led_matrix_none(effect_params_t *params) {
}
static void led_task_timers(void) {
-#if defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_MATRIX_TIMEOUT > 0
+#if defined(LED_MATRIX_KEYREACTIVE_ENABLED)
uint32_t deltaTime = sync_timer_elapsed32(led_timer_buffer);
-#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_MATRIX_TIMEOUT > 0
+#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED)
led_timer_buffer = sync_timer_read32();
- // Update double buffer timers
-#if LED_MATRIX_TIMEOUT > 0
- if (led_anykey_timer < UINT32_MAX) {
- if (UINT32_MAX - deltaTime < led_anykey_timer) {
- led_anykey_timer = UINT32_MAX;
- } else {
- led_anykey_timer += deltaTime;
- }
- }
-#endif // LED_MATRIX_TIMEOUT > 0
-
// Update double buffer last hit timers
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
uint8_t count = last_hit_buffer.count;
@@ -329,7 +322,7 @@ 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) ||
+ (last_input_activity_elapsed() > (uint32_t)LED_MATRIX_TIMEOUT) ||
#endif // LED_MATRIX_TIMEOUT > 0
false;
@@ -432,12 +425,6 @@ void led_matrix_init(void) {
}
#endif // LED_MATRIX_KEYREACTIVE_ENABLED
- if (!eeconfig_is_enabled()) {
- dprintf("led_matrix_init_drivers eeconfig is not enabled.\n");
- eeconfig_init();
- eeconfig_update_led_matrix_default();
- }
-
eeconfig_init_led_matrix();
if (!led_matrix_eeconfig.mode) {
dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");
@@ -447,7 +434,7 @@ void led_matrix_init(void) {
}
void led_matrix_set_suspend_state(bool state) {
-#ifdef LED_DISABLE_WHEN_USB_SUSPENDED
+#ifdef LED_MATRIX_SLEEP
if (state && !suspend_state && is_keyboard_master()) { // only run if turning off, and only once
led_task_render(0); // turn off all LEDs when suspending
led_task_flush(0); // and actually flash led state to LEDs
diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h
index c903a230f4..eeaeee20b5 100644
--- a/quantum/led_matrix/led_matrix.h
+++ b/quantum/led_matrix/led_matrix.h
@@ -23,32 +23,9 @@
#include <stdint.h>
#include <stdbool.h>
#include "led_matrix_types.h"
+#include "led_matrix_drivers.h"
#include "keyboard.h"
-#if defined(LED_MATRIX_IS31FL3218)
-# include "is31fl3218-simple.h"
-#elif defined(LED_MATRIX_IS31FL3731)
-# include "is31fl3731-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3733
-# include "is31fl3733-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3736
-# include "is31fl3736-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3737
-# include "is31fl3737-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3741
-# include "is31fl3741-simple.h"
-#endif
-#if defined(IS31FLCOMMON)
-# include "is31flcommon.h"
-#endif
-#ifdef LED_MATRIX_SNLED27351
-# include "snled27351-simple.h"
-#endif
-
#ifndef LED_MATRIX_TIMEOUT
# define LED_MATRIX_TIMEOUT 0
#endif
@@ -159,6 +136,8 @@ bool led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max);
void led_matrix_init(void);
+void led_matrix_reload_from_eeprom(void);
+
void led_matrix_set_suspend_state(bool state);
bool led_matrix_get_suspend_state(void);
void led_matrix_toggle(void);
@@ -193,18 +172,6 @@ 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);
-typedef struct {
- /* Perform any initialisation required for the other driver functions to work. */
- void (*init)(void);
-
- /* Set the brightness of a single LED in the buffer. */
- void (*set_value)(int index, uint8_t value);
- /* Set the brightness of all LEDS on the keyboard in the buffer. */
- void (*set_value_all)(uint8_t value);
- /* Flush any buffered changes to the hardware. */
- void (*flush)(void);
-} led_matrix_driver_t;
-
static inline bool led_matrix_check_finished_leds(uint8_t led_idx) {
#if defined(LED_MATRIX_SPLIT)
if (is_keyboard_left()) {
@@ -217,8 +184,6 @@ static inline bool led_matrix_check_finished_leds(uint8_t led_idx) {
#endif
}
-extern const led_matrix_driver_t led_matrix_driver;
-
extern led_eeconfig_t led_matrix_eeconfig;
extern uint32_t g_led_timer;
diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c
index 117bed9851..b866383481 100644
--- a/quantum/led_matrix/led_matrix_drivers.c
+++ b/quantum/led_matrix/led_matrix_drivers.c
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "led_matrix.h"
+#include "led_matrix_drivers.h"
/* Each driver needs to define a struct:
*
@@ -73,12 +73,36 @@ const led_matrix_driver_t led_matrix_driver = {
.set_value_all = is31fl3741_set_value_all,
};
-#elif defined(IS31FLCOMMON)
+#elif defined(LED_MATRIX_IS31FL3742A)
const led_matrix_driver_t led_matrix_driver = {
- .init = IS31FL_simple_init_drivers,
- .flush = IS31FL_common_flush,
- .set_value = IS31FL_simple_set_brightness,
- .set_value_all = IS31FL_simple_set_brigntness_all,
+ .init = is31fl3742a_init_drivers,
+ .flush = is31fl3742a_flush,
+ .set_value = is31fl3742a_set_value,
+ .set_value_all = is31fl3742a_set_value_all,
+};
+
+#elif defined(LED_MATRIX_IS31FL3743A)
+const led_matrix_driver_t led_matrix_driver = {
+ .init = is31fl3743a_init_drivers,
+ .flush = is31fl3743a_flush,
+ .set_value = is31fl3743a_set_value,
+ .set_value_all = is31fl3743a_set_value_all,
+};
+
+#elif defined(LED_MATRIX_IS31FL3745)
+const led_matrix_driver_t led_matrix_driver = {
+ .init = is31fl3745_init_drivers,
+ .flush = is31fl3745_flush,
+ .set_value = is31fl3745_set_value,
+ .set_value_all = is31fl3745_set_value_all,
+};
+
+#elif defined(LED_MATRIX_IS31FL3746A)
+const led_matrix_driver_t led_matrix_driver = {
+ .init = is31fl3746a_init_drivers,
+ .flush = is31fl3746a_flush,
+ .set_value = is31fl3746a_set_value,
+ .set_value_all = is31fl3746a_set_value_all,
};
#elif defined(LED_MATRIX_SNLED27351)
diff --git a/quantum/led_matrix/led_matrix_drivers.h b/quantum/led_matrix/led_matrix_drivers.h
new file mode 100644
index 0000000000..d792600e1f
--- /dev/null
+++ b/quantum/led_matrix/led_matrix_drivers.h
@@ -0,0 +1,44 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+
+#if defined(LED_MATRIX_IS31FL3218)
+# include "is31fl3218-mono.h"
+#elif defined(LED_MATRIX_IS31FL3731)
+# include "is31fl3731-mono.h"
+#elif defined(LED_MATRIX_IS31FL3733)
+# include "is31fl3733-mono.h"
+#elif defined(LED_MATRIX_IS31FL3736)
+# include "is31fl3736-mono.h"
+#elif defined(LED_MATRIX_IS31FL3737)
+# include "is31fl3737-mono.h"
+#elif defined(LED_MATRIX_IS31FL3741)
+# include "is31fl3741-mono.h"
+#elif defined(LED_MATRIX_IS31FL3742A)
+# include "is31fl3742a-mono.h"
+#elif defined(LED_MATRIX_IS31FL3743A)
+# include "is31fl3743a-mono.h"
+#elif defined(LED_MATRIX_IS31FL3745)
+# include "is31fl3745-mono.h"
+#elif defined(LED_MATRIX_IS31FL3746A)
+# include "is31fl3746a-mono.h"
+#elif defined(LED_MATRIX_SNLED27351)
+# include "snled27351-mono.h"
+#endif
+
+typedef struct {
+ /* Perform any initialisation required for the other driver functions to work. */
+ void (*init)(void);
+
+ /* Set the brightness of a single LED in the buffer. */
+ void (*set_value)(int index, uint8_t value);
+ /* Set the brightness of all LEDS on the keyboard in the buffer. */
+ void (*set_value_all)(uint8_t value);
+ /* Flush any buffered changes to the hardware. */
+ void (*flush)(void);
+} led_matrix_driver_t;
+
+extern const led_matrix_driver_t led_matrix_driver;
diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c
index 17dc701a41..2fa49ade8e 100644
--- a/quantum/pointing_device/pointing_device.c
+++ b/quantum/pointing_device/pointing_device.c
@@ -251,14 +251,15 @@ __attribute__((weak)) bool pointing_device_task(void) {
# else
if (readPin(POINTING_DEVICE_MOTION_PIN))
# endif
+ {
#endif
#if defined(SPLIT_POINTING_ENABLE)
# if defined(POINTING_DEVICE_COMBINED)
static uint8_t old_buttons = 0;
- local_mouse_report.buttons = old_buttons;
- local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
- old_buttons = local_mouse_report.buttons;
+ local_mouse_report.buttons = old_buttons;
+ local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
+ old_buttons = local_mouse_report.buttons;
# elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
local_mouse_report = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_report(local_mouse_report) : shared_mouse_report;
# else
@@ -268,6 +269,10 @@ __attribute__((weak)) bool pointing_device_task(void) {
local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
#endif // defined(SPLIT_POINTING_ENABLE)
+#ifdef POINTING_DEVICE_MOTION_PIN
+ }
+#endif
+
// allow kb to intercept and modify report
#if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)
if (is_keyboard_left()) {
diff --git a/quantum/pointing_device/pointing_device_auto_mouse.c b/quantum/pointing_device/pointing_device_auto_mouse.c
index 3135b9e531..1b11fffedb 100644
--- a/quantum/pointing_device/pointing_device_auto_mouse.c
+++ b/quantum/pointing_device/pointing_device_auto_mouse.c
@@ -17,6 +17,7 @@
#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+# include <stdlib.h>
# include <string.h>
# include "pointing_device_auto_mouse.h"
# include "debug.h"
@@ -217,7 +218,11 @@ void auto_mouse_layer_off(void) {
* @return bool of pointing_device activation
*/
__attribute__((weak)) bool auto_mouse_activation(report_mouse_t mouse_report) {
- return mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons;
+ auto_mouse_context.total_mouse_movement.x += mouse_report.x;
+ auto_mouse_context.total_mouse_movement.y += mouse_report.y;
+ auto_mouse_context.total_mouse_movement.h += mouse_report.h;
+ auto_mouse_context.total_mouse_movement.v += mouse_report.v;
+ return abs(auto_mouse_context.total_mouse_movement.x) > AUTO_MOUSE_THRESHOLD || abs(auto_mouse_context.total_mouse_movement.y) > AUTO_MOUSE_THRESHOLD || abs(auto_mouse_context.total_mouse_movement.h) > AUTO_MOUSE_THRESHOLD || abs(auto_mouse_context.total_mouse_movement.v) > AUTO_MOUSE_THRESHOLD || mouse_report.buttons;
}
/**
@@ -235,14 +240,16 @@ void pointing_device_task_auto_mouse(report_mouse_t mouse_report) {
// update activation and reset debounce
auto_mouse_context.status.is_activated = auto_mouse_activation(mouse_report);
if (is_auto_mouse_active()) {
- auto_mouse_context.timer.active = timer_read();
- auto_mouse_context.timer.delay = 0;
+ auto_mouse_context.total_mouse_movement = (total_mouse_movement_t){.x = 0, .y = 0, .h = 0, .v = 0};
+ auto_mouse_context.timer.active = timer_read();
+ auto_mouse_context.timer.delay = 0;
if (!layer_state_is((AUTO_MOUSE_TARGET_LAYER))) {
layer_on((AUTO_MOUSE_TARGET_LAYER));
}
} else if (layer_state_is((AUTO_MOUSE_TARGET_LAYER)) && timer_elapsed(auto_mouse_context.timer.active) > auto_mouse_context.config.timeout) {
layer_off((AUTO_MOUSE_TARGET_LAYER));
- auto_mouse_context.timer.active = 0;
+ auto_mouse_context.timer.active = 0;
+ auto_mouse_context.total_mouse_movement = (total_mouse_movement_t){.x = 0, .y = 0, .h = 0, .v = 0};
}
}
diff --git a/quantum/pointing_device/pointing_device_auto_mouse.h b/quantum/pointing_device/pointing_device_auto_mouse.h
index 1343855e00..904f18b68e 100644
--- a/quantum/pointing_device/pointing_device_auto_mouse.h
+++ b/quantum/pointing_device/pointing_device_auto_mouse.h
@@ -42,9 +42,18 @@
#ifndef AUTO_MOUSE_DEBOUNCE
# define AUTO_MOUSE_DEBOUNCE 25
#endif
+#ifndef AUTO_MOUSE_THRESHOLD
+# define AUTO_MOUSE_THRESHOLD 10
+#endif
/* data structure */
typedef struct {
+ mouse_xy_report_t x;
+ mouse_xy_report_t y;
+ int8_t v;
+ int8_t h;
+} total_mouse_movement_t;
+typedef struct {
struct {
bool is_enabled;
uint8_t layer;
@@ -60,6 +69,7 @@ typedef struct {
bool is_toggled;
int8_t mouse_key_tracker;
} status;
+ total_mouse_movement_t total_mouse_movement;
} auto_mouse_context_t;
/* ----------Set up and control------------------------------------------------------------------------------ */
diff --git a/quantum/process_keycode/process_caps_word.c b/quantum/process_keycode/process_caps_word.c
index 1088c8f76c..b8fb868c6d 100644
--- a/quantum/process_keycode/process_caps_word.c
+++ b/quantum/process_keycode/process_caps_word.c
@@ -14,6 +14,7 @@
#include "process_caps_word.h"
#include "process_auto_shift.h"
+#include "process_space_cadet.h"
#include "caps_word.h"
#include "keycodes.h"
#include "quantum_keycodes.h"
@@ -110,6 +111,9 @@ bool process_caps_word(uint16_t keycode, keyrecord_t* record) {
# endif // COMMAND_ENABLE
) {
caps_word_on();
+# ifdef SPACE_CADET_ENABLE
+ reset_space_cadet();
+# endif // SPACE_CADET_ENABLE
}
# endif // defined(COMMAND_ENABLE) && !defined(IS_COMMAND)
#endif // BOTH_SHIFTS_TURNS_ON_CAPS_WORD
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c
index 377fcb69e2..5ecd897d16 100644
--- a/quantum/process_keycode/process_midi.c
+++ b/quantum/process_keycode/process_midi.c
@@ -38,7 +38,7 @@ void process_midi_all_notes_off(void) {
#endif // MIDI_BASIC
#ifdef MIDI_ADVANCED
-static uint8_t tone_status[2][MIDI_TONE_COUNT];
+static uint8_t tone_status[MIDI_TONE_COUNT];
static uint8_t midi_modulation;
static int8_t midi_modulation_step;
@@ -57,8 +57,7 @@ void midi_init(void) {
midi_config.modulation_interval = 8;
for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++) {
- tone_status[0][i] = MIDI_INVALID_NOTE;
- tone_status[1][i] = 0;
+ tone_status[i] = MIDI_INVALID_NOTE;
}
midi_modulation = 0;
@@ -77,21 +76,19 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) {
uint8_t tone = keycode - MIDI_TONE_MIN;
uint8_t velocity = midi_config.velocity;
if (record->event.pressed) {
- uint8_t note = midi_compute_note(keycode);
- midi_send_noteon(&midi_device, channel, note, velocity);
- dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
- tone_status[1][tone] += 1;
- if (tone_status[0][tone] == MIDI_INVALID_NOTE) {
- tone_status[0][tone] = note;
+ if (tone_status[tone] == MIDI_INVALID_NOTE) {
+ uint8_t note = midi_compute_note(keycode);
+ midi_send_noteon(&midi_device, channel, note, velocity);
+ dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
+ tone_status[tone] = note;
}
} else {
- uint8_t note = tone_status[0][tone];
- tone_status[1][tone] -= 1;
- if (tone_status[1][tone] == 0) {
+ uint8_t note = tone_status[tone];
+ if (note != MIDI_INVALID_NOTE) {
midi_send_noteoff(&midi_device, channel, note, velocity);
dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
- tone_status[0][tone] = MIDI_INVALID_NOTE;
}
+ tone_status[tone] = MIDI_INVALID_NOTE;
}
return false;
}
diff --git a/quantum/process_keycode/process_space_cadet.c b/quantum/process_keycode/process_space_cadet.c
index f948ad6238..3e280d57d9 100644
--- a/quantum/process_keycode/process_space_cadet.c
+++ b/quantum/process_keycode/process_space_cadet.c
@@ -157,10 +157,14 @@ bool process_space_cadet(uint16_t keycode, keyrecord_t *record) {
}
default: {
if (record->event.pressed) {
- sc_last = 0;
+ reset_space_cadet();
}
break;
}
}
return true;
}
+
+void reset_space_cadet() {
+ sc_last = 0;
+}
diff --git a/quantum/process_keycode/process_space_cadet.h b/quantum/process_keycode/process_space_cadet.h
index 6d10051532..9d254e26fd 100644
--- a/quantum/process_keycode/process_space_cadet.h
+++ b/quantum/process_keycode/process_space_cadet.h
@@ -21,3 +21,4 @@
void perform_space_cadet(keyrecord_t *record, uint16_t sc_keycode, uint8_t holdMod, uint8_t tapMod, uint8_t keycode);
bool process_space_cadet(uint16_t keycode, keyrecord_t *record);
+void reset_space_cadet(void);
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index b8a8d32f35..ce3b8fc81f 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -133,7 +133,7 @@ bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
if (!active_td || keycode == active_td) return false;
- action = &tap_dance_actions[TD_INDEX(active_td)];
+ action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(active_td)];
action->state.interrupted = true;
action->state.interrupting_keycode = keycode;
process_tap_dance_action_on_dance_finished(action);
@@ -154,7 +154,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
- action = &tap_dance_actions[TD_INDEX(keycode)];
+ action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(keycode)];
action->state.pressed = record->event.pressed;
if (record->event.pressed) {
@@ -182,7 +182,7 @@ void tap_dance_task(void) {
if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return;
- action = &tap_dance_actions[TD_INDEX(active_td)];
+ action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(active_td)];
if (!action->state.interrupted) {
process_tap_dance_action_on_dance_finished(action);
}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index 2b114dabd3..c0137c14a3 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "action.h"
+#include "quantum_keycodes.h"
typedef struct {
uint16_t interrupting_keycode;
@@ -74,8 +75,7 @@ typedef struct {
#define ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(user_fn_on_each_tap, user_fn_on_each_release, user_fn_on_dance_finished, user_fn_on_dance_reset) \
{ .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, user_fn_on_each_release}, .user_data = NULL, }
-#define TD(n) (QK_TAP_DANCE | TD_INDEX(n))
-#define TD_INDEX(code) ((code)&0xFF)
+#define TD_INDEX(code) QK_TAP_DANCE_GET_INDEX(code)
#define TAP_DANCE_KEYCODE(state) TD(((tap_dance_action_t *)state) - tap_dance_actions)
extern tap_dance_action_t tap_dance_actions[];
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index d3249bd455..882e1d07ae 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -190,6 +190,10 @@
#define SH_T(kc) (QK_SWAP_HANDS | ((kc)&0xFF))
#define QK_SWAP_HANDS_GET_TAP_KEYCODE(kc) ((kc)&0xFF)
+// Tap dance
+#define TD(i) (QK_TAP_DANCE | ((i)&0xFF))
+#define QK_TAP_DANCE_GET_INDEX(kc) ((kc)&0xFF)
+
// MIDI aliases
#define MIDI_TONE_MIN QK_MIDI_NOTE_C_0
#define MIDI_TONE_MAX QK_MIDI_NOTE_B_5
diff --git a/quantum/rgb_matrix/animations/solid_reactive_anim.h b/quantum/rgb_matrix/animations/solid_reactive_anim.h
index edf6041350..e18ffb5f2b 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_anim.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_anim.h
@@ -7,7 +7,7 @@ static HSV SOLID_REACTIVE_math(HSV hsv, uint16_t offset) {
# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4);
# endif
- hsv.h += qsub8(130, offset);
+ hsv.h += scale8(255 - offset, 64);
return hsv;
}
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c
index d93d189827..4865664ac0 100644
--- a/quantum/rgb_matrix/rgb_matrix.c
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -76,9 +76,6 @@ static uint8_t rgb_last_enable = UINT8_MAX;
static uint8_t rgb_last_effect = UINT8_MAX;
static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false};
static rgb_task_states rgb_task_state = SYNCING;
-#if RGB_MATRIX_TIMEOUT > 0
-static uint32_t rgb_anykey_timer;
-#endif // RGB_MATRIX_TIMEOUT > 0
// double buffers
static uint32_t rgb_timer_buffer;
@@ -163,9 +160,6 @@ void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) {
#ifndef RGB_MATRIX_SPLIT
if (!is_keyboard_master()) return;
#endif
-#if RGB_MATRIX_TIMEOUT > 0
- rgb_anykey_timer = 0;
-#endif // RGB_MATRIX_TIMEOUT > 0
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
uint8_t led[LED_HITS_TO_REMEMBER];
@@ -246,18 +240,11 @@ static bool rgb_matrix_none(effect_params_t *params) {
}
static void rgb_task_timers(void) {
-#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_MATRIX_TIMEOUT > 0
+#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
uint32_t deltaTime = sync_timer_elapsed32(rgb_timer_buffer);
-#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_MATRIX_TIMEOUT > 0
+#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
rgb_timer_buffer = sync_timer_read32();
- // Update double buffer timers
-#if RGB_MATRIX_TIMEOUT > 0
- if (rgb_anykey_timer + deltaTime <= UINT32_MAX) {
- rgb_anykey_timer += deltaTime;
- }
-#endif // RGB_MATRIX_TIMEOUT > 0
-
// Update double buffer last hit timers
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
uint8_t count = last_hit_buffer.count;
@@ -370,7 +357,7 @@ void rgb_matrix_task(void) {
// while suspended and just do a software shutdown. This is a cheap hack for now.
bool suspend_backlight = suspend_state ||
#if RGB_MATRIX_TIMEOUT > 0
- (rgb_anykey_timer > (uint32_t)RGB_MATRIX_TIMEOUT) ||
+ (last_input_activity_elapsed() > (uint32_t)RGB_MATRIX_TIMEOUT) ||
#endif // RGB_MATRIX_TIMEOUT > 0
false;
@@ -473,12 +460,6 @@ void rgb_matrix_init(void) {
}
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
- if (!eeconfig_is_enabled()) {
- dprintf("rgb_matrix_init_drivers eeconfig is not enabled.\n");
- eeconfig_init();
- eeconfig_update_rgb_matrix_default();
- }
-
eeconfig_init_rgb_matrix();
if (!rgb_matrix_config.mode) {
dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n");
@@ -488,7 +469,7 @@ void rgb_matrix_init(void) {
}
void rgb_matrix_set_suspend_state(bool state) {
-#ifdef RGB_DISABLE_WHEN_USB_SUSPENDED
+#ifdef RGB_MATRIX_SLEEP
if (state && !suspend_state) { // only run if turning off, and only once
rgb_task_render(0); // turn off all LEDs when suspending
rgb_task_flush(0); // and actually flash led state to LEDs
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
index 9a3ffb8ea3..b1bf839bf6 100644
--- a/quantum/rgb_matrix/rgb_matrix.h
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -21,31 +21,10 @@
#include <stdint.h>
#include <stdbool.h>
#include "rgb_matrix_types.h"
+#include "rgb_matrix_drivers.h"
#include "color.h"
#include "keyboard.h"
-#if defined(RGB_MATRIX_IS31FL3218)
-# include "is31fl3218.h"
-#elif defined(RGB_MATRIX_IS31FL3731)
-# include "is31fl3731.h"
-#elif defined(RGB_MATRIX_IS31FL3733)
-# include "is31fl3733.h"
-#elif defined(RGB_MATRIX_IS31FL3736)
-# include "is31fl3736.h"
-#elif defined(RGB_MATRIX_IS31FL3737)
-# include "is31fl3737.h"
-#elif defined(RGB_MATRIX_IS31FL3741)
-# include "is31fl3741.h"
-#elif defined(IS31FLCOMMON)
-# include "is31flcommon.h"
-#elif defined(RGB_MATRIX_SNLED27351)
-# include "snled27351.h"
-#elif defined(RGB_MATRIX_AW20216S)
-# include "aw20216s.h"
-#elif defined(RGB_MATRIX_WS2812)
-# include "ws2812.h"
-#endif
-
#ifndef RGB_MATRIX_TIMEOUT
# define RGB_MATRIX_TIMEOUT 0
#endif
@@ -272,17 +251,6 @@ void rgb_matrix_set_flags_noeeprom(led_flags_t flags);
# define rgblight_decrease_speed_noeeprom rgb_matrix_decrease_speed_noeeprom
#endif
-typedef struct {
- /* Perform any initialisation required for the other driver functions to work. */
- void (*init)(void);
- /* Set the colour of a single LED in the buffer. */
- void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
- /* Set the colour of all LEDS on the keyboard in the buffer. */
- void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b);
- /* Flush any buffered changes to the hardware. */
- void (*flush)(void);
-} rgb_matrix_driver_t;
-
static inline bool rgb_matrix_check_finished_leds(uint8_t led_idx) {
#if defined(RGB_MATRIX_SPLIT)
if (is_keyboard_left()) {
@@ -295,8 +263,6 @@ static inline bool rgb_matrix_check_finished_leds(uint8_t led_idx) {
#endif
}
-extern const rgb_matrix_driver_t rgb_matrix_driver;
-
extern rgb_config_t rgb_matrix_config;
extern uint32_t g_rgb_timer;
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c
index 0f979cb233..b5e539657d 100644
--- a/quantum/rgb_matrix/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.c
@@ -14,7 +14,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "rgb_matrix.h"
+#include "rgb_matrix_drivers.h"
+
+#include <stdbool.h>
+#include "keyboard.h"
+#include "color.h"
#include "util.h"
/* Each driver needs to define the struct
@@ -72,12 +76,36 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
.set_color_all = is31fl3741_set_color_all,
};
-#elif defined(IS31FLCOMMON)
+#elif defined(RGB_MATRIX_IS31FL3742A)
+const rgb_matrix_driver_t rgb_matrix_driver = {
+ .init = is31fl3742a_init_drivers,
+ .flush = is31fl3742a_flush,
+ .set_color = is31fl3742a_set_color,
+ .set_color_all = is31fl3742a_set_color_all,
+};
+
+#elif defined(RGB_MATRIX_IS31FL3743A)
+const rgb_matrix_driver_t rgb_matrix_driver = {
+ .init = is31fl3743a_init_drivers,
+ .flush = is31fl3743a_flush,
+ .set_color = is31fl3743a_set_color,
+ .set_color_all = is31fl3743a_set_color_all,
+};
+
+#elif defined(RGB_MATRIX_IS31FL3745)
+const rgb_matrix_driver_t rgb_matrix_driver = {
+ .init = is31fl3745_init_drivers,
+ .flush = is31fl3745_flush,
+ .set_color = is31fl3745_set_color,
+ .set_color_all = is31fl3745_set_color_all,
+};
+
+#elif defined(RGB_MATRIX_IS31FL3746A)
const rgb_matrix_driver_t rgb_matrix_driver = {
- .init = IS31FL_RGB_init_drivers,
- .flush = IS31FL_common_flush,
- .set_color = IS31FL_RGB_set_color,
- .set_color_all = IS31FL_RGB_set_color_all,
+ .init = is31fl3746a_init_drivers,
+ .flush = is31fl3746a_flush,
+ .set_color = is31fl3746a_set_color,
+ .set_color_all = is31fl3746a_set_color_all,
};
#elif defined(RGB_MATRIX_SNLED27351)
@@ -103,7 +131,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
# endif
// LED color buffer
-rgb_led_t rgb_matrix_ws2812_array[RGB_MATRIX_LED_COUNT];
+rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_COUNT];
bool ws2812_dirty = false;
static void init(void) {
@@ -112,7 +140,7 @@ static void init(void) {
static void flush(void) {
if (ws2812_dirty) {
- ws2812_setleds(rgb_matrix_ws2812_array, RGB_MATRIX_LED_COUNT);
+ ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_COUNT);
ws2812_dirty = false;
}
}
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.h b/quantum/rgb_matrix/rgb_matrix_drivers.h
new file mode 100644
index 0000000000..8f919b1b3c
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.h
@@ -0,0 +1,47 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+
+#if defined(RGB_MATRIX_AW20216S)
+# include "aw20216s.h"
+#elif defined(RGB_MATRIX_IS31FL3218)
+# include "is31fl3218.h"
+#elif defined(RGB_MATRIX_IS31FL3731)
+# include "is31fl3731.h"
+#elif defined(RGB_MATRIX_IS31FL3733)
+# include "is31fl3733.h"
+#elif defined(RGB_MATRIX_IS31FL3736)
+# include "is31fl3736.h"
+#elif defined(RGB_MATRIX_IS31FL3737)
+# include "is31fl3737.h"
+#elif defined(RGB_MATRIX_IS31FL3741)
+# include "is31fl3741.h"
+#elif defined(RGB_MATRIX_IS31FL3742A)
+# include "is31fl3742a.h"
+#elif defined(RGB_MATRIX_IS31FL3743A)
+# include "is31fl3743a.h"
+#elif defined(RGB_MATRIX_IS31FL3745)
+# include "is31fl3745.h"
+#elif defined(RGB_MATRIX_IS31FL3746A)
+# include "is31fl3746a.h"
+#elif defined(RGB_MATRIX_SNLED27351)
+# include "snled27351.h"
+#elif defined(RGB_MATRIX_WS2812)
+# include "ws2812.h"
+#endif
+
+typedef struct {
+ /* Perform any initialisation required for the other driver functions to work. */
+ void (*init)(void);
+ /* Set the colour of a single LED in the buffer. */
+ void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
+ /* Set the colour of all LEDS on the keyboard in the buffer. */
+ void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b);
+ /* Flush any buffered changes to the hardware. */
+ void (*flush)(void);
+} rgb_matrix_driver_t;
+
+extern const rgb_matrix_driver_t rgb_matrix_driver;
diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c
index 8ac886d441..530cb04688 100644
--- a/quantum/rgblight/rgblight.c
+++ b/quantum/rgblight/rgblight.c
@@ -116,7 +116,7 @@ animation_status_t animation_status = {};
#endif
#ifndef LED_ARRAY
-rgb_led_t led[RGBLED_NUM];
+rgb_led_t led[RGBLIGHT_LED_COUNT];
# define LED_ARRAY led
#endif
@@ -126,7 +126,7 @@ rgblight_segment_t const *const *rgblight_layers = NULL;
static bool deferred_set_layer_state = false;
#endif
-rgblight_ranges_t rgblight_ranges = {0, RGBLED_NUM, 0, RGBLED_NUM, RGBLED_NUM};
+rgblight_ranges_t rgblight_ranges = {0, RGBLIGHT_LED_COUNT, 0, RGBLIGHT_LED_COUNT, RGBLIGHT_LED_COUNT};
void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
rgblight_ranges.clipping_start_pos = start_pos;
@@ -134,8 +134,8 @@ void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
}
void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) {
- if (start_pos >= RGBLED_NUM) return;
- if (start_pos + num_leds > RGBLED_NUM) return;
+ if (start_pos >= RGBLIGHT_LED_COUNT) return;
+ if (start_pos + num_leds > RGBLIGHT_LED_COUNT) return;
rgblight_ranges.effect_start_pos = start_pos;
rgblight_ranges.effect_end_pos = start_pos + num_leds;
rgblight_ranges.effect_num_leds = num_leds;
@@ -229,13 +229,7 @@ void rgblight_init(void) {
return;
}
- dprintf("rgblight_init called.\n");
dprintf("rgblight_init start!\n");
- if (!eeconfig_is_enabled()) {
- dprintf("rgblight_init eeconfig is not enabled.\n");
- eeconfig_init();
- eeconfig_update_rgblight_default();
- }
rgblight_config.raw = eeconfig_read_rgblight();
RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
if (!rgblight_config.mode) {
@@ -664,7 +658,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
}
void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
- if (!rgblight_config.enable || index >= RGBLED_NUM) {
+ if (!rgblight_config.enable || index >= RGBLIGHT_LED_COUNT) {
return;
}
@@ -700,7 +694,7 @@ static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_
#endif
void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end) {
- if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLED_NUM) {
+ if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLIGHT_LED_COUNT) {
return;
}
@@ -727,19 +721,19 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start,
#ifndef RGBLIGHT_SPLIT
void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) {
- rgblight_setrgb_range(r, g, b, 0, (uint8_t)RGBLED_NUM / 2);
+ rgblight_setrgb_range(r, g, b, 0, (uint8_t)RGBLIGHT_LED_COUNT / 2);
}
void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b) {
- rgblight_setrgb_range(r, g, b, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM);
+ rgblight_setrgb_range(r, g, b, (uint8_t)RGBLIGHT_LED_COUNT / 2, (uint8_t)RGBLIGHT_LED_COUNT);
}
void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) {
- rgblight_sethsv_range(hue, sat, val, 0, (uint8_t)RGBLED_NUM / 2);
+ rgblight_sethsv_range(hue, sat, val, 0, (uint8_t)RGBLIGHT_LED_COUNT / 2);
}
void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) {
- rgblight_sethsv_range(hue, sat, val, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM);
+ rgblight_sethsv_range(hue, sat, val, (uint8_t)RGBLIGHT_LED_COUNT / 2, (uint8_t)RGBLIGHT_LED_COUNT);
}
#endif // ifndef RGBLIGHT_SPLIT
@@ -789,7 +783,7 @@ static void rgblight_layers_write(void) {
break; // No more segments
}
// Write segment.count LEDs
- rgb_led_t *const limit = &led[MIN(segment.index + segment.count, RGBLED_NUM)];
+ rgb_led_t *const limit = &led[MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT)];
for (rgb_led_t *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) {
# ifdef RGBLIGHT_LAYERS_RETAIN_VAL
sethsv(segment.hue, segment.sat, current_val, led_ptr);
@@ -900,12 +894,6 @@ void rgblight_wakeup(void) {
#endif
-__attribute__((weak)) void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds) {
- ws2812_setleds(start_led, num_leds);
-}
-
-#ifndef RGBLIGHT_CUSTOM
-
void rgblight_set(void) {
rgb_led_t *start_led;
uint8_t num_leds = rgblight_ranges.clipping_num_leds;
@@ -915,42 +903,41 @@ void rgblight_set(void) {
led[i].r = 0;
led[i].g = 0;
led[i].b = 0;
-# ifdef RGBW
+#ifdef RGBW
led[i].w = 0;
-# endif
+#endif
}
}
-# ifdef RGBLIGHT_LAYERS
+#ifdef RGBLIGHT_LAYERS
if (rgblight_layers != NULL
-# if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF)
+# if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF)
&& rgblight_config.enable
-# elif defined(RGBLIGHT_SLEEP)
+# elif defined(RGBLIGHT_SLEEP)
&& !is_suspended
-# endif
+# endif
) {
rgblight_layers_write();
}
-# endif
+#endif
-# ifdef RGBLIGHT_LED_MAP
- rgb_led_t led0[RGBLED_NUM];
- for (uint8_t i = 0; i < RGBLED_NUM; i++) {
+#ifdef RGBLIGHT_LED_MAP
+ rgb_led_t led0[RGBLIGHT_LED_COUNT];
+ for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) {
led0[i] = led[pgm_read_byte(&led_map[i])];
}
start_led = led0 + rgblight_ranges.clipping_start_pos;
-# else
+#else
start_led = led + rgblight_ranges.clipping_start_pos;
-# endif
+#endif
-# ifdef RGBW
+#ifdef RGBW
for (uint8_t i = 0; i < num_leds; i++) {
convert_rgb_to_rgbw(&start_led[i]);
}
-# endif
- rgblight_call_driver(start_led, num_leds);
-}
#endif
+ rgblight_driver.setleds(start_led, num_leds);
+}
#ifdef RGBLIGHT_SPLIT
/* for split keyboard master side */
@@ -1279,8 +1266,8 @@ void rgblight_effect_snake(animation_status_t *anim) {
# endif
for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
k = pos + j * increment;
- if (k > RGBLED_NUM) {
- k = k % (RGBLED_NUM);
+ if (k > RGBLIGHT_LED_COUNT) {
+ k = k % (RGBLIGHT_LED_COUNT);
}
if (k < 0) {
k = k + rgblight_ranges.effect_num_leds;
@@ -1465,7 +1452,7 @@ typedef struct PACKED {
uint8_t max_life;
} TwinkleState;
-static TwinkleState led_twinkle_state[RGBLED_NUM];
+static TwinkleState led_twinkle_state[RGBLIGHT_LED_COUNT];
void rgblight_effect_twinkle(animation_status_t *anim) {
const bool random_color = anim->delta / 3;
diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h
index a222ab6b9f..9e2b073776 100644
--- a/quantum/rgblight/rgblight.h
+++ b/quantum/rgblight/rgblight.h
@@ -16,6 +16,12 @@
#pragma once
+// DEPRECATED DEFINES - DO NOT USE
+#if defined(RGBLED_NUM)
+# define RGBLIGHT_LED_COUNT RGBLED_NUM
+#endif
+// ========
+
/***** rgblight_mode(mode)/rgblight_mode_noeeprom(mode) ****
old mode number (before 0.6.117) to new mode name table
@@ -160,6 +166,7 @@ enum RGBLIGHT_EFFECT_MODE {
#include <stdint.h>
#include <stdbool.h>
+#include "rgblight_drivers.h"
#include "progmem.h"
#include "eeconfig.h"
#include "ws2812.h"
@@ -233,7 +240,7 @@ void rgblight_unblink_all_but_layer(uint8_t layer);
#endif
-extern rgb_led_t led[RGBLED_NUM];
+extern rgb_led_t led[RGBLIGHT_LED_COUNT];
extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
diff --git a/quantum/rgblight/rgblight_drivers.c b/quantum/rgblight/rgblight_drivers.c
new file mode 100644
index 0000000000..45b60e1a5f
--- /dev/null
+++ b/quantum/rgblight/rgblight_drivers.c
@@ -0,0 +1,20 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rgblight_drivers.h"
+
+#if defined(RGBLIGHT_WS2812)
+# include "ws2812.h"
+
+const rgblight_driver_t rgblight_driver = {
+ .setleds = ws2812_setleds,
+};
+
+#elif defined(RGBLIGHT_APA102)
+# include "apa102.h"
+
+const rgblight_driver_t rgblight_driver = {
+ .setleds = apa102_setleds,
+};
+
+#endif
diff --git a/quantum/rgblight/rgblight_drivers.h b/quantum/rgblight/rgblight_drivers.h
new file mode 100644
index 0000000000..f7125a6f3d
--- /dev/null
+++ b/quantum/rgblight/rgblight_drivers.h
@@ -0,0 +1,13 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+#include "color.h"
+
+typedef struct {
+ void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds);
+} rgblight_driver_t;
+
+extern const rgblight_driver_t rgblight_driver;
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 874339361d..2f592bd4cf 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -147,10 +147,10 @@ __attribute__((weak)) bool is_keyboard_left_impl(void) {
return readPin(SPLIT_HAND_PIN);
# endif
#elif defined(SPLIT_HAND_MATRIX_GRID)
-# ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT
- return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID);
-# else
+# ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_LEFT
return !peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID);
+# else
+ return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID);
# endif
#elif defined(EE_HANDS)
if (!eeconfig_is_enabled()) {