Firmware: making the keys type
Everything you soldered in Chapter 10 is, right now, an inert sculpture. The switches close circuits, the diodes point the right way, the controller sits in its socket, and none of it does anything, because nobody has told the controller what its job is. That is what firmware does: it is a small program that lives permanently on the controller and runs the moment power arrives over the USB cable.
The job it runs is simple to describe. Many times per second, the firmware scans the matrix: it powers each row in turn and checks each column to see which switches are closed (you met the matrix and its diodes in Chapter 1). When it finds a pressed key, it looks that position up in a table called the keymap ("row 2, column 3 means the letter D"), and reports the result to your computer over USB using a standard language called HID (Human Interface Device). HID is the same protocol every keyboard and mouse on earth speaks, which is why your hand-built board needs no drivers: the computer just sees "a keyboard."
So "flashing firmware," the step this chapter walks you through, means copying that program onto the controller. You will do it twice, once per half, and it takes about two minutes per half once you have the file. Getting the right file is most of the chapter.
The lay of the land: QMK, Vial, VIA, ZMK
Four names come up constantly in this hobby, and they overlap in confusing ways. Here is the honest map.
QMK (Quantum Mechanical Keyboard) is the standard firmware for wired custom keyboards. It is free, open source, and supports hundreds of boards, including ours: the Lily58 is a supported keyboard in the official QMK repository, so you never have to write firmware, only configure it. Everything else in this list is either built on QMK or defined by how it differs from QMK.
Vial is a fork of QMK (a modified copy that evolves alongside it) with one killer feature: once a Vial-enabled firmware is on your board, you can remap any key live, from a page in your web browser at vial.rocks, with no reflashing. Press the key on screen, pick its new meaning, done, and the change is saved on the keyboard itself. For a beginner this is the friendliest wired path by a wide margin, when a prebuilt Vial firmware exists for your specific controller. For the Lily58 with common RP2040 controllers, it usually does; check get.vial.today and your kit vendor's documentation.
VIA is the same idea as Vial (live remapping through a graphical tool) but a separate, older ecosystem with its own app at usevia.app. Some prebuilt firmware supports VIA, some supports Vial, some supports neither. They are not compatible with each other. If your vendor hands you a "VIA firmware," use the VIA app with it; the experience is very similar.
ZMK is a different firmware entirely, built for wireless keyboards. If you chose the nice!nano wireless route back in Chapter 2, ZMK is your world: you configure it by editing files in a GitHub repository, and GitHub's servers build the firmware for you automatically (a system called GitHub Actions), then you download the result. It works well, but it is a different book's worth of material, and Typeractive's documentation (see the references) teaches it better than a detour here could. This chapter assumes the wired build.
Don't be confused. QMK, VIA, and Vial are not three rival firmwares. QMK is the firmware. VIA and Vial are both "a way to remap a QMK-based firmware live from a graphical app," and each needs a firmware built with its support turned on. Think of QMK as the engine, and VIA or Vial as two different dashboards you can order the car with. ZMK is the genuinely separate thing: a whole different engine, for wireless boards only.
The beginner path: no toolchain, no tears
You can install QMK's full development environment on your computer, and one day you might want to. On day one, do not. There are two easier routes, and both produce a perfectly good firmware file.
Route 1: a prebuilt Vial firmware. If your kit vendor or the Vial project publishes a ready-made Lily58 Vial firmware for your controller, download it, flash it (next section), and you are done forever with flashing: all future remapping happens live at vial.rocks. This is the path we recommend when it exists. The catch is the words "for your controller": a firmware built for an ATmega32u4 Pro Micro will not run on an RP2040 board and vice versa, so match the file to what you actually socketed.
Route 2: QMK Configurator. This is QMK's official point-and-click firmware builder at config.qmk.fm. It runs in your browser, holds your hand, and compiles the firmware on QMK's servers so you install nothing. Here is the whole procedure:
- Open config.qmk.fm. In the Keyboard dropdown, type
lily58and select lily58/rev1. - If the site asks about the controller or offers a converter option, pick the one matching your board (for RP2040 drop-in boards like the Elite-Pi or Frood, QMK calls this a "converter" such as
elite_pi; the Configurator exposes it near the keyboard selection). - Click Load default keymap. The screen fills with a picture of the Lily58 with the standard layout on it.
- To change a key: click the key on the picture, then click its new assignment from the big palette of key codes below. Repeat as you like, or change nothing on your first pass.
- Give the keymap a name in the Keymap Name box (your own name works fine), then press Compile. A progress pot boils for a minute.
- Press the Firmware download button. You get one file: a .uf2 file for RP2040 boards or a .hex file for ATmega32u4 boards.
That file is your firmware. On to putting it on the board.
Flashing, route A: RP2040 boards (the easy one)
This is why Chapter 2 steered you toward an RP2040 controller. Every RP2040 board has a built-in bootloader, a tiny factory-installed program whose only job is to accept new firmware, and it presents itself as a plain USB drive. The whole flash is a drag and drop:
- Plug the half you are flashing into the computer by USB. Only that half; leave the TRRS cable disconnected while flashing.
- Put the board into bootloader mode: hold the BOOT button while plugging in (or while tapping reset), or double-tap the reset button quickly. Your kit's controller docs say which; most accept both.
- A drive named RPI-RP2 appears on your computer, exactly like a USB stick.
- Drag the .uf2 file onto that drive.
- The drive vanishes by itself after a second or two. That is success: the board copied the firmware and rebooted into it.
No software to install, no drivers, nothing to type. Repeat for the other half with the same file.
Flashing, route B: ATmega32u4 Pro Micro (the classic one)
The classic Pro Micro has an older bootloader called Caterina, and it does not show up as a drive. You need a small helper program: QMK Toolbox, free from the QMK project (search "QMK Toolbox" on GitHub; Windows and macOS builds are provided).
- Open QMK Toolbox and use Open to select your .hex firmware file.
- Plug in the half you are flashing, alone.
- Double-tap the reset button (or short the RST and GND pins with tweezers if your board has no button). The Caterina bootloader wakes up for about eight seconds, and Toolbox prints a yellow "device connected" line.
- Within that window, click Flash. Text scrolls, ending in a success message.
If you miss the eight-second window, nothing breaks; double-tap again and re-click. Repeat for the other half.
Don't be confused. Compiling and flashing are two different steps. Compiling turns your configuration (which keys do what) into a firmware file; the Configurator did that on QMK's servers. Flashing copies that file onto the controller. You compile once per keymap change; you flash once per half. And on Vial or VIA firmware, remapping later needs neither: the app changes the keymap in place.
Two halves, one keyboard: master, slave, and handedness
Both halves get the same firmware file. At runtime, the half with the USB cable becomes the master: it talks to the computer, and it asks the other half (the slave) over the TRRS cable which of its keys are pressed. Newer documentation sometimes says "central" and "peripheral" for the same roles.
The firmware also needs each half to know whether it is the left or the right half, because the matrix is mirrored. The Lily58's default firmware uses the simplest rule: the half with the USB cable plugged in is the left half. So the common default setup is: USB into the left half, TRRS cable across to the right, and everything just works. If you would rather plug USB into the right half, QMK supports storing handedness permanently in EEPROM, a small scrap of memory on the controller that survives power-off. QMK ships special one-time firmware and a documented procedure for this (search the QMK docs for "setting handedness"); flash the handedness setting once, then flash your real firmware, and from then on either half is happy to take the cable. It is a nice upgrade, not a day-one requirement.
One rule worth repeating from Chapter 11: never plug or unplug the TRRS cable while USB power is connected. The TRRS plug shorts adjacent contacts as it slides in, and doing that on a powered board can damage a controller. Unplug USB first, always.
The tweezer test: prove it types before the switches go in
This is the payoff moment, and it belongs in Chapter 11's pre-assembly test, before you close anything up. With firmware flashed on both halves, USB into the left half, TRRS between them:
- Open a keyboard tester in your browser. Any of the free online testers works (see the references); even a blank text document does the job, though a tester shows modifier and function keys too.
- Take your metal tweezers and touch both contacts of one hotswap socket at the same time, bridging them. You are doing exactly what a switch does: closing the circuit.
- A letter appears on screen. That single letter proves the socket, the diode, the matrix trace, the controller, the firmware, and the USB link, all at once.
- Walk every socket on both halves, watching a character appear for each. Keys on the thumb clusters and the outer columns produce modifiers and layer keys, which the tester lights up rather than typing.
Any socket that stays silent gets marked with a sticky note and handled by Chapter 13's dead-key procedure, which is far easier now than after the switches are in.
Keymaps and layers, gently
A keyboard with 58 keys replaces one with 104. The trick is layers: the keymap is not one table but a small stack of them, and holding a special key switches which table is live. It is the same idea as the Shift key, which you have used your whole life: hold it and every key means something else.
The Lily58's default keymap has three layers you will actually use:
- Base layer: letters, numbers across the top row, Enter, common punctuation. Where your fingers live.
- Lower (hold the left thumb's layer key): symbols and the function keys, F1 through F12.
- Raise (hold the right thumb's layer key): arrows, brackets, and the punctuation that did not fit.
Hold the thumb key, tap the key you want, release. After a week your thumbs do it without asking you. The default keymap is deliberately conservative and close to a normal keyboard; live on it for at least a week before changing anything, so you learn what actually annoys you rather than what you guessed would.
When you do want a change, it is the Configurator loop from earlier: load your keymap, click the key, click its new meaning, compile, download, flash both halves. Or, on Vial firmware, open vial.rocks and click; the board updates instantly. For readers who like seeing what happens underneath, a keymap in QMK's source is literally a grid of key names in a text file, one entry per physical key per layer. Nothing mystical.
For the curious: the full QMK toolchain
If you outgrow the Configurator (you will know, because you will want a feature its interface does not expose, like home-row modifiers or custom OLED code), the next step is installing QMK on your own machine. In brief, so you know its shape: you install Python, run python3 -m pip install qmk, then qmk setup, which downloads the whole QMK source tree and checks your system. From then on, compiling is one command:
$ qmk compile -kb lily58 -km default
Ψ Compiling keymap with gmake ...
...
* The firmware size is fine - 22528/28672 (6144 bytes free)
That output is illustrative, not from a real run; the exact lines vary with your setup and controller. Your own keymaps live in a folder you edit with any text editor, and the QMK documentation at docs.qmk.fm is genuinely good. There is no rush: the Configurator covers everything a first-year keyboard needs.
If you have OLEDs
If you soldered the optional SSD1306 screens back in Chapter 10, the default Lily58 firmware already drives them: the master half typically shows the current layer name and what you are typing, and the slave half shows the Lily58 logo. If a screen stays dark, check Chapter 13 before suspecting the screen itself. Customizing what the OLEDs display (animations, word counters, tiny pets that walk faster as you type) is a beloved rabbit hole that requires the full toolchain and a little C code; the QMK documentation's OLED driver page is the trailhead when you are ready.
Takeaways
- Firmware is the program on the controller that scans the switch matrix and speaks USB HID to your computer. Flashing means copying it on.
- QMK is the standard for wired boards and supports the Lily58 out of the box. Vial and VIA add live remapping on top of it. ZMK is for wireless builds only.
- Day-one path: a prebuilt Vial firmware if one exists for your controller, otherwise QMK Configurator at config.qmk.fm. No toolchain install needed.
- RP2040 flashing is drag and drop onto the RPI-RP2 drive. ATmega32u4 flashing uses QMK Toolbox and a .hex file, inside the eight-second bootloader window.
- Both halves get the same file. USB side is master; default handedness assumes USB into the left half. Never hot-plug the TRRS cable.
- The tweezer test proves every socket types before a single switch goes in. Do it.
- Layers are the Shift-key idea generalized. Live on the default keymap for a week before customizing.
👉 Something will not work on the first try. That is not pessimism, it is statistics, and it is fine: Chapter 13 turns every symptom into an ordered checklist.