esmp3/src/player.cpp

100 lines
2.6 KiB
C++

// Based on https://github.com/mpflaga/Arduino_Library-vs1053_for_SdFat/blob/master/src/vs1053_SdFat.cpp
#include "player.h"
#include "spi_master.h"
Player::Player(SDCard* c) {
pinMode(XRESET, OUTPUT);
digitalWrite(XRESET, HIGH);
pinMode(DREQ, INPUT);
_init();
}
void Player::_reset() {
digitalWrite(XRESET, LOW);
delay(50);
digitalWrite(XRESET, HIGH);
delay(50);
}
void Player::_init() {
SPI.setClockDivider(SPI_CLOCK_DIV16);
_reset();
uint16_t result;
for(uint8_t x=0; x<255; x++) {
result = _read_register(SCI_MODE, 0, x);
if (result != 0) Serial.printf("Try %3d: 0x%04X\n", x, result);
}
delay(10);
/*_read_register(SCI_MODE, SPI_CLOCK_DIV16); // First read fails for some unknown reason...
_read_register(SCI_MODE, SPI_CLOCK_DIV16);
_read_register(SCI_STATUS, SPI_CLOCK_DIV16);
_read_register(SCI_STATUS, SPI_CLOCK_DIV16);
_read_register(SCI_MODE, SPI_CLOCK_DIV16);
_read_register(SCI_MODE, SPI_CLOCK_DIV16);
uint16_t response = _read_register(SCI_MODE, SPI_CLOCK_DIV16);
if (response != 0x4800) {
Serial.printf("Initialization failed. SCI_MODE was: 0x%04X. Expected: 0x4800\n", response);
return;
}*/
/*_write_register(SCI_CLOCKF, 0x6000); // Set multiplier to 3x
delay(10);
response = _read_register(SCI_CLOCKF);
if (response != 0x6000) {
Serial.printf("Initialization failed. SCI_CLOCKF was: 0x%04X. Expected: 0x6000\n", response);
return;
}*/
//Serial.println(result, HEX);
}
inline void Player::_wait() {
delayMicroseconds(100);
//Serial.print("Waiting for DREQ...");
while(!digitalRead(DREQ));
//Serial.printf(" done (%d cycles).\n", i);
}
uint16_t Player::_read_register(uint8_t address, uint32_t spi_speed, uint16_t t) {
Serial.printf("Try %03d, querying register 0x%02X...", t, address);
//SPI.setClockDivider(spi_speed);
if (t & (1<<1)) _wait();
SPIMaster::enable(PIN_VS1053_XCS);
if (t & (1<<2)) _wait();
//_wait();
SPI.transfer(CMD_READ);
if (t & (1<<3)) _wait();
SPI.transfer(address);
if (t & (1<<4)) _wait();
uint8_t b1 = SPI.transfer(0xFF);
if (t & (1<<5)) _wait();
uint8_t b2 = SPI.transfer(0xFF);
if (t & (1<<6)) _wait();
uint16_t result = b1 << 8 | b2;
Serial.printf("Response: 0x%02X 0x%02X -> 0x%04X\n", b1, b2, result);
if (t & (1<<7)) delay(10);
//_wait();
//SPIMaster::disable();
return result;
}
void Player::_write_register(uint8_t address, uint16_t value, uint32_t spi_speed) {
Serial.printf("Writing to register 0x%02X...", address);
SPI.setClockDivider(spi_speed);
SPIMaster::enable(PIN_VS1053_XCS);
SPI.transfer(CMD_WRITE);
SPI.transfer(address);
SPI.transfer(value >> 8);
SPI.transfer(value & 0xFF);
_wait();
SPIMaster::disable();
Serial.println(" done.");
}