mohan-bee/mini-mp3-player
Portable, battery-powered MP3 player hardware with USB charging, microSD storage, an MCU, VS10xx audio decoder, headphone output, status controls, and regulated power rails.
- Version
- 1.2.0
- License
- unset
- Stars
- 0
firmware/README.md
# Prototype playback firmware 0.1.0
Target: this project's Rev B CH32V203C8T6, 64 KB flash / 20 KB RAM, 8 MHz crystal. Compiled and host-tested; **not yet run on physical hardware**. MP3 decoding takes place in the VS1003. The MCU reads FAT files and sends compressed bytes to it.
## Use
Format a microSD card as FAT16 or FAT32, not exFAT. Put up to 128 MP3 files in its root, using short names such as `0001.MP3`, `0002.MP3`. No folders, playlists, long-name display, resume memory, USB storage or firmware update over USB are implemented. Power off before inserting/removing the card. SD v1/v2 SDSC/SDHC initialization is implemented; actual card compatibility and sustained 320 kbps playback require testing.
Playback begins with the first alphabetically sorted track. PLAY toggles pause. PREV/NEXT wrap through tracks. VOL toggles volume mode; PREV/NEXT then change both channels by 2 dB. Power-up volume is −32 dB, adjustable −60 to −8 dB. Green LED: steady = playing; brief flash every two seconds = paused; regular flashing = volume mode. Red LED is hardware charging status.
Numbered green error flashes repeat with a long gap: 2 = card/filesystem/no tracks; 3 = decoder; 4 = track/read error; 5 = low battery; 6 = ADC failure. PLAY retries initialization. A fast continuous blink with a clock error on UART means the expected 72 MHz clock was not obtained.
Battery voltage is logged every second. Three readings below nominal 3.55 V stop playback. **This does not disconnect the battery:** switch OFF and charge. The protected battery remains mandatory. Calibrate the nominal 1.2 V ADC reference against a meter before relying on the threshold. USB-only operation is supported by the circuit; battery-node readings while no cell is fitted need bench characterization.
## Flash
1. Inspect the board and check its rails using `PROTOTYPE.md`. Keep headphones disconnected during initial bring-up.
2. Use WCH-Link in **RISC-V mode**, configured for CH32V203C8T6 in WCH's programming utility. Connect TP1 GND, TP3 PA13/SWDIO, TP4 PA14/SWCLK; TP5 NRST is available. TP2 is the powered board's 3.3 V reference. Do not connect a programmer power output to TP2 while independently powering the board; follow the particular programmer's reference/power wiring.
3. Load `build/mini-mp3.hex`, program and run the programmer's verify operation. HEX carries its addresses; the accompanying BIN is linked at flash alias 0x00000000. Use the device-aware WCH flash loader, not an arbitrary raw memory write.
4. Reset/power-cycle. Use a **3.3 V** UART adapter: adapter RX to TP6 (PA9 TX), common ground TP1. 115200 baud, 8N1. Expect firmware version, clock 72000000, track count/name, then battery readings. TP7 PA10 RX is exposed but no command parser is implemented.
USB-C on this board is charging/power only. It cannot program the MCU or copy songs.
## Rebuild and tests
Install xPack RISC-V GCC 15.2.0-1 (or a compatible `riscv-none-elf-` compiler), Make, Python 3, and a host C compiler. From this directory:
```sh
make PREFIX=/path/to/toolchain/bin/riscv-none-elf-
python3 tests/run.py
```
Outputs: ELF with symbols, Intel HEX, raw BIN and linker map in `build/`. No RTOS, dynamic allocation or application interrupts are used. The WCH startup and peripheral library are included. The MCU runs at 72 MHz to reduce load. SPI1 starts at 281.25 kHz and changes to 9 MHz; SPI2 starts at 1.125 MHz and changes to 4.5 MHz after the VS1003 3× clock configuration. DREQ limits data bursts to 32 bytes. SCI is serialized with SDI. End-of-file supplies 2048 zero bytes before advancing.
Host tests exercise real FatFs against fragmented FAT16/FAT32 images and injected disk failures, the SD SPI protocol with emulated responses, decoder transactions/timeouts, and button debounce/rollover. These do **not** emulate WCH registers, electrical timing, analog sound, card latency, power or mechanics. Pause stops feeding and mutes; buffered decoder audio can advance briefly. Track changes use reset and may produce pops until analog behavior is measured. See `PROVENANCE.md` for third-party notices.