Repository navigation
1.3.1
Release Notes - November 30, 2025
Summary
This release focuses on Split Keyboard Communication Stability and RGB Synchronization Fix. The update resolves issues where the slave keyboard stops responding during LED effect switching on Iris CE, and RGB effects become out of sync after watchdog recovery. Key fixes include power consumption limits, split watchdog for automatic recovery, SPLIT_TRANSPORT_MIRROR for matrix state synchronization, and removal of framebuffer effects (TYPING_HEATMAP, DIGITAL_RAIN). Reactive effects are restored and work with SPLIT_TRANSPORT_MIRROR. Important: Both halves must be flashed with identical firmware.
Key Changes
1. Split Keyboard Communication Stability π§
Problem Solved: When switching LED effects on Iris CE split keyboard, the slave (right) half would stop responding entirely. After watchdog recovery, RGB effects were out of sync between halves.
Root Cause Analysis:
- Power Overconsumption: RGB Matrix brightness at 120 (default) draws excessive current during effect transitions
- Communication Overload: Three duplicate RM_NEXT keys in
_BOTH_UNDERlayer triggered simultaneous effect changes - No Recovery Mechanism: Split watchdog was disabled, preventing automatic recovery from communication failures
- Framebuffer Effects Not Synced: TYPING_HEATMAP and DIGITAL_RAIN use
g_rgb_frame_bufferwhich is NOT synchronized between split halves - Reactive Effects Require Keypress Position: SOLID_REACTIVE_*, SPLASH effects need keypress position info from both halves
Solution Implemented:
config.h Changes:
// Split Keyboard Stability Settings
#define SPLIT_TRANSPORT_MIRROR // Mirror master's matrix state to slave
#undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 100 // Reduced from 120 to limit power consumption
#define SPLIT_WATCHDOG_TIMEOUT 3000 // Auto-recovery after 3 seconds of communication loss
// Removed framebuffer effects (g_rgb_frame_buffer not synced):
// - TYPING_HEATMAP, DIGITAL_RAIN
// Reactive effects restored (work with SPLIT_TRANSPORT_MIRROR):
// - SOLID_REACTIVE_SIMPLE, SOLID_REACTIVE, SOLID_REACTIVE_WIDE
// - SOLID_REACTIVE_CROSS, SOLID_REACTIVE_NEXUS, SPLASH, SOLID_SPLASHrules.mk Changes:
SPLIT_WATCHDOG_ENABLE = yes # Enable automatic recovery from communication failureskeymap.c Changes:
- Removed duplicate RM_NEXT keys from
_BOTH_UNDERlayer (3 β 1) - Kept single RM_NEXT at top-left position (ESC key location)
Technical Details:
| Setting | Before | After | Impact |
|---|---|---|---|
RGB_MATRIX_MAXIMUM_BRIGHTNESS |
120 | 100 | ~17% power reduction |
SPLIT_WATCHDOG_ENABLE |
no | yes | Auto-recovery enabled |
SPLIT_WATCHDOG_TIMEOUT |
N/A | 3000ms | 3-second recovery window |
SPLIT_TRANSPORT_MIRROR |
no | yes | Matrix state synchronization |
RM_NEXT keys in _BOTH_UNDER |
3 | 1 | Reduced communication load |
| RGB Matrix effects | 30 | 28 | Framebuffer effects removed, Reactive restored |
2. Firmware Size Optimization π¦
Current Build Statistics:
- Firmware Size: 27,076 / 28,672 bytes (94%)
- Free Space: 1,596 bytes
- Improvement: From 98% to 94% utilization
Optimizations Applied:
| Optimization | Impact |
|---|---|
CONSOLE_ENABLE = no |
~1,000-1,500 bytes saved |
const β #define conversion |
Minor savings |
| RGB Matrix effects: 45 β 28 | Significant savings |
SPLIT_WATCHDOG_ENABLE = yes |
Minimal overhead added |
SPLIT_TRANSPORT_MIRROR |
+86 bytes for matrix sync |
RGB Matrix Effects (28 Enabled):
- Basic (5): Solid Color, Alpha Mods, Gradient Up/Down, Gradient Left/Right, Breathing
- Cycle (8): All, Left/Right, Up/Down, Out/In, Out/In Dual, Pinwheel, Spiral, Rainbow Moving Chevron
- Hue (3): Breathing, Pendulum, Wave
- Special (5): Raindrops, Jellybean Raindrops, Pixel Rain, Pixel Flow, Pixel Fractal
- Reactive (7): Solid Reactive (Simple, Standard, Wide, Cross, Nexus), Splash, Solid Splash
Removed Effects (Split Sync Issues):
- TYPING_HEATMAP, DIGITAL_RAIN (g_rgb_frame_buffer not synced between halves)
3. Layer 3 (_BOTH_UNDER) Layout Update πΉ
Before (3 RM_NEXT keys):
ββββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ
βRM_NEXT β _______β _______β _______β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
βKC_LPRN βKC_RPRN β KC_EQL β KC_GT βKC_LCBR βKC_RCBR β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______βKC_MINS β KC_GT β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ
β _______β _______β _______β _______β _______β _______β _______β
ββββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ
ββββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ
βRM_NEXT β _______β _______β _______β _______βQK_BOOT β β Was RM_NEXT
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______β _______β _______β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______β _______β _______β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______β _______β _______β _______βRM_NEXT β _______β β Was RM_NEXT
ββββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ
After (1 RM_NEXT key):
ββββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ
βRM_NEXT β _______β _______β _______β _______β _______β β Single RM_NEXT
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
βKC_LPRN βKC_RPRN β KC_EQL β KC_GT βKC_LCBR βKC_RCBR β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______βKC_MINS β KC_GT β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ
β _______β _______β _______β _______β _______β _______β _______β
ββββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ
ββββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ
β _______β _______β _______β _______β _______βQK_BOOT β β Now _______
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______β _______β _______β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______β _______β _______β _______β _______β
ββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββ€
β _______β _______β _______β _______β _______β _______β _______β β Now _______
ββββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ
Technical Specifications
Platform Support
- β Iris Rev7 (ATmega32u4): HEX file output
- β Iris CE Rev1 (RP2040): UF2 file output
Build Specifications
- Firmware Size: 27,004 / 28,672 bytes (94%)
- Free Space: 1,668 bytes
- QMK Version: Compatible with QMK 0.24.0+
Configuration Changes Summary
config.h:
#pragma once
// Split Keyboard Stability Settings
#define SPLIT_TRANSPORT_MIRROR // Matrix state sync
#undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 100
#define SPLIT_WATCHDOG_TIMEOUT 3000
// RGB Matrix Effects (21 total)
// Basic (5), Cycle (8), Hue (3), Special (5)
// Removed: Framebuffer effects, Reactive effectsrules.mk:
SPLIT_WATCHDOG_ENABLE = yes # Auto-recovery from communication failuresBuild Commands
# Iris Rev7 (ATmega32u4 - HEX file)
qmk compile -kb keebio/iris/rev7 -km zerodice0
# Iris CE Rev1 (RP2040 - UF2 file)
qmk compile -kb keebio/iris_ce/rev1 -km zerodice0Flash Firmware
# Rev7
qmk flash -kb keebio/iris/rev7 -km zerodice0
# CE Rev1 - Copy UF2 to RPI-RP2 driveTesting Guide
Split Keyboard Stability Test
- Flash firmware to both keyboard halves
- Connect keyboard via USB
- Rapidly switch LED effects using RM_NEXT key (FN1 + FN2 + ESC)
- Verify slave keyboard remains responsive
- If communication drops, wait 3 seconds for auto-recovery
Verification Checklist
- LED effects switch smoothly on both halves
- Slave keyboard responds to keypresses after effect changes
- No cable reconnection required during normal use
- Auto-recovery works after intentional cable disconnect/reconnect
Migration Guide
From Previous Version
No Breaking Changes: All existing functionality preserved.
New Behavior:
- RGB brightness reduced from 120 to 100 (slightly dimmer, more stable)
- Split watchdog enables automatic recovery from communication failures
- Single RM_NEXT key in
_BOTH_UNDERlayer (top-left position)
Testing Recommendations:
- Test LED effect switching extensively
- Verify both halves respond during effect transitions
- Test communication recovery by briefly disconnecting/reconnecting cable
Known Issues & Limitations
Resolved Issues
- β Slave keyboard unresponsive during LED effect switching: Fixed with brightness limit + watchdog + RM_NEXT deduplication
- β RGB sync broken after watchdog recovery: Fixed with SPLIT_TRANSPORT_MIRROR + removal of sync-problematic effects
Current Limitations
- βΉοΈ Brightness reduced: RGB effects are ~17% dimmer for stability
- βΉοΈ Single RM_NEXT key: Effect switching now only from left-hand side (FN1 + FN2 + ESC)
- βΉοΈ Reduced effect count: 21 effects (Framebuffer/Reactive effects removed)
- Removed: TYPING_HEATMAP, DIGITAL_RAIN, all SOLID_REACTIVE_*, SPLASH, SOLID_SPLASH
μμ½
μ΄ λ¦΄λ¦¬μ¦λ Split ν€λ³΄λ ν΅μ μμ μ± κ°μ κ³Ό RGB λκΈ°ν λ¬Έμ ν΄κ²°μ μ€μ μ λ‘λλ€. Iris CEμμ LED ν¨κ³Ό μ ν μ slave ν€λ³΄λκ° μλ΅νμ§ μκ³ , watchdog 볡ꡬ ν RGB μ±ν¬κ° λ§μ§ μλ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€. μ λ ₯ μλΉ μ ν, split watchdog, SPLIT_TRANSPORT_MIRROR νμ±ν, κ·Έλ¦¬κ³ framebuffer ν¨κ³Ό(TYPING_HEATMAP, DIGITAL_RAIN)λ₯Ό μ κ±°νμ΅λλ€. λ°μν ν¨κ³Όλ SPLIT_TRANSPORT_MIRRORλ‘ λμν©λλ€. μ€μ: μμͺ½ ν€λ³΄λ λͺ¨λ λμΌν νμ¨μ΄ νλμ νμ.
μ£Όμ λ³κ²½μ¬ν
1. Split ν€λ³΄λ ν΅μ μμ μ± π§
ν΄κ²°λ λ¬Έμ : Iris CE split ν€λ³΄λμμ LED ν¨κ³Όλ₯Ό μ νν λ slave(μ€λ₯Έμͺ½) μ λ°μ΄ μμ ν μλ΅νμ§ μμμ΅λλ€. ν€λ³΄λ μΌμ΄λΈμ 물리μ μΌλ‘ μ¬μ°κ²°νκΈ° μ κΉμ§ λ¬Έμ κ° μ§μλμμ΅λλ€.
κ·Όλ³Έ μμΈ λΆμ:
- μ λ ₯ κ³Όλ€ μλΉ: RGB Matrix λ°κΈ° 120(κΈ°λ³Έκ°)μ΄ ν¨κ³Ό μ ν μ€ κ³Όλν μ λ₯ μλΉ
- ν΅μ κ³ΌλΆν:
_BOTH_UNDERλ μ΄μ΄μ 3κ° μ€λ³΅ RM_NEXT ν€κ° λμ ν¨κ³Ό λ³κ²½ νΈλ¦¬κ±° - 볡ꡬ λ©μ»€λμ¦ μμ: Split watchdogμ΄ λΉνμ±νλμ΄ ν΅μ μ€ν¨ μ μλ 볡ꡬ λΆκ°
ꡬνλ ν΄κ²°μ± :
| μ€μ | μ΄μ | μ΄ν | μν₯ |
|---|---|---|---|
RGB_MATRIX_MAXIMUM_BRIGHTNESS |
120 | 100 | ~17% μ λ ₯ κ°μ |
SPLIT_WATCHDOG_ENABLE |
no | yes | μλ 볡ꡬ νμ±ν |
SPLIT_WATCHDOG_TIMEOUT |
N/A | 3000ms | 3μ΄ λ³΅κ΅¬ μ°½ |
SPLIT_TRANSPORT_MIRROR |
no | yes | λ§€νΈλ¦μ€ μν λκΈ°ν |
_BOTH_UNDERμ RM_NEXT ν€ |
3κ° | 1κ° | ν΅μ λΆν κ°μ |
| RGB Matrix ν¨κ³Ό | 30κ° | 28κ° | Framebuffer μ κ±°, Reactive 볡μ |
2. νμ¨μ΄ μ©λ μ΅μ ν π¦
νμ¬ λΉλ ν΅κ³:
- νμ¨μ΄ ν¬κΈ°: 27,076 / 28,672 bytes (94%)
- μ¬μ 곡κ°: 1,596 bytes
- κ°μ : 98%μμ 94% μ¬μ©λ₯ λ‘ κ°μ
μ μ©λ μ΅μ ν:
| μ΅μ ν | ν¨κ³Ό |
|---|---|
CONSOLE_ENABLE = no |
~1,000-1,500 bytes μ κ° |
const β #define λ³ν |
μν μ κ° |
| RGB Matrix ν¨κ³Ό: 45 β 28 | μλΉν μ κ° |
SPLIT_WATCHDOG_ENABLE = yes |
μ΅μ μ€λ²ν€λ μΆκ° |
SPLIT_TRANSPORT_MIRROR |
+86 bytes (λ§€νΈλ¦μ€ λκΈ°ν) |
3. λ μ΄μ΄ 3 (_BOTH_UNDER) λ μ΄μμ μ
λ°μ΄νΈ πΉ
- RM_NEXT ν€ 3κ°μμ 1κ°λ‘ κ°μ
- λ¨μΌ RM_NEXT ν€λ μΌμͺ½ μλ¨ μμΉ (ESC ν€ μμΉ)μ μ μ§
ν μ€νΈ κ°μ΄λ
Split ν€λ³΄λ μμ μ± ν μ€νΈ
- μμͺ½ ν€λ³΄λ μ λ°μ νμ¨μ΄ νλμ
- USBλ‘ ν€λ³΄λ μ°κ²°
- RM_NEXT ν€ (FN1 + FN2 + ESC)λ‘ LED ν¨κ³Ό λΉ λ₯΄κ² μ ν
- slave ν€λ³΄λκ° μλ΅μ μ μ§νλμ§ νμΈ
- ν΅μ μ΄ λμ΄μ§λ©΄ μλ 볡ꡬλ₯Ό μν΄ 3μ΄ λκΈ°
νμΈ μ²΄ν¬λ¦¬μ€νΈ
- LED ν¨κ³Όκ° μμͺ½μμ λΆλλ½κ² μ νλ¨
- ν¨κ³Ό λ³κ²½ ν slave ν€λ³΄λκ° ν€ μ λ ₯μ μλ΅ν¨
- μ μ μ¬μ© μ€ μΌμ΄λΈ μ¬μ°κ²°μ΄ νμ μμ
- μλμ μΈ μΌμ΄λΈ λΆλ¦¬/μ¬μ°κ²° ν μλ 볡ꡬ μλ
μλ €μ§ λ¬Έμ λ° μ νμ¬ν
ν΄κ²°λ λ¬Έμ
- β LED ν¨κ³Ό μ ν μ€ slave ν€λ³΄λ 무μλ΅: λ°κΈ° μ ν + watchdog + RM_NEXT μ€λ³΅ μ κ±°λ‘ ν΄κ²°
- β watchdog 볡ꡬ ν RGB μ±ν¬ κΉ¨μ§: SPLIT_TRANSPORT_MIRROR μΆκ° + λκΈ°ν λ¬Έμ ν¨κ³Ό μ κ±°
νμ¬ μ νμ¬ν
- βΉοΈ λ°κΈ° κ°μ: RGB ν¨κ³Όκ° μμ μ±μ μν΄ ~17% μ΄λμμ§
- βΉοΈ λ¨μΌ RM_NEXT ν€: ν¨κ³Ό μ νμ μ΄μ μΌμ μͺ½μμλ§ κ°λ₯ (FN1 + FN2 + ESC)
- βΉοΈ ν¨κ³Ό μ κ°μ: 21κ° ν¨κ³Ό (Framebuffer/Reactive ν¨κ³Ό μ κ±°)
- μ κ±°λ¨: TYPING_HEATMAP, DIGITAL_RAIN, λͺ¨λ SOLID_REACTIVE_*, SPLASH, SOLID_SPLASH