8.8 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	QMK Flash Tools - Modular Edition
Automated flashing tools for QMK split keyboards with RP2040 controllers (like Liatris).
📁 Structure
qmk_flash_tools/
├── autoflash_modular.sh       # Main flashing script
├── lib/                        # Reusable library modules
│   ├── device_detection.sh     # USB device detection functions
│   ├── side_mapping.sh         # Device-to-side mapping storage
│   └── qmk_helpers.sh          # QMK build/flash wrappers
├── test/                       # Standalone test scripts
│   ├── test_device_detection.sh
│   ├── test_side_mapping.sh
│   └── test_qmk_helpers.sh
└── README.md                   # This file
🚀 Quick Start
1. Flash Both Sides
cd qmk_flash_tools
chmod +x autoflash_modular.sh
./autoflash_modular.sh
The script will:
- Build firmware once
 - First time only: Ask which side you'll flash (left/right)
 - Subsequent runs: Auto-detect which side is plugged in
 - Wait for you to enter bootloader
 - Verify and flash with correct handedness
 - Repeat for the other side
 
2. Test Individual Components
# Test device detection
cd test
chmod +x test_device_detection.sh
./test_device_detection.sh
# Test side mapping
chmod +x test_side_mapping.sh
./test_side_mapping.sh
# Test QMK helpers
chmod +x test_qmk_helpers.sh
./test_qmk_helpers.sh
🔧 Configuration
Edit the top of autoflash_modular.sh:
KEYBOARD="fingerpunch/sweeeeep"  # Your keyboard
KEYMAP="smathev"                 # Your keymap
USB_MOUNT_PATHS=(...)            # Where USB drives mount
SIDE_MAPPING_FILE="..."          # Device mappings (defaults to ./device_mappings.json)
📚 Library Documentation
device_detection.sh
Functions for detecting RP2040 devices via host USB information.
Key Functions:
wait_for_rp2040()- Wait for device to enter bootloaderget_usb_serial_from_host(mount_point)- Get USB serial from hostget_usb_device_path(mount_point)- Get USB port locationget_device_identifier(mount_point)- Get best available IDprint_device_info(mount_point)- Debug info
Example:
source lib/device_detection.sh
mount_point=$(wait_for_rp2040)
device_id=$(get_device_identifier "$mount_point")
echo "Device: $device_id"
side_mapping.sh
Functions for storing and retrieving which device is left/right.
Key Functions:
init_mapping_file()- Create mapping file if neededsave_side_mapping(device_id, side)- Save mappingget_saved_side(device_id)- Retrieve saved sidedetect_side(device_id)- Get side (prompts if unknown)list_all_mappings()- Show all saved mappingsclear_mapping(device_id)- Remove a mappingclear_all_mappings()- Reset all mappings
Example:
source lib/side_mapping.sh
export SIDE_MAPPING_FILE="./device_mappings.json"
save_side_mapping "serial:ABC123" "left"
side=$(get_saved_side "serial:ABC123")
echo "Side: $side"
qmk_helpers.sh
Wrapper functions for QMK CLI commands.
Key Functions:
check_qmk_installed()- Verify QMK is availablebuild_firmware(keyboard, keymap)- Compile firmwareflash_side(keyboard, keymap, side)- Flash with handednessflash_with_bootloader(keyboard, keymap, bootloader)- Flash with specific bootloaderverify_keyboard_exists(keyboard)- Check keyboard definitionclean_build()- Clean build artifacts
Example:
source lib/qmk_helpers.sh
check_qmk_installed || exit 1
build_firmware "fingerpunch/sweeeeep" "smathev"
flash_side "fingerpunch/sweeeeep" "smathev" "left"
🧪 Testing Workflow
Test Device Detection
- Without device:
 
./test/test_device_detection.sh
# Shows "no device found", good for baseline
- With device:
 
# Enter bootloader mode on keyboard
./test/test_device_detection.sh
# Shows USB serial, path, and identifier
Test Side Mapping
./test/test_side_mapping.sh
# Runs comprehensive tests:
# - Create mapping file
# - Save/retrieve mappings
# - Clear mappings
# - Interactive prompt (optional)
Test QMK Helpers
./test/test_qmk_helpers.sh
# Tests:
# - QMK installation check
# - Keyboard verification
# - Build (optional)
# - Function signatures
🐛 Troubleshooting
Device not detected
# Check if device appears
ls /media/$USER/
# Should see RPI-RP2 or similar
# Run device detection test
./test/test_device_detection.sh
Can't identify device
The script uses these methods in order:
- USB serial number (most reliable)
 - USB physical port path
 - Mount point name (fallback)
 
Check which method worked:
source lib/device_detection.sh
mount_point="/media/$USER/RPI-RP2"
print_device_info "$mount_point"
Side mismatch detected
If you see a mismatch warning:
Option 1: Exit and plug in correct side (safest)
- Choose 
[e]to exit - Unplug the keyboard
 - Plug in the correct side
 - Run the script again
 
Option 2: Update the mapping
- Choose 
[c]to clear old mapping and save new one - Use this if you know the old mapping was wrong
 
Option 3: Force flash (dangerous!)
- Choose 
[f]to flash anyway - Only use if you're absolutely certain
 - May result in swapped left/right behavior
 
Or manually reset mappings:
source lib/side_mapping.sh
clear_mapping "serial:ABC123"  # Use your device ID
Or reset all mappings:
cd qmk_flash_tools
rm device_mappings.json
Build fails
# Test QMK directly
qmk compile -kb fingerpunch/sweeeeep -km smathev
# Check keyboard exists
qmk list-keymaps -kb fingerpunch/sweeeeep
💡 Advanced Usage
Use in other scripts
#!/usr/bin/env bash
source /path/to/qmk_flash_tools/lib/device_detection.sh
source /path/to/qmk_flash_tools/lib/side_mapping.sh
# Your custom logic here
mount_point=$(wait_for_rp2040)
device_id=$(get_device_identifier "$mount_point")
side=$(detect_side "$device_id")
echo "Detected $side side"
Custom keyboard configuration
# Set environment variables before running
export KEYBOARD="your/keyboard"
export KEYMAP="your_keymap"
./autoflash_modular.sh
Different mapping file
export SIDE_MAPPING_FILE="/tmp/my_test_mappings.json"
./autoflash_modular.sh
📋 Requirements
- bash - Shell interpreter
 - qmk - QMK CLI (
python3 -m pip install qmk) - jq - JSON processor (
sudo apt-get install jq) - findmnt - Usually included with util-linux
 - udevadm - Usually included with systemd
 
🔒 File Permissions
Make scripts executable:
chmod +x autoflash_modular.sh
chmod +x test/*.sh
chmod +x lib/*.sh
📝 How Device Mapping Works
The script intelligently handles three states:
🟢 Empty Mapping (First Time)
- No devices mapped yet
 - Asks: "Which side will you flash first?"
 - Script learns both sides as you flash them
 - First device = saved as what you specify (left/right)
 - Second device = saved as the other side
 - Result: Complete mapping of both sides
 
🟡 Partial Mapping (One Side Known)
- One device mapped, one unknown
 - Auto-detects: No asking needed!
 - If you plug in the known device → "Detected: left side"
 - If you plug in unknown device → "Detected: right side (inferred)"
 - Result: Completes mapping automatically
 
🔴 Complete Mapping (Both Sides Known)
- Both devices are mapped
 - Auto-detects: Fully automatic!
 - Plug in any side → "Detected: left side" or "Detected: right side"
 - Only the two known devices are allowed
 - Unknown device → Rejected immediately (safety feature)
 - Result: Fast, automatic flashing with full protection
 
Why This Matters
- First run: Asks which side (one-time setup) ✅
 - Normal use: Fully automatic - just plug and flash! ✅
 - Protection: Unknown devices rejected - can't flash wrong keyboard ✅
 - Smart: Knows when to ask vs. when to auto-detect 🧠
 
📝 Additional Notes
- Input timing: You're asked which side BEFORE entering bootloader (so you can still type!)
 - EEPROM wipe: Liatris overwrites EEPROM on flash, so we use HOST USB info
 - Board-ID: INFO_UF2.TXT is NOT unique per device, don't rely on it
 - USB serial: Burned into RP2040 chip, persists even when EEPROM wiped
 
🆘 Support
Issues? Check:
- Run test scripts to isolate the problem
 - Check device detection with 
print_device_info() - Verify mappings with 
list_all_mappings() - Test QMK commands directly: 
qmk compile -kb ... -km ... 
📄 License
Same as your QMK userspace configuration.