It’s been a little while, but I have been making progress! If you missed parts 1, 2, 3, or 4, you might also find those interesting!
First - I got DMA working with my ST7798 screen. It’s much bigger than the OLED I was using. Second, I have full screen buffering working. I’m likely going to make this optional - so games & screens can directly decide when/where to clear the screen. I’m rewriting much of the UIs to allow things like colors be more configurable at a system level. The images in this post, are the “Hacker” theme.

PCB Progress
Since I solved my display problem, this gives me much more inside real-estate proportional to the screen. And - the pins for the display no longer get in the way of the micro-controllers. I’m laying out the main motherboard like the following:
On the front side - reverse mount headers so screen can just be pressed in. On the reverse - PI Pico 2 W is soldered directly onto the board. Same goes for the VS1053 board.
I think I’m going to make the ‘UI Buttons’ board as I’m calling it - be entirely separate. It’ll get a block of pins. Enough for an I2C bus, and also some raw pins for interrupts (or raw buttons) if I need.
I’m making good progress on this - I think I’m likely to order a duplicate electronics set (really, just a VS1053, 2nd screen, and power supply/battery), a small test run of PCBs. Then try and assemble a prototype! The wiring on the breadboard is kind of flakey especially with the high frequency transmission of pixel / music data over SPI.
Music Library
I have created a rust program to index my files and copy them to the SD card. It writes them in a special, numbered directory so by knowing a song’s ID, you can play it. I might try and keep the directory structure intact and add a lookup table to alow me to find the correct path, but I’m not sure if I want another layer of indirection around the files. The one nice thing, is that would allow a total library update without touching the music, as we’d just be pointing to the latest files.

My music library is structured like a flat file on the SD card. I can read and seek this using embedded_sdmmc. The structure (currently), is the following:
- Metadata:
- MAGIC: 4 bytes,
str- file type name. CurrentlyMLIB - VERSION: 2 bytes,
u16- version string for backwards compat usage - GENERATED_TIMESTAMP,
u64- unix timestamp in seconds. - Tables:
- Artists:
- ARTISTS_COUNT -
u16 - ARTISTS_TABLE_OFFSET -
u32- how far from start of file do we need to seek to get to the artists table? - ARTISTS_TABLE_ENTRY_SIZE -
u16- size in bytes of an entry in the artists table
- ARTISTS_COUNT -
- Albums:
- ALBUM_COUNT -
u16 - ALBUMS_TABLE_OFFSET -
u32 - ALBUMS_TABLE_ENTRY_SIZE -
u16
- ALBUM_COUNT -
- Songs
- SONG_COUNT -
u16 - SONG_TABLE_OFFSET -
u32 - SONG_TABLE_ENTRY_SIZE -
u32
- SONG_COUNT -
- Artists:
- STRING_POOL_OFFSET -
u32- stores strings data u32- RESERVED
- MAGIC: 4 bytes,
- Tables:
- ARTIST TABLE (ARTIST_COUNT entries)
- ARTIST_NAME_OFFSET -
u32- offset into string pool - ALBUM_COUNT -
u16 - ALBUMS_LIST_POOL_OFFSET -
u32- offset into lists pool, contains list of album indices for this artist
- ARTIST_NAME_OFFSET -
- ALBUM TABLE (ALBUM_COUNT entries)
- ALBUM_TITLE_OFFSET -
u32- offset into string pool - ARTIST_INDEX -
u16- index into artist table - SONG_COUNT -
u16 - SONGS_LIST_POOL_OFFSET -
u32- offset into lists pool, contains list of song indices for this album - ARTWORK_ID -
u32- offset into artwork pool, or 0 if no artwork
- ALBUM_TITLE_OFFSET -
- SONG TABLE (SONG_COUNT entries)
- SONG_FILE_ID -
u16- file path is stored as music/[id].ext - SONG_FILE_TYPE -
u8- enum: 0=mp3, 1=flac, 2=m4a, 3=wav - SONG_DURATION_MS -
u32 - SONG_TITLE_OFFSET -
u32- offset into string pool - ARTIST_INDEX -
u16- index into artist table - ALBUM_INDEX -
u16- index into album table
- SONG_FILE_ID -
- STRING POOL
- A big blob of null-terminated strings, indexed by offset
- SIZE -
u16 - STRING_DATA - SIZE bytes
- Null terminator - 1 byte
- ARTIST TABLE (ARTIST_COUNT entries)
- ARTWORK POOL (separate file)
- A big flat file containing of raw RGB565 pixel data, indexed by ID
- Items:
- SIZE -
u32 - IMAGE_DATA - SIZE bytes - NOTE - all should be the same, to permit random seeking to index
ibased on first SIZE. We can likely remove the redundant size field, I think.
- SIZE -

Sync Program
I’m writing a sync program that scans a directory on your computer, and creates library & artwork databases, and then writes them along with the files to your SD card.
Games
Since I have a nice screen now and fast drawing, I’m going to build several games for it. In no particular order:
- Snake
- Minesweeper
- Block-stacking game (tetris-esque)
- Shoot-em-up arcade game (think galaga, phoenix, others)
- Breakout style block breaker
Initially, i’m going to bake these in the firmware, until i determine a good API to expose. Then, I think I’d like to be able to expose a basic API and load programs into memory of SD card.
Simplify!
I originally planned to have much more stuff in this box.
For now, I’m eschewing most of that, to simplify the build process for the first version. I may decide to expose a pogo-pin interface (think 3.3v, SDA, SCL, GND), for external accessories like FM Radio, GPS, etc. Maybe things like that can be external accessories.