modified for VS1033

Dependents:   11U68_MP3Player with TFTLCD 11U68_MP3Player-with-TFTLCD Mp3_1

Fork of VS1033 by en 129

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VS1053.cpp Source File

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 dcsPin, PinName dreqPin,
00013                PinName rstPin, uint32_t spiFrequency)
00014 :
00015     spi(mosiPin, misoPin, sckPin),
00016     cs(csPin),
00017     dcs(dcsPin),
00018     dreq(dreqPin),
00019     rst(rstPin)
00020 {
00021     useSpiFreq = spiFrequency;
00022 
00023     // Initialize outputs
00024     cs = 1;
00025     dcs = 1;
00026     rst = 1;
00027 }
00028 
00029 /** Destructor of class VS1053. */
00030 VS1053::~VS1053() {
00031 }
00032 
00033 //SCI enable
00034 void VS1053::sci_en(void)
00035 {
00036     dcs = 1;
00037     cs = 0;
00038 }
00039 
00040 //SCI disable
00041 void VS1053::sci_dis(void)
00042 {
00043     dcs = 1;
00044     cs = 1;
00045 }
00046 
00047 //SDI enable
00048 void VS1053::sdi_en(void)
00049 {
00050     cs = 1;
00051     dcs = 0;
00052 }
00053 
00054 //SDI disable
00055 void VS1053::sdi_dis(void)
00056 {
00057     cs = 1;
00058     dcs = 1;
00059 }
00060 
00061 /** Make a hardware reset by hitting VS1053's RESET pin. */
00062 void VS1053::hardwareReset() {
00063     rst = 0;
00064     wait(0.1);
00065     rst = 1;
00066     wait(0.1);
00067 }
00068 
00069 //Serial Command Interface(SCI) init
00070 void VS1053::sci_init()
00071 {
00072     spi.format(8, 0);
00073     spi.frequency(1000000);
00074 
00075     cs = 0;
00076     for(int i=0; i<4; i++)
00077     {
00078         spi.write(0xFF);                        //clock the chip a bit
00079     }
00080     cs = 1;
00081     dcs = 1;
00082     wait_us(5);
00083     writeReg(SCI_MODE,(SM_SDINEW));
00084     writeReg(SCI_CLOCKF, 0x9800);
00085 }
00086 
00087 //Serial Data Interface(SDI) init
00088 void VS1053::sdi_init()
00089 {
00090     spi.format(8, 0);
00091     spi.frequency(useSpiFreq);
00092 
00093     writeReg(SCI_CLOCKF, 0xc000);  // SC_MULT=6 (4.0x)
00094     wait(0.01);
00095 
00096     cs = 1;
00097     dcs = 1;
00098 }
00099 
00100 void VS1053::VolControl(uint16_t vol)
00101 {
00102     writeReg(SCI_VOL,vol);
00103 }
00104 
00105 
00106 /** SDI Send a data byte to VS1053. */
00107 void VS1053::sendDataByte(uint8_t data) {
00108     sdi_en();
00109 
00110     while (!dreq);
00111     spi.write(data);
00112 
00113     sdi_dis();
00114 }
00115 
00116 bool VS1053::checkDREQ()
00117 {
00118     bool dreq_return = 0;
00119     dreq_return = dreq;
00120     return dreq_return;
00121 }
00122 
00123 /** SDI Send a data block specified as a pointer to VS1053.
00124  *  @return Data length successfully sent.
00125  */
00126 size_t VS1053::sendDataBlock(uint8_t* data, size_t length) {
00127     size_t n, sizeSent = 0;
00128     
00129     if (!data || !length) return 0;
00130     sdi_en();
00131     while (length) {
00132         n = length < 32 ? length : 32;
00133         for (uint32_t i = 0; i < n; i++)
00134         {
00135             while (!dreq);
00136             spi.write(*data++);
00137             sizeSent++; length--;
00138         }
00139     }
00140     sdi_dis();
00141     return sizeSent;
00142 }
00143 
00144 /** Attempt a termination of playing.
00145  *  Please call this repeatedly during data stream tramsission until it successes.
00146  *  @return Zero at failure, non-zero at success.
00147  */
00148 bool VS1053::stop() {
00149     uint16_t   n, length;
00150        
00151     // Send 0 2052 byte
00152     length = 256;
00153     sdi_en();
00154     while (length) {
00155         n = length < 32 ? length : 32;
00156         for (uint32_t i = 0; i < n; i++) {
00157             while (!dreq);
00158             spi.write(0x00);
00159             length--;
00160         }
00161     }
00162     sdi_dis();
00163 
00164     writeReg(SCI_MODE,( (SM_SDINEW)|(SM_RESET) ) );
00165     writeReg(SCI_CLOCKF, 0x9800);
00166 
00167     // Check if both HDAT0 and HDAT1 are cleared
00168     return readReg(SCI_HDAT0) == 0x0000 && readReg(SCI_HDAT1) == 0x0000;
00169 }
00170 
00171 /** Write to an SCI (Serial Control Interface) register entry. */
00172 void VS1053::writeReg(uint8_t addr, uint16_t word) {
00173     // If addr is out-of-range, do nothing
00174     if (addr > 0x0f) {
00175         return;
00176     }
00177     sci_en();
00178     while (!dreq);
00179     spi.write(0x02);         // Send a "Write SCI" instruction (02h),
00180     spi.write(addr);         // target address,
00181     spi.write(word >> 8);    // high byte,
00182     spi.write(word & 0xff);  // then low byte
00183     sci_dis();
00184 }
00185 
00186 /** Read an SCI (Serial Control Interface) register entry.
00187  *  @return Register value or 0000h when invalid address was specified.
00188  */
00189 uint16_t VS1053::readReg(uint8_t addr) {
00190     uint16_t word;
00191     
00192     // If addr is out-of-range, return 0000h
00193     if (addr > 0x0f) {
00194         return 0x0000;
00195     }
00196     sci_en();
00197     while (!dreq);
00198     spi.write(0x03);              // Send a "Read SCI" instruction (03h)
00199     spi.write(addr);              // and target address
00200     word = spi.write(0xff) << 8;  // Receive high byte with dummy data FFh
00201     word |= spi.write(0xff);      // Receive low byte
00202     sci_dis();
00203     return word;
00204 }
00205 
00206 void VS1053::sine_test_activate(unsigned char wave)
00207 {
00208     hardwareReset();
00209     spi.format(8, 0);
00210     spi.frequency(1000000);
00211     writeReg(SCI_MODE,(SM_SDINEW+SM_TESTS));
00212     sdi_en();
00213 
00214     while(dreq == 0)
00215     {
00216     }                          //wait unitl data request is high
00217     spi.write(0x53);                        //SDI write
00218     spi.write(0xEF);                        //SDI write
00219     spi.write(0x6E);                        //SDI write
00220     spi.write(wave);                        //SDI write
00221     spi.write(0x00);                        //filler byte
00222     spi.write(0x00);                        //filler byte
00223     spi.write(0x00);                        //filler byte
00224     spi.write(0x00);                        //filler byte
00225  
00226     sdi_dis();
00227 }
00228 void VS1053::sine_test_deactivate(void)
00229 {
00230     sdi_en();
00231 
00232     while(dreq == 0)
00233     {
00234     }
00235     spi.write(0x45);                        //SDI write
00236     spi.write(0x78);                        //SDI write
00237     spi.write(0x69);                        //SDI write
00238     spi.write(0x74);                        //SDI write
00239     spi.write(0x00);                        //filler byte
00240     spi.write(0x00);                        //filler byte
00241     spi.write(0x00);                        //filler byte
00242     spi.write(0x00);                        //filler byte
00243     
00244     sdi_dis();
00245 }