1. You would need to dig into the SCI_WRITE implementation and see why it's so slow. If it's using SPI, what SPI clock speed have you configured?
I haven't done oscilloscope analysis on the signal yet, but at least Adafruit's code for sciWrite() looks to match the requirement from VS1053b's datasheet. Adafruit's code is below (unmodified):
Code: Select all
void Adafruit_VS1053::sciWrite(uint8_t addr, uint16_t data) {
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);
#endif
digitalWrite(_cs, LOW);
spiwrite(VS1053_SCI_WRITE);
spiwrite(addr);
spiwrite(data >> 8);
spiwrite(data & 0xFF);
digitalWrite(_cs, HIGH);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.endTransaction();
#endif
}
Using arduino's micro() command, each spiwrite() call takes 35us, which is ~30KHz. Below is Adafruit's spiwrite() code unmodified. It uses Arduino's SPI.transfer() function. I've checked that useHardwareSPI is true.
Code: Select all
void Adafruit_VS1053::spiwrite(uint8_t *c, uint16_t num) {
// MSB first, clock low when inactive (CPOL 0), data valid on leading edge
// (CPHA 0) Make sure clock starts low
if (useHardwareSPI) {
//#if defined(ESP32) // optimized
// SPI.writeBytes(c, num);
// return;
//#endif
while (num--) {
SPI.transfer(c[0]);
c++;
}
} else {
while (num--) {
for (int8_t i = 7; i >= 0; i--) {
*clkportreg &= ~clkpin;
if (c[0] & (1 << i)) {
*mosiportreg |= mosipin;
} else {
*mosiportreg &= ~mosipin;
}
*clkportreg |= clkpin;
}
*clkportreg &= ~clkpin; // Make sure clock ends low
c++;
}
}
}
Adafruit's VS1053 library uses 8MHz for data and 250KHz for control on the SPI. Code below:
Code: Select all
#define VS1053_CONTROL_SPI_SETTING \
SPISettings(250000, MSBFIRST, SPI_MODE0) //!< VS1053 SPI control settings
#define VS1053_DATA_SPI_SETTING \
SPISettings(8000000, MSBFIRST, SPI_MODE0) //!< VS1053 SPI data settings
I've tried to play around with the SPIsettings(). it turns out that increasing the 250KHz to 1MHz reduces the loading time from 3.3s to 1.3s.
What is VS1053b's recommended SPIsetting? The Feather M0 microcontroller uses a 32MHz crystal.
Does you see any problem using SPI.transfer()? Would DMA help? I would rather stay with VS1053b (migrating to another chip would be the last resort).
Thank you,
Ray