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