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/src/decoder.c
#include "board.h"
#include "decoder.h"
static bool wait_ready(void) {
uint32_t start=millis();
while (!vs_ready()) if ((uint32_t)(millis()-start)>500) return false;
return true;
}
static bool reg_write(uint8_t reg,uint16_t value) {
uint8_t rx;
if (!wait_ready()) return false;
vs_select(false,true);
bool ok=vs_byte(2,&rx) && vs_byte(reg,&rx) && vs_byte(value>>8,&rx) && vs_byte(value&255,&rx);
vs_select(false,false);
// DREQ may drop after the final SCI clock; allow the specified settling time.
delay_ms(1);
return ok && wait_ready();
}
static bool reg_read(uint8_t reg,uint16_t *value) {
uint8_t rx,hi=0,lo=0;
if (!wait_ready()) return false;
vs_select(false,true);
bool ok=vs_byte(3,&rx) && vs_byte(reg,&rx) && vs_byte(0xff,&hi) && vs_byte(0xff,&lo);
vs_select(false,false); delay_ms(1);
*value=((uint16_t)hi<<8)|lo;
return ok && wait_ready();
}
bool decoder_volume(uint8_t attenuation) {
return reg_write(0x0b,((uint16_t)attenuation<<8)|attenuation);
}
void decoder_off(void) {
vs_select(false,false); vs_select(true,false); vs_reset(true);
}
bool decoder_init(uint8_t attenuation) {
decoder_off(); vs_speed(false); delay_ms(5); vs_reset(false); delay_ms(5);
uint16_t status;
if (!reg_read(1,&status) || ((status>>4)&15)!=3) return false;
// Native separate SCI/SDI selects. 3x clock + up to 1x automatic addition.
if (!reg_write(0,0x0800) || !reg_write(3,0x9000) || !reg_write(2,0)) return false;
vs_speed(true);
return decoder_volume(attenuation);
}
bool decoder_send(const uint8_t *bytes,unsigned count) {
if (count>32 || !vs_ready()) return false;
uint8_t rx;
vs_select(true,true);
for (unsigned i=0;i<count;i++) {
if (!vs_byte(bytes[i],&rx)) { vs_select(true,false); return false; }
}
vs_select(true,false); return true;
}