Skip to content

About

My keymap for my Lily58 with a Pimoroni trackball on each side.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lily58 Advanced Trackball Keymap

A highly customized QMK keymap for the Lily58 split keyboard featuring dual Pimoroni trackball integration with advanced mouse emulation, adaptive cursor scaling, and dynamic layer management.

Hardware Requirements

  • Keyboard: Lily58 Rev1 split keyboard
  • MCU: RP2040 (both halves)
  • Pointing Devices: Pimoroni trackball modules on both left and right halves
  • Communication: I2C for trackballs, serial/SPI for split communication

Core Features

🖱️ Dual Trackball System

Adaptive Cursor Scaling

  • Dynamic acceleration: Cursor speed automatically adjusts based on movement velocity
  • Growth Factor: Configurable multiplier (default: 8x, adjustable via keycodes)
  • Momentum smoothing: 0.06 exponential moving average for fluid motion
  • Scale range: 0.0001x to 64x maximum scaling
  • Hardware acceleration: Utilizes RP2040's built-in FPU for floating-point calculations

Three Emulation Modes (Per Trackball)

  1. Standard Mouse Mode (Default)

    • Full precision cursor control with adaptive scaling
    • Independent operation of left and right trackballs
  2. Arrow Key Emulation Mode

    • Converts trackball movement to arrow key presses
    • Momentum factor: 0.99 (smoothing)
    • Step threshold: 6 pixels per arrow key tap
    • Ideal for text navigation and menu selection
  3. Scroll Wheel Emulation Mode

    • Horizontal and vertical scrolling
    • Divisor: 8.0 (configurable speed)
    • Smooth fractional accumulation
    • Natural scroll direction (drag-to-scroll metaphor)

Mode Switching

  • Double-tap detection: Tap trackball button twice within 400ms to enter Arrow Mode
  • Press-and-hold: Hold trackball button for 400ms to enter Scroll Mode
  • Toggle off: Single tap when in any mode returns to Standard Mode
  • Visual feedback: RGB LED indicates current mode per trackball
    • Blue: Standard Mouse Mode
    • Red: Arrow Key Emulation
    • Green: Scroll Emulation

🎨 RGB LED Status Indicators

Dynamic RGB feedback on both trackball modules:

State Color Condition
Base Layer (Normal) Blue Default state, BTN_SWAP off
Base Layer (Swapped) White BTN_SWAP enabled
Layer 1 (Lower) Red Navigation/numpad layer active
Layer 2 (Upper) Green Function/system control layer active
Layer 3 (Auto Mouse) Yellow Auto mouse layer active
Layer 4 (Settings) White/Blue Settings layer (varies with BTN_SWAP)
Caps Lock Active Violet Caps Lock on (layer 0 only)

⌨️ Advanced Layer System

5 Layers with Dynamic Switching

  • Layer 0: Base QWERTY with home row mods
  • Layer 1: Navigation, numpad, media controls
  • Layer 2: Window management, browser controls, function keys
  • Layer 3: Auto Mouse Layer (automatic activation)
  • Layer 4: Settings and configuration

Layer Jump Handler

  • Tap-or-hold behavior: 200ms delay before layer activation
  • Double-tap prevention: Smart handling of rapid key presses
  • Delayed release: 200ms timeout after key release to prevent sticky layers
  • Shared timers: Efficient timer management across similar keycodes

Auto Mouse Layer (Optional)

  • Automatic activation: Layer 3 enables when trackball movement detected
  • Timeout: 1500ms of inactivity returns to previous layer
  • Manual toggle: Can be enabled/disabled via keycode or combo (5+6)
  • Activity tracking: Monitors arrow keys, mouse buttons, and trackball movement
  • Limiter: 500ms minimum between timer updates to reduce overhead

🔄 Button Swap System

Dynamically remaps dual-function keys based on workflow:

Normal Mode (BTN_SWAP off):
- O_CAPS_L1: Space (tap) / Space (hold) / Layer 1 (hold 200ms)
- I_SPC_L1: Caps (tap) / Space (hold) / Layer 1 (hold 200ms)

Swapped Mode (BTN_SWAP on):
- O_CAPS_L1: Caps (tap) / Space (hold) / Layer 1 (hold 200ms)
- I_SPC_L1: Space (tap) / Space (hold) / Layer 1 (hold 200ms)

RGB feedback: Trackball LEDs change to white/blue to indicate swap state Sync: Master automatically syncs swap state to slave via RPC

🎯 Home Row Mods

  • F: Left Control (MOD_LCTL)
  • G: Left Shift (MOD_LSFT)
  • H: Right Shift (MOD_RSFT)
  • J: Right Control (MOD_RCTL)
  • Tapping term: 280ms (customized for home row)

🔗 Key Combos (21 Total)

Combo Keys Output Purpose
Left Parenthesis E + W ( Quick bracket access
Right Parenthesis I + O ) Quick bracket access
Left Brace D + S { Quick bracket access
Right Brace L + K } Quick bracket access
Left Bracket C + X [ Quick bracket access
Right Bracket . + , ] Quick bracket access
Delete F + D Del Quick delete
Backspace K + J Bksp Quick backspace
Left Middle Mouse L_MB1 + L_MB2 MB3 Middle click (left trackball)
Right Middle Mouse R_MB1 + R_MB2 MB3 Middle click (right trackball)
Mouse Layer Middle ML_MB1 + ML_MB2 MB3 Middle click (mouse layer)
Refresh LTB_BK + RTB_FW F5 Browser refresh
Caps Lock Tab + Q Caps Quick caps lock
Auto Mouse Toggle 5 + 6 ML_AUTO Toggle auto mouse layer
Equals 0 + Backspace = Quick equals sign
Button Swap Esc + 1 B_SWAP Toggle button swap
Ctrl+Delete F + G Ctrl+Del Delete word forward
Ctrl+Backspace H + J Ctrl+Bksp Delete word backward
Password Macro B + Play " 2326" Custom password entry
Left Arrow C + V < Shift+comma
Right Arrow M + , > Shift+period

⏱️ Timing & Performance

Timer Management

  • 32-bit timers: Caps lock timer uses uint32_t to prevent overflow (30+ second timeout)
  • 16-bit timers: All other timers (safe for <60 second durations)
  • Timer limiter: 500ms minimum between updates to reduce overhead
  • Housekeeping rate: Runs every matrix scan (~1000Hz)

Caps Lock Auto-Off

  • Timeout: 30,000ms (30 seconds) of inactivity
  • Overflow protection: Uses 32-bit timer and timer_elapsed32()

Mouse Report Processing

  • Polling rate: 100-1000Hz depending on trackball activity
  • Layer caching: Single calculation per layer change (not per mouse report)
  • Optimized lookups: Cached highest layer state for performance

Tapping Terms (Customized)

  • Home row mods: 280ms
  • Layer toggle keys: 100ms (Play/Mute)
  • Special layers: 0ms (instant activation for LT(4))
  • Default: 200ms (TAPPING_TERM)

🔧 Custom Keycodes (37 Total)

Dual-Function Keys

  • ESC_GRV: Esc (tap) / Grave (hold)
  • BSPC_MINS: Backspace (tap) / Minus (hold) / Minus with Shift
  • R_MB1/R_MB2: Letters Y/U (tap) / Mouse buttons (on trackball movement)
  • L_MB1/L_MB2: Letters T/R (tap) / Mouse buttons (on trackball movement)
  • ML_MB1/ML_MB2: Mouse buttons (auto mouse layer)

Navigation Combos

  • LTB_BK: Left Tab (tap) / Browser Back (hold)
  • RTB_FW: Right Tab (tap) / Browser Forward (hold)
  • CT_UN: Close Tab (tap) / Undo Close Tab (hold)
  • CW_LW: Last Window (tap) / Cycle Windows (hold)
  • DL_DR: Virtual Desktop Left (tap) / Right (hold)
  • PD_PU: Page Down (tap) / Page Up (hold)
  • HM_EN: Home (tap) / End (hold)

Media & System

  • NX_PR: Next Track (tap) / Previous Track (hold)
  • VU_VD: Volume Up (tap) / Volume Down (hold)
  • UN_RE: Undo (tap) / Redo (hold)
  • CO_PA: Copy (tap) / Paste (hold)
  • DE_CU: Delete (tap) / Cut (hold)
  • CW_FS: Close Window (tap) / Fullscreen (hold)
  • CT_TW: Cycle Taskbar (tap) / Alt+Tab Window Cycle (hold)

Configuration

  • B_SWAP: Toggle button swap mode
  • ML_AUTO: Toggle auto mouse layer
  • FX_SLV_M/P: Decrease/increase growth factor (÷2 / ×2)

🔌 Split Communication

RPC (Remote Procedure Call) System

  • Message types:
    1. Layer sync (type 1): Updates slave trackball RGB on layer changes
    2. Button swap sync (type 2): Synchronizes BTN_SWAP state across halves
  • Automatic sync: Master sends updates on every layer change
  • Initialization: BTN_SWAP state synced on keyboard boot
  • Safety checks: Master-only transmission, slave-only reception

RGB Synchronization

  • Target modes:
    • Slave only (0): Updates only slave trackball
    • Master only (1): Updates only master trackball
    • Both (2): Updates both trackballs simultaneously
  • Conditional updates: Only sends RPC when necessary to reduce I2C traffic

🛡️ Safety & Error Handling

  • Master/slave checks: All split-specific code protected by is_keyboard_master()
  • Bounds validation: Layer values validated before RPC transmission
  • Overflow protection: 32-bit timers for long-duration timeouts
  • Race condition prevention: Mutual exclusion with else if in housekeeping
  • Timer consistency: Cached timer values within single events
  • Mode state validation: Enum-based mode system prevents invalid states

💾 Memory Efficiency

  • Static allocations: All state variables pre-allocated (no malloc)
  • Cached layer state: Single calculation stored for repeated use
  • Minimal RPC overhead: 2-byte messages for synchronization
  • Efficient timers: 16-bit timers where sufficient, 32-bit only when needed

Build Commands

# Left half
make lily58/rev1:via:flash -e POINTING_DEVICE=trackball_trackball -e POINTING_DEVICE_POSITION=left -j 8

# Right half
make lily58/rev1:via:flash -e POINTING_DEVICE=trackball_trackball -e POINTING_DEVICE_POSITION=right -j 8

Configuration Files Required

config.h

#define TAPPING_TERM 200
#define TAPPING_TERM_PER_KEY
#define SPLIT_TRANSACTION_IDS_USER USER_SYNC
#define DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD  // Optional
#define BOTH_SHIFTS_TURNS_ON_CAPS_WORD       // Optional

rules.mk

COMBO_ENABLE = yes
CAPS_WORD_ENABLE = yes
SEND_STRING_ENABLE = yes
MOUSEKEY_ENABLE = yes
POINTING_DEVICE_ENABLE = yes

Performance Characteristics

CPU Usage (RP2040 @ 133MHz)

  • Layer caching optimization: ~0.14% CPU saved (~184,000 cycles/sec)
  • Mouse processing: <1% CPU during active trackball use
  • Idle overhead: Minimal (<0.1% CPU)

Latency

  • Key response: <5ms (typical QMK matrix scan)
  • Mouse reports: 1-10ms depending on polling rate
  • Layer changes: Instant (cached state)
  • RGB updates: <2ms per update

Tolerance & Limits

  • Maximum layers: 5 (0-4)
  • Timer overflow protection: Up to 49.7 days (32-bit timers)
  • Growth factor range: 0.25x to theoretically unlimited (practical max ~64x)
  • Combo term: 50ms default (configurable per combo)
  • Double-tap window: 400ms for mode switching

Usage Tips

  1. Mouse Sensitivity Adjustment: Use FX_SLV_M/P keys to halve or double the cursor acceleration on-the-fly
  2. Arrow Key Navigation: Double-tap trackball button for precise text editing without leaving home position
  3. Scrolling: Hold trackball button for 400ms to activate smooth scrolling
  4. Button Swap: Toggle with combo (Esc+1) to switch between typing and mousing workflows
  5. Auto Mouse Layer: Enable for automatic layer switching when moving trackball
  6. Home Row Mods: Slight delay (280ms) allows normal typing without accidental modifiers

Customization

All constants are defined at the top of the keymap for easy modification:

  • LAYER_CHANGE_DELAY: 200ms
  • TIMER_LIMITER: 500ms
  • ATML_TIMEOUT: 1500ms
  • RGB_MS_TIMEOUT: 1500ms
  • ARROW_MOMENTUM: 0.99
  • ARROW_STEP: 6 pixels
  • SCROLL_DIVISOR_H/V: 8.0
  • GROWTH_FACTOR: 8.0 (adjustable at runtime)
  • MOMENTUM: 0.06
  • MIN_SCALE: 0.0001
  • MAX_SCALE: 64.0

Credits

Based on QMK Firmware with extensive customization for dual trackball integration and advanced mouse emulation.


License: GPL v2 (inherited from original Lily58 keymap by Naoki Katahira)

About

My keymap for my Lily58 with a Pimoroni trackball on each side.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages