feat(q5_max): enable Keychron RGB and fix EEPROM persistence #18

Merged
rootiest merged 1 commits from feat/keychron-rgb-persistence into main 2026-04-13 16:37:08 +00:00
Owner

Summary

  • Enable KEYCHRON_RGB_ENABLE for the Q5 Max, wiring up PER_KEY_RGB and MIXED_RGB effects with proper defaults (default_per_key_led[], default_region[])
  • Fix a cascade of EEPROM bugs that caused the Launcher-configured RGB mode to revert to the default heatmap on every power cycle and wireless transport change
  • Pin VIA_EEPROM_MAGIC_ADDR to a fixed offset so future Keychron EEPROM growth can't silently corrupt the stored keymap

Changes by file

rules.mk

  • Add KEYCHRON_RGB_ENABLE = yes — master flag enabling all Keychron custom RGB code

eeconfig_kb.h

  • Add #undef EECONFIG_KB_DATA_SIZE before the Keychron redefinition to suppress redefinition of QMK's default-zero value

keychron_rgb.c — four EEPROM bug fixes

  1. retail_demo_enable never written to EEPROMeeconfig_reset_custom_rgb() used eeprom_read_block instead of eeprom_update_block, leaving 0xFF on freshly-flashed boards; retail_demo_task() treats any non-zero value as "demo active" and forces the mode to CUSTOM_MIXED_RGB every scan, preventing any other mode from sticking
  2. Retail demo clamp on load — clamp retail_demo_enable > 1 to 0 to recover boards already affected by the above
  3. Version stamp moved to reset patheeprom_update_dword(EECONFIG_KEYBOARD, ...) moved from eeconfig_init_custom_rgb() (load) to eeconfig_reset_custom_rgb() (write), so the version is only stamped when valid defaults are actually committed to EEPROM
  4. QMK RGB mode not persistedkc_rgb_save() now calls eeconfig_update_rgb_matrix() so the current mode (e.g. CUSTOM_MIXED_RGB) is saved alongside Keychron data; without this, rgb_matrix_init() on transport change reloads the compile-time default RGB_MATRIX_TYPING_HEATMAP

mixed_rgb.c / rgb_matrix_kb.inc

  • Add #include "eeconfig_custom_rgb.h" so EECONFIG_SIZE_CUSTOM_RGB is in scope for the compile guards that gate the custom effects

ansi_encoder.c

  • Define default_per_key_led[] (red Esc/CapsLock, yellow modifiers, blue alpha keys) and default_region[] (all keys in region 0) — both are extern'd by keychron_rgb.c

q5_max.c

  • Call eeconfig_init_custom_rgb() in keyboard_post_init_kb() so Keychron RGB arrays are loaded from EEPROM on boot instead of being zero-initialised
  • Add wireless_enter_connected_kb() hook: re-applies the EEPROM-saved QMK RGB mode after BT/2.4G reconnect in case the reconnect sequence resets the in-RAM mode before the display settles

keymap.c

  • DIP switch Win-side override: replace rgb_matrix_mode() / rgb_matrix_sethsv() calls (which write to EEPROM and overwrite the Launcher-configured mode) with a dip_win_active flag; rgb_matrix_indicators_advanced_user() paints all LEDs white each frame when the flag is set, leaving the active effect and EEPROM untouched
  • Add QK_CLEAR_EEPROM to the KEEB_CTL layer as an escape hatch for EEPROM recovery

config.h

  • Define VIA_EEPROM_MAGIC_ADDR 544 to anchor VIA keymap storage at a fixed EEPROM offset; without this, growth in EECONFIG_KB_DATA_SIZE silently shifts the keymap block, corrupting stored layouts (observed as layer-0 keys reverting to KC_NONE on boot)

Test plan

  • Compile succeeds with no errors
  • Launcher-configured Mixed RGB mode survives power cycle
  • Launcher-configured Mixed RGB mode survives BT ↔ 2.4G ↔ USB transport change
  • DIP switch Win side shows solid white; returning to Mac side restores the active Launcher effect
  • Layer 0 keymap (including Esc) is preserved correctly across power cycles
  • QK_CLEAR_EEPROM on KEEB_CTL layer resets EEPROM as expected
## Summary - Enable `KEYCHRON_RGB_ENABLE` for the Q5 Max, wiring up `PER_KEY_RGB` and `MIXED_RGB` effects with proper defaults (`default_per_key_led[]`, `default_region[]`) - Fix a cascade of EEPROM bugs that caused the Launcher-configured RGB mode to revert to the default heatmap on every power cycle and wireless transport change - Pin `VIA_EEPROM_MAGIC_ADDR` to a fixed offset so future Keychron EEPROM growth can't silently corrupt the stored keymap ## Changes by file ### `rules.mk` - Add `KEYCHRON_RGB_ENABLE = yes` — master flag enabling all Keychron custom RGB code ### `eeconfig_kb.h` - Add `#undef EECONFIG_KB_DATA_SIZE` before the Keychron redefinition to suppress redefinition of QMK's default-zero value ### `keychron_rgb.c` — four EEPROM bug fixes 1. **`retail_demo_enable` never written to EEPROM** — `eeconfig_reset_custom_rgb()` used `eeprom_read_block` instead of `eeprom_update_block`, leaving `0xFF` on freshly-flashed boards; `retail_demo_task()` treats any non-zero value as "demo active" and forces the mode to `CUSTOM_MIXED_RGB` every scan, preventing any other mode from sticking 2. **Retail demo clamp on load** — clamp `retail_demo_enable > 1` to `0` to recover boards already affected by the above 3. **Version stamp moved to reset path** — `eeprom_update_dword(EECONFIG_KEYBOARD, ...)` moved from `eeconfig_init_custom_rgb()` (load) to `eeconfig_reset_custom_rgb()` (write), so the version is only stamped when valid defaults are actually committed to EEPROM 4. **QMK RGB mode not persisted** — `kc_rgb_save()` now calls `eeconfig_update_rgb_matrix()` so the current mode (e.g. `CUSTOM_MIXED_RGB`) is saved alongside Keychron data; without this, `rgb_matrix_init()` on transport change reloads the compile-time default `RGB_MATRIX_TYPING_HEATMAP` ### `mixed_rgb.c` / `rgb_matrix_kb.inc` - Add `#include "eeconfig_custom_rgb.h"` so `EECONFIG_SIZE_CUSTOM_RGB` is in scope for the compile guards that gate the custom effects ### `ansi_encoder.c` - Define `default_per_key_led[]` (red Esc/CapsLock, yellow modifiers, blue alpha keys) and `default_region[]` (all keys in region 0) — both are `extern`'d by `keychron_rgb.c` ### `q5_max.c` - Call `eeconfig_init_custom_rgb()` in `keyboard_post_init_kb()` so Keychron RGB arrays are loaded from EEPROM on boot instead of being zero-initialised - Add `wireless_enter_connected_kb()` hook: re-applies the EEPROM-saved QMK RGB mode after BT/2.4G reconnect in case the reconnect sequence resets the in-RAM mode before the display settles ### `keymap.c` - **DIP switch Win-side override**: replace `rgb_matrix_mode()` / `rgb_matrix_sethsv()` calls (which write to EEPROM and overwrite the Launcher-configured mode) with a `dip_win_active` flag; `rgb_matrix_indicators_advanced_user()` paints all LEDs white each frame when the flag is set, leaving the active effect and EEPROM untouched - Add `QK_CLEAR_EEPROM` to the KEEB_CTL layer as an escape hatch for EEPROM recovery ### `config.h` - Define `VIA_EEPROM_MAGIC_ADDR 544` to anchor VIA keymap storage at a fixed EEPROM offset; without this, growth in `EECONFIG_KB_DATA_SIZE` silently shifts the keymap block, corrupting stored layouts (observed as layer-0 keys reverting to `KC_NONE` on boot) ## Test plan - [x] Compile succeeds with no errors - [x] Launcher-configured Mixed RGB mode survives power cycle - [x] Launcher-configured Mixed RGB mode survives BT ↔ 2.4G ↔ USB transport change - [x] DIP switch Win side shows solid white; returning to Mac side restores the active Launcher effect - [x] Layer 0 keymap (including Esc) is preserved correctly across power cycles - [x] `QK_CLEAR_EEPROM` on KEEB_CTL layer resets EEPROM as expected
rootiest added 1 commit 2026-04-13 16:32:47 +00:00
Enable KEYCHRON_RGB_ENABLE for the Q5 Max, wiring up PER_KEY_RGB and
MIXED_RGB effects, and fix a cascade of EEPROM bugs that caused the
Launcher-configured RGB mode to revert to the default heatmap on every
power cycle and wireless transport change.

Keychron RGB enablement:
- Add KEYCHRON_RGB_ENABLE = yes to rules.mk
- Define default_per_key_led[] and default_region[] for the ANSI Encoder
  layout in ansi_encoder.c (extern'd by keychron_rgb.c)
- Fix missing #include "eeconfig_custom_rgb.h" in mixed_rgb.c and
  rgb_matrix_kb.inc so EECONFIG_SIZE_CUSTOM_RGB is in scope for the
  compile guards that gate the custom effects
- Add #undef EECONFIG_KB_DATA_SIZE before the Keychron redefinition in
  eeconfig_kb.h to suppress redefinition of QMK's default-zero value

EEPROM persistence fixes (keychron_rgb.c):
- Fix retail_demo_enable never being written to EEPROM in
  eeconfig_reset_custom_rgb(): original code used eeprom_read_block
  instead of eeprom_update_block, leaving 0xFF on freshly-flashed
  boards; retail_demo_task() treats any non-zero value as "demo active"
  and forces the mode to CUSTOM_MIXED_RGB every scan
- Clamp retail_demo_enable > 1 to 0 on load to recover boards already
  affected by the above bug
- Move EECONFIG_KEYBOARD version stamp from eeconfig_init_custom_rgb()
  (load path) to eeconfig_reset_custom_rgb() (reset/write path) so the
  version is only stamped when valid defaults are actually written
- Call eeconfig_update_rgb_matrix() in kc_rgb_save() so the current QMK
  RGB mode is persisted alongside Keychron data; without this,
  rgb_matrix_init() (called on every transport change) reloads the
  compile-time default RGB_MATRIX_TYPING_HEATMAP from EEPROM

Transport-change persistence (q5_max.c):
- Call eeconfig_init_custom_rgb() in keyboard_post_init_kb() so Keychron
  RGB arrays are loaded from EEPROM on every boot instead of being
  zero-initialised
- Add wireless_enter_connected_kb() hook: re-applies the EEPROM-saved
  QMK RGB mode after BT/2.4G reconnect in case the reconnect sequence
  resets the in-RAM mode before the display settles

DIP switch Win-side override (keymap.c):
- Replace rgb_matrix_mode() / rgb_matrix_sethsv() calls (which write to
  EEPROM and permanently overwrite the Launcher mode) with a
  dip_win_active flag; rgb_matrix_indicators_advanced_user() paints all
  LEDs white each frame when the flag is set, leaving the active effect
  and EEPROM untouched

VIA keymap address pinning (config.h):
- Define VIA_EEPROM_MAGIC_ADDR 544 to anchor VIA keymap storage at a
  fixed EEPROM offset; without this, growth in EECONFIG_KB_DATA_SIZE
  silently shifts the keymap block, corrupting stored layouts (observed
  as layer-0 keys reverting to KC_TRNS / KC_NONE on boot)
rootiest merged commit 2da8bab7a5 into main 2026-04-13 16:37:08 +00:00
rootiest deleted branch feat/keychron-rgb-persistence 2026-04-13 16:37:08 +00:00
Sign in to join this conversation.