Reverse Engineering Techniques
Scott and Liz tag teamed the reverse engineering for this project. This page goes over some tips and tricks that they used to get CircuitPython running on the Yoto Mini and Yoto Player.
Chip Markings
After getting the device open, the first step is to try and read the chip markings on all of the components. When you get the marking, you'll want to search for the marking followed by the word "datasheet" or "component". By doing this, you should get hits for what the name of the device actually is.
This process worked for almost every peripheral on the Yoto Players except for the speaker amplifier. That involved looking at the 3rd party licenses on the Yoto website and noticing the aw881xx mentioned in the list. Searching for that component name lead to seeing results for the Awinic company. Finally, Liz searched Awinic components on LCSC and found the matching amplifier IC.
Logic Analyzer and Multimeter
Now that the chips were identified on the board, the next step was to figure out which pins on the ESP32 module do what.
Liz used a multimeter to ring out the board. You put your multimeter in continuity mode and check for continuity between pins. For example, she could probe the SCL or SDA pin on an IC and see what pin that corresponded with on the ESP32 to figure out the I2C pins.
Scott set up the PCB on his PCBite and used the probes to capture a few signals at a time with a Saleae. This gave an idea which ones were I2C and SPI. The eMMC pins were one of two options that the ESP32 supported.
The two of us tag teamed our different approaches to put together a cohesive pin mapping for the Yoto Players. We both kept notes documents to share with each other as we worked.
Scott started by looking at the firmware dump using ImHex. It's his preferred hex viewer of choice, but any one will do. He tried and failed to find the display's initialization sequence. It wasn't a straight byte array. He did manage to find the display chip number though! Some web searching had led him to GC9 ICs and a search through the hex found the full part number.
Scott turned to Ghidra to try and find the display initialization sequence. It can section out parts of the hex into functions and then you can change the names of suspected functions.
After searching for a few different values in the logic capture, Scott found the init function. Below, the write_display_command was a rename to make the pattern clearer. The 0xFE then 0xEF is a common start to GC init sequences.
While searching through the firmware, Scott noticed mention of JSON files, including board-specific ones. Lo and behold, he found JSON files in the firmware that define pinouts and configuration for each hardware revision!
After reformatting the discovered JSON, it is very easy to see the exact pinouts of everything, including the functions of the IO expander pins! It also includes default settings for the IO expander. Anyone hacking the Yoto's should take a look at these files in their firmware. They were all we needed to set up the board module in CircuitPython.
To CircuitPython
While this was happening, Liz built a generic ESP32 CircuitPython install with all of the pins broken out. This made testing and initial interfacing really easy. She referenced the datasheets for the peripherals to write CircuitPython drivers for them and worked through them one by one. Eventually all of this work was combined into the helper library for the Yoto Players.
Scott worked on the core support in CircuitPython. He added native IO expander support, which had been a goal to add to CircuitPython, and built-in support for the display. He added two board definitions to the core; one for the Yoto Mini and one for the Yoto Player.
Page last edited February 05, 2026
Text editor powered by tinymce.