-
Notifications
You must be signed in to change notification settings - Fork 4
Keymap System
Mae PUGIN edited this page Mar 21, 2026
·
1 revision
KeSp supports 10 layers of keymaps, each mapping every matrix position to a 16-bit keycode. Keymaps are stored in NVS (Non-Volatile Storage) and survive power cycles. They can be modified at runtime via the CDC Protocol.
Layer 9 ─── highest priority
Layer 8
...
Layer 1
Layer 0 ─── base layer (always active as fallback)
- Only one layer is active at a time (
current_layout, 0-9) -
K_TRNS(transparent) keys fall through to layer 0 - Layer switching is done via special keycodes
All keycodes are 16-bit values defined in main/input/key_definitions.h.
Standard USB HID Usage Table keycodes:
| Range | Keys |
|---|---|
0x04-0x1D
|
A-Z |
0x1E-0x27
|
1-9, 0 |
0x28 |
Enter |
0x29 |
Escape |
0x2A |
Backspace |
0x2B |
Tab |
0x2C |
Space |
0x2D-0x38
|
Symbols (-=[]\ etc.) |
0x3A-0x45
|
F1-F12 |
0x4F-0x52
|
Arrow Right/Left/Down/Up |
0xE0-0xE7
|
Modifiers (LCtrl, LShift, LAlt, LGUI, RCtrl, RShift, RAlt, RGUI) |
| Value | Macro | Description |
|---|---|---|
0x0000 |
K_NO |
No action |
0x0001 |
K_TRNS |
Transparent (fall through to layer 0) |
| Range | Description |
|---|---|
0x0100-0x0109
|
Layer select — switch to layer 0-9 permanently |
0x0123-0x012C
|
Layer hold — switch to layer 0-9 while held, return on release |
0x0135+ |
Plugin keys — macros and extensions |
To make a key switch to layer 1 while held:
- Keycode:
0x0124(LAYER_HOLD_BASE_VAL + 1)
Each board defines its default keymap in boards/<name>/board_keymap.c:
uint16_t keymaps[LAYERS][MATRIX_ROWS][MATRIX_COLS] = {
/* Layer 0 */
{
{ K_ESC, K_QUOT, K_COMM, K_DOT, ... },
{ K_TAB, K_A, K_O, K_E, ... },
...
},
/* Layer 1 */
{ ... },
...
};
char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH] = {
"Dvorak",
"Extra",
"QWERTY",
"", "", "", "", "", "", ""
};Keymaps are stored in NVS under the "storage" namespace:
| NVS Key | Type | Content |
|---|---|---|
"keymaps" |
blob | Full keymaps[] array |
"layout_names" |
blob | Full default_layout_names[] array |
"macros" |
blob | All macro definitions |
"macros_count" |
uint32 | Number of active macros |
"key_stats" |
blob | Per-key press counters |
"bigram_stats" |
blob | Key-pair frequency counters |
-
keymap_init_nvs()— open NVS handle -
load_keymaps()— restore keymaps (falls back to compiled defaults) -
load_layout_names()— restore layer names -
load_macros()— restore macros -
load_key_stats()— restore key press counters -
load_bigram_stats()— restore bigram data
-
Keymaps: saved immediately on
SETKEYorSETLAYERCDC command -
Layer names: saved immediately on
LAYOUTNAMECDC command -
Macros: saved immediately on
MACROADDorMACRODEL - Key stats: auto-saved every 100 keypresses OR every 60 seconds
- Bigrams: auto-saved every 100 keypresses OR every 120 seconds (disabled if NVS full)
Up to 20 macros, each with:
- Name: up to 15 characters
- Keys: up to 6 keycodes (played in sequence)
- Key definition: internal keycode assigned to the macro
typedef struct {
char name[16]; // null-terminated
uint8_t keys[6]; // HID keycodes
uint16_t key_definition; // assigned keycode (0x0135+)
} macro_t;MACROADD 0;Copy;0xE0,0x06 → Ctrl+C (LCtrl=0xE0, C=0x06)
MACROADD 1;Paste;0xE0,0x19 → Ctrl+V (LCtrl=0xE0, V=0x19)
Then assign the macro's key_definition to a position in any layer using SETKEY.
Defined in main/input/keyboard_config.h:
| Constant | Value | Description |
|---|---|---|
LAYERS |
10 | Total available layers |
MAX_LAYER |
9 | Max layer index |
MAX_LAYOUT_NAME_LENGTH |
15 | Max chars per layer name |
MAX_MACROS |
20 | Max macro slots |
MAX_MACRO_NAME_LENGTH |
16 | Max chars per macro name (incl. null) |
NKRO |
defined | N-key rollover enabled |