AUDIO LIB

Dependents:   HagridOS5

Fork of VS1053 by Vassilis Serasidis

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VS1053.cpp Source File

VS1053.cpp

00001 #include "VS1053.h"
00002 #include "mbed.h"
00003  
00004 // patch binary
00005 #include "VS1053b_patch.c"
00006 // spectrum analyzer binary
00007 #include "VS1053b_specana.c"
00008  
00009 //Serial pc(USBTX, USBRX);
00010  
00011 /* ==================================================================
00012  * Constructor
00013  * =================================================================*/
00014 VS1053::VS1053(
00015          PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
00016          PinName dreq, PinName dcs, PinName vol)
00017     :
00018      _spi(mosi, miso, sck), 
00019      _CS(cs), 
00020      _RST(rst), 
00021      _DREQ(dreq),
00022      _DCS(dcs), 
00023      _VOL(vol) {
00024         firstTime=-1;    
00025     }    
00026  
00027 /*===================================================================
00028  * Functions
00029  *==================================================================*/
00030  
00031 void VS1053::cs_low(void)
00032 {
00033     _CS = 0;                                
00034 }
00035 void VS1053::cs_high(void)
00036 {
00037     _CS = 1;                                
00038 }
00039 void VS1053::dcs_low(void)
00040 {
00041     _DCS = 0;
00042  
00043 }
00044 void VS1053::dcs_high(void)
00045 {
00046     _DCS = 1;
00047 }
00048 void VS1053::sci_en(void)                    //SCI enable
00049 {
00050     cs_high();
00051     dcs_high();
00052     cs_low();
00053 }
00054 void VS1053::sci_dis(void)                    //SCI disable
00055 {
00056     cs_high();
00057 }
00058 void VS1053::sdi_en(void)                    //SDI enable
00059 {
00060     dcs_high();
00061     cs_high();
00062     dcs_low();
00063 }
00064 void VS1053::sdi_dis(void)                    //SDI disable
00065 {
00066     dcs_high();
00067 }
00068 void VS1053::reset(void)                    //hardware reset
00069 {
00070 //    wait(0.01);
00071     wait_ms(10);
00072     _RST = 0;
00073 //    wait(0.01);
00074     wait_ms(5);
00075     _RST = 1;
00076 //    wait(0.10);
00077     wait_ms(10);
00078 }
00079 void VS1053::power_down(void)                //hardware and software reset
00080 {
00081     cs_low();
00082     reset();
00083 //    sci_write(0x00, SM_PDOWN);
00084     sci_write(0x00, 0x10); // tempo
00085     wait(0.01);
00086     reset();
00087 }
00088 void VS1053::sci_initialise(void)
00089 {
00090     _RST = 1;                                //no reset
00091     _spi.format(8,0);                        //spi 8bit interface, steady state low
00092  //   _spi.frequency(1000000);                //rising edge data record, freq. 1Mhz
00093     _spi.frequency(2000000);                //rising edge data record, freq. 2Mhz
00094  
00095     
00096     cs_low();
00097     for(int i=0; i<4; i++)
00098     {
00099     _spi.write(0xFF);                        //clock the chip a bit
00100     }
00101     cs_high();
00102     dcs_high();
00103     wait_us(5);
00104 }
00105 void VS1053::sdi_initialise(void)
00106 {
00107     _spi.format(8,0);
00108 //    _spi.frequency(7000000);                //set to 7MHz
00109 //    _spi.frequency(12000000);                //set to 12MHz to make fast transfer
00110     _spi.frequency(18000000);                //set to 18MHz to make fast transfer
00111 //NG does not work//    _spi.frequency(24000000);                //set to 24MHz to make fast transfer
00112     
00113     cs_high();
00114     dcs_high();
00115 }
00116 void VS1053::sci_write(unsigned char address, unsigned short int data)
00117 {
00118     sci_en();                                //enables SCI/disables SDI
00119     
00120     while(!_DREQ);                            //wait unitl data request is high
00121     _spi.write(0x02);                        //SCI write
00122     _spi.write(address);                    //register address
00123     _spi.write((data >> 8) & 0xFF);            //write out first half of data word
00124     _spi.write(data & 0xFF);                //write out second half of data word
00125     
00126     sci_dis();                                //enables SDI/disables SCI
00127     wait_us(5);
00128 }
00129 void VS1053::sdi_write(unsigned char datum)
00130 {
00131     sdi_en();
00132     
00133     while(!_DREQ);
00134     _spi.write(datum);
00135     
00136 //?    sci_dis();
00137       sdi_dis();
00138 }
00139 unsigned short int VS1053::sci_read(unsigned short int address)
00140 {
00141     cs_low();                                //enables SCI/disables SDI
00142     
00143     while(!_DREQ);                            //wait unitl data request is high
00144     _spi.write(0x03);                        //SCI write
00145     _spi.write(address);                    //register address
00146     unsigned short int received = _spi.write(0x00);    //write out dummy byte
00147     received <<= 8;
00148     received += _spi.write(0x00);            //write out dummy byte
00149     
00150     cs_high();                                //enables SDI/disables SCI
00151     
00152     return received;                        //return received word
00153 }
00154 void VS1053::sine_test_activate(unsigned char wave)
00155 {
00156     cs_high();                                //enables SDI/disables SCI
00157     
00158     while(!_DREQ);                            //wait unitl data request is high
00159     _spi.write(0x53);                        //SDI write
00160     _spi.write(0xEF);                        //SDI write
00161     _spi.write(0x6E);                        //SDI write
00162     _spi.write(wave);                        //SDI write
00163     _spi.write(0x00);                        //filler byte
00164     _spi.write(0x00);                        //filler byte
00165     _spi.write(0x00);                        //filler byte
00166     _spi.write(0x00);                        //filler byte
00167  
00168     cs_low();                                //enables SCI/disables SDI
00169 }
00170 void VS1053::sine_test_deactivate(void)
00171 {
00172     cs_high();
00173     
00174     while(!_DREQ);
00175     _spi.write(0x45);                        //SDI write
00176     _spi.write(0x78);                        //SDI write
00177     _spi.write(0x69);                        //SDI write
00178     _spi.write(0x74);                        //SDI write
00179     _spi.write(0x00);                        //filler byte
00180     _spi.write(0x00);                        //filler byte
00181     _spi.write(0x00);                        //filler byte
00182     _spi.write(0x00);                        //filler byte
00183 }
00184 void VS1053::volume(uint8_t left, uint8_t right)
00185 {
00186 
00187 
00188   uint16_t v;
00189   v = left;
00190   v <<= 8;
00191   v |= right;
00192 
00193     while(!_DREQ);
00194     
00195     sci_write(0x0B, v);
00196 }
00197  
00198 void VS1053::writeStream(unsigned char *array, int size)
00199 {
00200    for(int i=0; i<size; i++)
00201    {
00202        sdi_write(array[i]);
00203    }
00204    volume(50,50);
00205 }
00206  
00207 #if 0
00208 // this function does not work
00209 // because of function call overhead
00210 void VS1053::putcStream(unsigned char datum)
00211 {
00212     sdi_write(datum);
00213 }
00214 #endif
00215  
00216 unsigned short int VS1053::wram_read(unsigned short int address)
00217 {
00218     unsigned short int tmp1,tmp2;
00219     sci_write(SCI_WRAMADDR,address);
00220     tmp1=sci_read(SCI_WRAM);
00221     sci_write(SCI_WRAMADDR,address);
00222     tmp2=sci_read(SCI_WRAM);
00223     if (tmp1==tmp2) return tmp1;
00224     sci_write(SCI_WRAMADDR,address);
00225     tmp1=sci_read(SCI_WRAM);
00226     if (tmp1==tmp2) return tmp1;
00227     sci_write(SCI_WRAMADDR,address);    
00228     tmp1=sci_read(SCI_WRAM);
00229     if (tmp1==tmp2) return tmp1;
00230     return tmp1;    
00231 }
00232  
00233 void VS1053::wram_write(unsigned short int address, unsigned short int data)
00234 {
00235     sci_write(SCI_WRAMADDR,address);
00236     sci_write(SCI_WRAM,data);
00237     return;
00238 }
00239  
00240  
00241 void VS1053::terminateStream(void)
00242 {
00243 #if 1
00244     unsigned int endFillByte=wram_read(para_endFillByte);
00245 //    printf("endFillByte:%04X\r\n",endFillByte); // debug
00246     for(int n=0; n<2052; n++) sdi_write(0xFF&endFillByte);
00247     sci_write(SCI_MODE,(SM_SDINEW+SM_CANCEL));
00248     for(int n=0; n<2048; n++) sdi_write(0xFF&endFillByte);
00249     // don't reset if you don't want to lose the patch 
00250     //    sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); //  set mode reg.
00251     //    wait_ms(10); 
00252 #endif 
00253 }
00254  
00255 void VS1053::write_plugin(const unsigned short *plugin, unsigned int len)
00256 {
00257   unsigned int i;
00258   unsigned short addr, n, val;
00259  
00260   for(i=0; i<len;)
00261   {
00262     addr = plugin[i++];
00263     n    = plugin[i++];
00264     if(n & 0x8000U) //RLE run, replicate n samples
00265     {
00266       n  &= 0x7FFF;
00267       val = plugin[i++];
00268       while(n--) 
00269       {
00270         sci_write(addr,val);
00271       }
00272     }
00273     else //copy run, copy n sample
00274     {
00275       while(n--)
00276       {
00277         val = plugin[i++];
00278         sci_write(addr,val);
00279       }
00280     }
00281   }
00282  
00283   return;
00284 }
00285  
00286  
00287 void VS1053::initialize(void)
00288 {
00289     _RST = 1;
00290     cs_high();                           //chip disabled
00291     sci_initialise();                    //initialise MBED
00292     sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); //  set mode reg.
00293     wait_ms(10); 
00294 #if 1
00295        // debug
00296         unsigned int chipID_0=wram_read(para_chipID_0);
00297         if (firstTime) printf("chipID_0:%04X\r\n",chipID_0); // debug
00298         unsigned int chipID_1=wram_read(para_chipID_1);
00299         if (firstTime) printf("chipID_1:%04X\r\n",chipID_1); // debug      
00300         unsigned int struct_version=wram_read(para_version);
00301         if (firstTime) printf("structure version:%04X\r\n",struct_version); // debug      
00302  #endif
00303     //get chip version, set clock multiplier and load patch
00304     int i = (sci_read(SCI_STATUS)&0xF0)>>4;
00305     if(i == 4) 
00306     {
00307         if (firstTime) printf("Installed Chip is: VS1053\r\n");
00308         sci_write(SCI_CLOCKF, (SC_MULT_XTALIx50+SC_ADD_20x)); 
00309 #ifdef VS_PATCH
00310         // loading patch
00311         write_plugin(vs1053b_patch, sizeof(vs1053b_patch)/2);
00312         if (firstTime) {
00313             printf("VS1053b patch loaded.\r\n");
00314             printf("patch size:%d bytes\r\n",sizeof(vs1053b_patch));
00315         }
00316 #endif
00317 #ifdef VS_SPECANA
00318         // loading plugin(spectrum analyzer)
00319         write_plugin(vs1053b_specana, sizeof(vs1053b_specana)/2);
00320         if (firstTime) printf("VS1053b specana loaded.\r\n");
00321 #endif
00322     }
00323     else printf("??? Not Supported Chip???\r\n");
00324     sdi_initialise(); 
00325     firstTime=0; // disable message when init after 1st time
00326 }