Skip to content

Keymap System

Mae PUGIN edited this page Mar 21, 2026 · 1 revision

Keymap System

Overview

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 Architecture

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

Key Definitions

All keycodes are 16-bit values defined in main/input/key_definitions.h.

Standard HID Keycodes (0x0000 - 0x00FF)

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)

Special Keycodes

Value Macro Description
0x0000 K_NO No action
0x0001 K_TRNS Transparent (fall through to layer 0)

Layer Operations (0x00FF+)

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

Layer Hold Example

To make a key switch to layer 1 while held:

  • Keycode: 0x0124 (LAYER_HOLD_BASE_VAL + 1)

Default Keymap

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",
    "", "", "", "", "", "", ""
};

NVS Persistence

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

Load Order (at boot)

  1. keymap_init_nvs() — open NVS handle
  2. load_keymaps() — restore keymaps (falls back to compiled defaults)
  3. load_layout_names() — restore layer names
  4. load_macros() — restore macros
  5. load_key_stats() — restore key press counters
  6. load_bigram_stats() — restore bigram data

Save Triggers

  • Keymaps: saved immediately on SETKEY or SETLAYER CDC command
  • Layer names: saved immediately on LAYOUTNAME CDC command
  • Macros: saved immediately on MACROADD or MACRODEL
  • 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)

Macros

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;

Adding a Macro via CDC

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.

Configuration Constants

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

Clone this wiki locally