Same Board, Different Trackball
I'm building open firmware for the LilyGo T-Deck, a nifty little device with a keyboard, trackball, LoRa radio, and color screen. It runs on an ESP32-S3. The kind of gadget that makes you want to write firmware for it.
Here's the thing: some T-Deck units can't scroll down.
The trackball on some batches uses plain GPIO pins. Up, down, left, right, press. Read the pins, get the direction. Simple. But other batches, apparently including some newer ones, ship with an I2C-based trackball sensor instead. Different hardware, same product name, same box, same listing. No version number, no SKU difference, no warning.
You flash the same firmware on both and one of them works perfectly. The other? Scrolling down just doesn't work. The GPIO you're polling for "down" isn't connected to anything anymore. The actual input is coming through an I2C address you never thought to read.
This is the kind of problem closed firmware handles badly. When you ship one binary for one hardware revision, you're fine. When the hardware silently changes under you, you get mystery bugs that only some users can reproduce. "Works on my device" becomes a lottery.
Open firmware can do something about this. You can probe the I2C bus at boot, detect which trackball variant is present, and load the right driver. You can log what you found so users know which hardware they have. You can ship one firmware that adapts instead of two firmwares that each break on the wrong device.
But here's the trap: you don't just copy someone else's solution and call it done. The existing firmware for this device, MeshOS, handles both variants with a string-driven conditional that maps raw bytes to directions. It works, sort of, but it's not something you'd want to build on. The variable names are gone. The logic is buried in decompiled blobs. The comments are whatever the decompiler guessed.
I looked at it. I took notes. And then I wrote my own trackball driver from scratch, because "it works in the other firmware" is not the same as "it's built right."
The OpenMeshOS trackball driver will do runtime detection. GPIO first. If the down pin never fires, we try I2C. If I2C responds at the expected address, we switch to I2C mode on the fly. No config file, no user intervention, no "which revision did you buy?" The device figures itself out.
That's the whole point of open firmware: not to replicate what exists, but to do it better. To handle the edge cases the manufacturer didn't document. To make "same board, different trackball" someone else's problem, not yours.
If you're building firmware and you find a hardware variant your code doesn't handle, don't just patch the broken path. Build the detection logic. Make it automatic. Document what you found. The next person who hits that bug will thank you.
← All posts