1
Dependents: internet_radio_leo
Fork of VS1053 by
VS1053.cpp
00001 /** 00002 * ==================================================== Dec 21 2013, kayeks == 00003 * VS1053.cpp 00004 * =========================================================================== 00005 * Just a simple library for VLSI's mp3/midi codec chip 00006 * - Minimal and simple implementation (and dirty too) 00007 * 00008 * Modified on 05 September 2015 by Vassilis Serasidis. 00009 * - Added a patch for playing MP3 files on some "LC Technology" VS1053 boards. 00010 * 00011 * 00012 */ 00013 00014 #include "mbed.h" 00015 #include "VS1053.h" 00016 00017 /** Constructor of class VS1053. */ 00018 VS1053::VS1053(PinName mosiPin, PinName misoPin, PinName sckPin, 00019 PinName csPin, PinName bsyncPin, PinName dreqPin, 00020 PinName rstPin, uint32_t spiFrequency) 00021 : 00022 spi(mosiPin, misoPin, sckPin), 00023 cs(csPin), 00024 bsync(bsyncPin), 00025 dreq(dreqPin), 00026 rst(rstPin) 00027 { 00028 spi.format(8, 0); 00029 spi.frequency(spiFrequency); 00030 00031 // Initialize outputs 00032 cs = 1; 00033 bsync = 1; 00034 rst = 1; 00035 } 00036 00037 /** Destructor of class VS1053. */ 00038 VS1053::~VS1053() { 00039 } 00040 00041 /** Make a hardware reset by hitting VS1053's RESET pin. */ 00042 void VS1053::hardwareReset() { 00043 rst = 0; 00044 wait(.05); 00045 rst = 1; 00046 wait(.05); 00047 } 00048 00049 /** Patch for some LC Technology VS1053 board with "no sound" problem. 00050 * 5 September 2015 bby Vassilis Serasidis 00051 */ 00052 void VS1053::modeSwitch(void) 00053 { 00054 //GPIO_DDR 00055 writeReg(SCI_WRAMADDR, 0xc017); 00056 writeReg(SCI_WRAM, 0x0003); 00057 00058 wait(.05); 00059 writeReg(SCI_MODE, (1<<SM_SDINEW) | (1<<SM_RESET)); 00060 wait(.05); 00061 } 00062 00063 /** Send a data byte to VS1053. */ 00064 void VS1053::sendDataByte(char data) { 00065 while (!dreq); 00066 bsync = 0; 00067 spi.write(data); 00068 bsync = 1; 00069 } 00070 00071 /** Send a data block specified as a pointer to VS1053. 00072 * @return Data length successfully sent. 00073 */ 00074 size_t VS1053::sendDataBlock(char* data, size_t length) { 00075 size_t n, sizeSent = 0; 00076 00077 if (!data || !length) return 0; 00078 while (length) { 00079 n = length < 32 ? length : 32; 00080 while (!dreq); 00081 bsync = 0; 00082 for (uint32_t i = 0; i < n; i++) { 00083 spi.write(*data++); 00084 sizeSent++; length--; 00085 } 00086 bsync = 1; 00087 } 00088 return sizeSent; 00089 } 00090 00091 /** Change VS1053's PLL setting for speedup. */ 00092 void VS1053::clockUp() { 00093 // Set CLKI to 43.0-55.3 MHz 00094 writeReg(SCI_CLOCKF, 0x8800); // SC_MULT=4 (3.5x), SC_ADD=1 (+1.0x) 00095 wait(0.01); 00096 } 00097 00098 /** Send cancel request to VS1053. 00099 * @return Zero at failure, non-zero at success. 00100 */ 00101 bool VS1053::sendCancel() { 00102 uint16_t reg; 00103 00104 // Set SM_CANCEL bit 00105 reg = readReg(SCI_MODE); 00106 if (reg & 0x0008) { 00107 // Abort if SM_CANCEL is still set 00108 return false; 00109 } 00110 writeReg(SCI_MODE, reg | 0x0008); 00111 return true; 00112 } 00113 00114 /** Attempt a termination of playing. 00115 * Please call this repeatedly during data stream tramsission until it successes. 00116 * @return Zero at failure, non-zero at success. 00117 */ 00118 bool VS1053::stop() { 00119 uint16_t reg; 00120 uint8_t endFillByte; 00121 size_t n, length; 00122 00123 // If SM_CANCEL is still set, do nothing 00124 reg = readReg(SCI_MODE); 00125 if (reg & 0x0008) { 00126 return false; 00127 } 00128 00129 // Read endFillByte from XRAM <1E06h> 00130 writeReg(SCI_WRAMADDR, 0x1e06); 00131 reg = readReg(SCI_WRAM); 00132 00133 // Send lower 8 bits of endFillByte 2,052 times 00134 endFillByte = reg & 0xff; 00135 length = 2052; 00136 while (length) { 00137 n = length < 32 ? length : 32; 00138 while (!dreq); 00139 bsync = 0; 00140 for (uint32_t i = 0; i < n; i++) { 00141 spi.write(endFillByte); 00142 length--; 00143 } 00144 bsync = 1; 00145 } 00146 // Check if both HDAT0 and HDAT1 are cleared 00147 return readReg(SCI_HDAT0) == 0x0000 && readReg(SCI_HDAT1) == 0x0000; 00148 } 00149 00150 /** Write to an SCI (Serial Control Interface) register entry. */ 00151 void VS1053::writeReg(uint8_t addr, uint16_t word) { 00152 // If addr is out-of-range, do nothing 00153 if (addr > 0x0f) { 00154 return; 00155 } 00156 00157 while (!dreq); 00158 cs = 0; 00159 spi.write(0x02); // Send a "Write SCI" instruction (02h), 00160 spi.write(addr); // target address, 00161 spi.write(word >> 8); // high byte, 00162 spi.write(word & 0xff); // then low byte 00163 while (!dreq); 00164 cs = 1; 00165 } 00166 00167 /** Read an SCI (Serial Control Interface) register entry. 00168 * @return Register value or 0000h when invalid address was specified. 00169 */ 00170 uint16_t VS1053::readReg(uint8_t addr) { 00171 uint16_t word; 00172 00173 // If addr is out-of-range, return 0000h 00174 if (addr > 0x0f) { 00175 return 0x0000; 00176 } 00177 00178 while (!dreq); 00179 cs = 0; 00180 spi.write(0x03); // Send a "Read SCI" instruction (03h) 00181 spi.write(addr); // and target address 00182 word = spi.write(0xff) << 8; // Receive high byte with dummy data FFh 00183 word |= spi.write(0xff); // Receive low byte 00184 while (!dreq); 00185 cs = 1; 00186 return word; 00187 }
Generated on Sun Jul 17 2022 11:40:55 by
![doxygen](doxygen.png)