openyoto - open sourced yoto player firmware
prelude
A kids’ toy sitting in a bedroom with a permanent internet connection bothered me.
Not in a tinfoil-hat way. The Yoto Player does not have a microphone, and it’s nice, kid friendly hardware. But it is, technically, remotely controllable: a device that takes orders from a server I don’t own, sitting in a kid’s bedroom.
And there’s no way to just look at what it’s doing. The firmware is a black box unless you open it. But with Pandora’s box opened, any code monkey armed with an LLM can pry into it. And so I did.
context
Under the shell, a Yoto Mini is an ESP32 plus a supporting cast: an NFC reader/writer, a speaker, two knobs, a small display, flash, and a battery. The cards are just NFC tags. Tap one, the player looks up a playlist, audio comes out.
On paper, a kids hardware project should take a weekend or two, no?
Audio, NFC, knobs, battery management. These all take time (and effort).
Audio. There’s no operating system to hide behind. Decoding MP3, AAC (ADTS) and M4A in real time, keeping the I2S stream fed, and doing it while the UI loop, the NFC polling and the display are all fighting over the same two cores. You get a chip, not a media player.
NFC. Reading a card is the easy half. Writing blank cards reliably (data, artwork, mappings the firmware can read back later) is where the days go. Tag types, timing, retries, cards that work fine until they don’t.
Battery management. Charge controller, fuel gauge, and a device that has to keep playing while both change underneath it. Get one state machine wrong and the player dies at naptime.
Button interactions. Debounce, short press, long press, hold while audio is streaming. Trivial on a desktop with an operating system. On two cores with a real-time audio pipeline, every one of them is another thing that must not block.
LCD screen driving. A small screen, no framebuffer handed to you, pixels pushed while everything else keeps running. Partial updates, no flicker, and no cycles to spare.
workflow
The whole thing (drivers, audio pipeline, display, the flashing loop, the documentation) was built on the omp harness.
Luckily in 2026, we were gifted the equivalent of 1,000,000 monkeys typing on a typewriter for software engineering. Eventually, Shakespeare was going to be written.
In practice, I describe what I want in high level English and the model gets the job done. I started out with deepseek-v4-flash, which got 80% of the way there but hit a wall on NFC card reading. Swapped over to gpt-5-6, and that didn’t really work either.
After two days of fiddling I tested it against an official Yoto card, and lo and behold: the cheap NFC cards I bought from Amazon were not compatible. Go figure.
being a meat proxy
The AI was extremely capable from the beginning and throughout the whole process. I did not read or write any code. My job: 10% describing what I wanted in high-level English, 90% pressing buttons and telling it what broke.
For a while I thought there was no shortcut around the buttons, because the player’s USB-C port is power-only and can’t flash anything. You open the shell, wire an external USB-UART adapter with 3.3 V logic to the internal pins, and drive the bootloader by hand.
Eventually I realized you could automate both: drop the board into bootloader without me, and test features by reading the serial output. That closed loop let it iterate much quicker, and let me leave it on autopilot completely.
what it does now
The Yoto Player runs openyoto, open source firmware, instead of the cloud firmware it shipped with. No Yoto account and no internet connection needed: audio and card mappings live on the SD card.
- Bring your own audio. Local MP3, AAC (ADTS) and M4A files off the SD card.
- Make your own cards. Pick tracks and artwork, write a compatible blank NFC card, tap it on the player.
- Works as a Bluetooth speaker. Audio in from your phone, not out to Bluetooth headphones.
- Admin page, served from the player. Scan the admin card, the player puts up its own hotspot, you open the page on your phone and upload files.
That last one is the part that makes it feel like a real product instead of a firmware dump. You scan a card and a web page shows up. No cable, no pesky app, no account signup, just to put files onto a device that YOU own.
fin…
On and off, this took about 10 days. Not 10 days of typing. 10 days of wiring, flashing, holding two buttons, and telling a model what to write next.
Pre-AI this would have been months. Not because the code is exotic, but because every one of those components (audio decode, NFC init, display driver, etc) is a rabbit hole you fall into one at a time. Having 100 subagents research them concurrently collapsed the time required significantly.
The doomer telling goes: you will own nothing and be happy. I’d rather be a techno optimist. A toy that used to be a client of someone else’s cloud now runs my firmware, on hardware I own, with no account in between. You will own everything, and you will be happy.
footnotes
- firmware docs: docs.openyoto.com
- models used:
gpt-5-6,deepseek-v4-flash - repository: github.com/tensorfish/open-yoto
- firmware: openyoto.com