mbeduino MP3 Sheild player MP3 player that runs on mebeduin with MP3 Shield. Regarding mbeduino, refer to: http://mbed.org/users/okini3939/notebook/mbeduino/ Regarding MP3 Shiled, refer to: http://www.sparkfun.com/commerce/product_info.php?products_id=9736

Dependencies:   mbed SDFileSystem

Committer:
xshige
Date:
Sat Oct 16 05:14:59 2010 +0000
Revision:
1:c47269f0e9e1
Parent:
0:67cb2f650c15
2010/10/16 version: (1) Patch loading is supported.  The patch is needed to make FLAC decoder work. (2)MP3,Ogg,MIDI,WMA,FLAC,AAC work correctly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xshige 0:67cb2f650c15 1 #include "VS1053.h"
xshige 0:67cb2f650c15 2 #include "mbed.h"
xshige 0:67cb2f650c15 3
xshige 1:c47269f0e9e1 4 // patch binary
xshige 1:c47269f0e9e1 5 #include "VS1053b_patch.c"
xshige 1:c47269f0e9e1 6 // spectrum analyzer binary
xshige 1:c47269f0e9e1 7 #include "VS1053b_specana.c"
xshige 0:67cb2f650c15 8
xshige 0:67cb2f650c15 9 Serial pc(USBTX, USBRX);
xshige 0:67cb2f650c15 10
xshige 0:67cb2f650c15 11 /* ==================================================================
xshige 0:67cb2f650c15 12 * Constructor
xshige 0:67cb2f650c15 13 * =================================================================*/
xshige 0:67cb2f650c15 14 VS1053::VS1053(
xshige 0:67cb2f650c15 15 PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
xshige 0:67cb2f650c15 16 PinName dreq, PinName dcs, PinName vol)
xshige 0:67cb2f650c15 17 :
xshige 0:67cb2f650c15 18 _spi(mosi, miso, sck),
xshige 0:67cb2f650c15 19 _CS(cs),
xshige 0:67cb2f650c15 20 _RST(rst),
xshige 0:67cb2f650c15 21 _DREQ(dreq),
xshige 0:67cb2f650c15 22 _DCS(dcs),
xshige 0:67cb2f650c15 23 _VOL(vol) {
xshige 1:c47269f0e9e1 24 firstTime=-1;
xshige 0:67cb2f650c15 25 }
xshige 0:67cb2f650c15 26
xshige 0:67cb2f650c15 27 /*===================================================================
xshige 0:67cb2f650c15 28 * Functions
xshige 0:67cb2f650c15 29 *==================================================================*/
xshige 0:67cb2f650c15 30
xshige 0:67cb2f650c15 31 void VS1053::cs_low(void)
xshige 0:67cb2f650c15 32 {
xshige 0:67cb2f650c15 33 _CS = 0;
xshige 0:67cb2f650c15 34 }
xshige 0:67cb2f650c15 35 void VS1053::cs_high(void)
xshige 0:67cb2f650c15 36 {
xshige 0:67cb2f650c15 37 _CS = 1;
xshige 0:67cb2f650c15 38 }
xshige 0:67cb2f650c15 39 void VS1053::dcs_low(void)
xshige 0:67cb2f650c15 40 {
xshige 0:67cb2f650c15 41 _DCS = 0;
xshige 1:c47269f0e9e1 42
xshige 0:67cb2f650c15 43 }
xshige 0:67cb2f650c15 44 void VS1053::dcs_high(void)
xshige 0:67cb2f650c15 45 {
xshige 0:67cb2f650c15 46 _DCS = 1;
xshige 0:67cb2f650c15 47 }
xshige 0:67cb2f650c15 48 void VS1053::sci_en(void) //SCI enable
xshige 0:67cb2f650c15 49 {
xshige 0:67cb2f650c15 50 cs_high();
xshige 0:67cb2f650c15 51 dcs_high();
xshige 0:67cb2f650c15 52 cs_low();
xshige 0:67cb2f650c15 53 }
xshige 0:67cb2f650c15 54 void VS1053::sci_dis(void) //SCI disable
xshige 0:67cb2f650c15 55 {
xshige 0:67cb2f650c15 56 cs_high();
xshige 0:67cb2f650c15 57 }
xshige 0:67cb2f650c15 58 void VS1053::sdi_en(void) //SDI enable
xshige 0:67cb2f650c15 59 {
xshige 0:67cb2f650c15 60 dcs_high();
xshige 0:67cb2f650c15 61 cs_high();
xshige 0:67cb2f650c15 62 dcs_low();
xshige 0:67cb2f650c15 63 }
xshige 0:67cb2f650c15 64 void VS1053::sdi_dis(void) //SDI disable
xshige 0:67cb2f650c15 65 {
xshige 0:67cb2f650c15 66 dcs_high();
xshige 0:67cb2f650c15 67 }
xshige 0:67cb2f650c15 68 void VS1053::reset(void) //hardware reset
xshige 0:67cb2f650c15 69 {
xshige 1:c47269f0e9e1 70 // wait(0.01);
xshige 1:c47269f0e9e1 71 wait_ms(10);
xshige 0:67cb2f650c15 72 _RST = 0;
xshige 1:c47269f0e9e1 73 // wait(0.01);
xshige 1:c47269f0e9e1 74 wait_ms(5);
xshige 0:67cb2f650c15 75 _RST = 1;
xshige 1:c47269f0e9e1 76 // wait(0.10);
xshige 1:c47269f0e9e1 77 wait_ms(10);
xshige 0:67cb2f650c15 78 }
xshige 0:67cb2f650c15 79 void VS1053::power_down(void) //hardware and software reset
xshige 0:67cb2f650c15 80 {
xshige 0:67cb2f650c15 81 cs_low();
xshige 0:67cb2f650c15 82 reset();
xshige 0:67cb2f650c15 83 // sci_write(0x00, SM_PDOWN);
xshige 0:67cb2f650c15 84 sci_write(0x00, 0x10); // tempo
xshige 0:67cb2f650c15 85 wait(0.01);
xshige 0:67cb2f650c15 86 reset();
xshige 0:67cb2f650c15 87 }
xshige 0:67cb2f650c15 88 void VS1053::sci_initialise(void)
xshige 0:67cb2f650c15 89 {
xshige 0:67cb2f650c15 90 _RST = 1; //no reset
xshige 0:67cb2f650c15 91 _spi.format(8,0); //spi 8bit interface, steady state low
xshige 1:c47269f0e9e1 92 // _spi.frequency(1000000); //rising edge data record, freq. 1Mhz
xshige 1:c47269f0e9e1 93 _spi.frequency(2000000); //rising edge data record, freq. 2Mhz
xshige 1:c47269f0e9e1 94
xshige 0:67cb2f650c15 95
xshige 0:67cb2f650c15 96 cs_low();
xshige 0:67cb2f650c15 97 for(int i=0; i<4; i++)
xshige 0:67cb2f650c15 98 {
xshige 0:67cb2f650c15 99 _spi.write(0xFF); //clock the chip a bit
xshige 0:67cb2f650c15 100 }
xshige 0:67cb2f650c15 101 cs_high();
xshige 0:67cb2f650c15 102 dcs_high();
xshige 0:67cb2f650c15 103 wait_us(5);
xshige 0:67cb2f650c15 104 }
xshige 0:67cb2f650c15 105 void VS1053::sdi_initialise(void)
xshige 0:67cb2f650c15 106 {
xshige 0:67cb2f650c15 107 _spi.format(8,0);
xshige 1:c47269f0e9e1 108 // _spi.frequency(7000000); //set to 7MHz
xshige 1:c47269f0e9e1 109 // _spi.frequency(12000000); //set to 12MHz to make fast transfer
xshige 1:c47269f0e9e1 110 _spi.frequency(18000000); //set to 18MHz to make fast transfer
xshige 1:c47269f0e9e1 111 //NG does not work// _spi.frequency(24000000); //set to 24MHz to make fast transfer
xshige 0:67cb2f650c15 112
xshige 0:67cb2f650c15 113 cs_high();
xshige 0:67cb2f650c15 114 dcs_high();
xshige 0:67cb2f650c15 115 }
xshige 0:67cb2f650c15 116 void VS1053::sci_write(unsigned char address, unsigned short int data)
xshige 0:67cb2f650c15 117 {
xshige 0:67cb2f650c15 118 sci_en(); //enables SCI/disables SDI
xshige 0:67cb2f650c15 119
xshige 0:67cb2f650c15 120 while(!_DREQ); //wait unitl data request is high
xshige 0:67cb2f650c15 121 _spi.write(0x02); //SCI write
xshige 0:67cb2f650c15 122 _spi.write(address); //register address
xshige 0:67cb2f650c15 123 _spi.write((data >> 8) & 0xFF); //write out first half of data word
xshige 0:67cb2f650c15 124 _spi.write(data & 0xFF); //write out second half of data word
xshige 0:67cb2f650c15 125
xshige 0:67cb2f650c15 126 sci_dis(); //enables SDI/disables SCI
xshige 0:67cb2f650c15 127 wait_us(5);
xshige 0:67cb2f650c15 128 }
xshige 0:67cb2f650c15 129 void VS1053::sdi_write(unsigned char datum)
xshige 0:67cb2f650c15 130 {
xshige 0:67cb2f650c15 131 sdi_en();
xshige 0:67cb2f650c15 132
xshige 0:67cb2f650c15 133 while(!_DREQ);
xshige 0:67cb2f650c15 134 _spi.write(datum);
xshige 0:67cb2f650c15 135
xshige 1:c47269f0e9e1 136 //? sci_dis();
xshige 1:c47269f0e9e1 137 sdi_dis();
xshige 0:67cb2f650c15 138 }
xshige 1:c47269f0e9e1 139 unsigned short int VS1053::sci_read(unsigned short int address)
xshige 0:67cb2f650c15 140 {
xshige 0:67cb2f650c15 141 cs_low(); //enables SCI/disables SDI
xshige 0:67cb2f650c15 142
xshige 0:67cb2f650c15 143 while(!_DREQ); //wait unitl data request is high
xshige 0:67cb2f650c15 144 _spi.write(0x03); //SCI write
xshige 0:67cb2f650c15 145 _spi.write(address); //register address
xshige 0:67cb2f650c15 146 unsigned short int received = _spi.write(0x00); //write out dummy byte
xshige 0:67cb2f650c15 147 received <<= 8;
xshige 0:67cb2f650c15 148 received += _spi.write(0x00); //write out dummy byte
xshige 0:67cb2f650c15 149
xshige 0:67cb2f650c15 150 cs_high(); //enables SDI/disables SCI
xshige 0:67cb2f650c15 151
xshige 0:67cb2f650c15 152 return received; //return received word
xshige 0:67cb2f650c15 153 }
xshige 0:67cb2f650c15 154 void VS1053::sine_test_activate(unsigned char wave)
xshige 0:67cb2f650c15 155 {
xshige 0:67cb2f650c15 156 cs_high(); //enables SDI/disables SCI
xshige 0:67cb2f650c15 157
xshige 0:67cb2f650c15 158 while(!_DREQ); //wait unitl data request is high
xshige 0:67cb2f650c15 159 _spi.write(0x53); //SDI write
xshige 0:67cb2f650c15 160 _spi.write(0xEF); //SDI write
xshige 0:67cb2f650c15 161 _spi.write(0x6E); //SDI write
xshige 0:67cb2f650c15 162 _spi.write(wave); //SDI write
xshige 0:67cb2f650c15 163 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 164 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 165 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 166 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 167
xshige 0:67cb2f650c15 168 cs_low(); //enables SCI/disables SDI
xshige 0:67cb2f650c15 169 }
xshige 0:67cb2f650c15 170 void VS1053::sine_test_deactivate(void)
xshige 0:67cb2f650c15 171 {
xshige 0:67cb2f650c15 172 cs_high();
xshige 0:67cb2f650c15 173
xshige 0:67cb2f650c15 174 while(!_DREQ);
xshige 0:67cb2f650c15 175 _spi.write(0x45); //SDI write
xshige 0:67cb2f650c15 176 _spi.write(0x78); //SDI write
xshige 0:67cb2f650c15 177 _spi.write(0x69); //SDI write
xshige 0:67cb2f650c15 178 _spi.write(0x74); //SDI write
xshige 0:67cb2f650c15 179 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 180 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 181 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 182 _spi.write(0x00); //filler byte
xshige 0:67cb2f650c15 183 }
xshige 0:67cb2f650c15 184 void VS1053::volume(void)
xshige 0:67cb2f650c15 185 {
xshige 0:67cb2f650c15 186 #ifdef FIXED_VOL
xshige 0:67cb2f650c15 187 unsigned char volumize = (0 * 255); // FIXED VOL (not support volume input)
xshige 0:67cb2f650c15 188 #else
xshige 0:67cb2f650c15 189 unsigned char volumize = (_VOL * 255);
xshige 0:67cb2f650c15 190 #endif
xshige 0:67cb2f650c15 191 while(!_DREQ);
xshige 0:67cb2f650c15 192
xshige 0:67cb2f650c15 193 unsigned short int attenuation = ((256 * volumize) + volumize);
xshige 0:67cb2f650c15 194 sci_write(0x0B, attenuation);
xshige 0:67cb2f650c15 195 }
xshige 0:67cb2f650c15 196
xshige 0:67cb2f650c15 197 void VS1053::writeStream(unsigned char *array, int size)
xshige 0:67cb2f650c15 198 {
xshige 0:67cb2f650c15 199 for(int i=0; i<size; i++)
xshige 0:67cb2f650c15 200 {
xshige 0:67cb2f650c15 201 sdi_write(array[i]);
xshige 0:67cb2f650c15 202 }
xshige 0:67cb2f650c15 203 volume();
xshige 0:67cb2f650c15 204 }
xshige 0:67cb2f650c15 205
xshige 0:67cb2f650c15 206 #if 0
xshige 0:67cb2f650c15 207 // this function does not work
xshige 0:67cb2f650c15 208 // because of function call overhead
xshige 0:67cb2f650c15 209 void VS1053::putcStream(unsigned char datum)
xshige 0:67cb2f650c15 210 {
xshige 0:67cb2f650c15 211 sdi_write(datum);
xshige 0:67cb2f650c15 212 }
xshige 0:67cb2f650c15 213 #endif
xshige 0:67cb2f650c15 214
xshige 1:c47269f0e9e1 215 unsigned short int VS1053::wram_read(unsigned short int address)
xshige 1:c47269f0e9e1 216 {
xshige 1:c47269f0e9e1 217 unsigned short int tmp1,tmp2;
xshige 1:c47269f0e9e1 218 sci_write(SCI_WRAMADDR,address);
xshige 1:c47269f0e9e1 219 tmp1=sci_read(SCI_WRAM);
xshige 1:c47269f0e9e1 220 sci_write(SCI_WRAMADDR,address);
xshige 1:c47269f0e9e1 221 tmp2=sci_read(SCI_WRAM);
xshige 1:c47269f0e9e1 222 if (tmp1==tmp2) return tmp1;
xshige 1:c47269f0e9e1 223 sci_write(SCI_WRAMADDR,address);
xshige 1:c47269f0e9e1 224 tmp1=sci_read(SCI_WRAM);
xshige 1:c47269f0e9e1 225 if (tmp1==tmp2) return tmp1;
xshige 1:c47269f0e9e1 226 sci_write(SCI_WRAMADDR,address);
xshige 1:c47269f0e9e1 227 tmp1=sci_read(SCI_WRAM);
xshige 1:c47269f0e9e1 228 if (tmp1==tmp2) return tmp1;
xshige 1:c47269f0e9e1 229 return tmp1;
xshige 1:c47269f0e9e1 230 }
xshige 1:c47269f0e9e1 231
xshige 1:c47269f0e9e1 232 void VS1053::wram_write(unsigned short int address, unsigned short int data)
xshige 1:c47269f0e9e1 233 {
xshige 1:c47269f0e9e1 234 sci_write(SCI_WRAMADDR,address);
xshige 1:c47269f0e9e1 235 sci_write(SCI_WRAM,data);
xshige 1:c47269f0e9e1 236 return;
xshige 1:c47269f0e9e1 237 }
xshige 1:c47269f0e9e1 238
xshige 1:c47269f0e9e1 239
xshige 0:67cb2f650c15 240 void VS1053::terminateStream(void)
xshige 0:67cb2f650c15 241 {
xshige 1:c47269f0e9e1 242 #if 1
xshige 1:c47269f0e9e1 243 unsigned int endFillByte=wram_read(para_endFillByte);
xshige 1:c47269f0e9e1 244 // printf("endFillByte:%04X\r\n",endFillByte); // debug
xshige 1:c47269f0e9e1 245 for(int n=0; n<2052; n++) sdi_write(0xFF&endFillByte);
xshige 1:c47269f0e9e1 246 sci_write(SCI_MODE,(SM_SDINEW+SM_CANCEL));
xshige 1:c47269f0e9e1 247 for(int n=0; n<2048; n++) sdi_write(0xFF&endFillByte);
xshige 1:c47269f0e9e1 248 // don't reset if you don't want to lose the patch
xshige 1:c47269f0e9e1 249 // sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); // set mode reg.
xshige 1:c47269f0e9e1 250 // wait_ms(10);
xshige 1:c47269f0e9e1 251 #endif
xshige 1:c47269f0e9e1 252 }
xshige 1:c47269f0e9e1 253
xshige 1:c47269f0e9e1 254 void VS1053::write_plugin(const unsigned short *plugin, unsigned int len)
xshige 1:c47269f0e9e1 255 {
xshige 1:c47269f0e9e1 256 unsigned int i;
xshige 1:c47269f0e9e1 257 unsigned short addr, n, val;
xshige 1:c47269f0e9e1 258
xshige 1:c47269f0e9e1 259 for(i=0; i<len;)
xshige 1:c47269f0e9e1 260 {
xshige 1:c47269f0e9e1 261 addr = plugin[i++];
xshige 1:c47269f0e9e1 262 n = plugin[i++];
xshige 1:c47269f0e9e1 263 if(n & 0x8000U) //RLE run, replicate n samples
xshige 1:c47269f0e9e1 264 {
xshige 1:c47269f0e9e1 265 n &= 0x7FFF;
xshige 1:c47269f0e9e1 266 val = plugin[i++];
xshige 1:c47269f0e9e1 267 while(n--)
xshige 1:c47269f0e9e1 268 {
xshige 1:c47269f0e9e1 269 sci_write(addr,val);
xshige 1:c47269f0e9e1 270 }
xshige 1:c47269f0e9e1 271 }
xshige 1:c47269f0e9e1 272 else //copy run, copy n sample
xshige 1:c47269f0e9e1 273 {
xshige 1:c47269f0e9e1 274 while(n--)
xshige 1:c47269f0e9e1 275 {
xshige 1:c47269f0e9e1 276 val = plugin[i++];
xshige 1:c47269f0e9e1 277 sci_write(addr,val);
xshige 1:c47269f0e9e1 278 }
xshige 1:c47269f0e9e1 279 }
xshige 1:c47269f0e9e1 280 }
xshige 0:67cb2f650c15 281
xshige 1:c47269f0e9e1 282 return;
xshige 0:67cb2f650c15 283 }
xshige 1:c47269f0e9e1 284
xshige 1:c47269f0e9e1 285
xshige 1:c47269f0e9e1 286 void VS1053::initialize(void)
xshige 1:c47269f0e9e1 287 {
xshige 1:c47269f0e9e1 288 _RST = 1;
xshige 1:c47269f0e9e1 289 cs_high(); //chip disabled
xshige 1:c47269f0e9e1 290 sci_initialise(); //initialise MBED
xshige 1:c47269f0e9e1 291 sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); // set mode reg.
xshige 1:c47269f0e9e1 292 wait_ms(10);
xshige 1:c47269f0e9e1 293 #if 1
xshige 1:c47269f0e9e1 294 // debug
xshige 1:c47269f0e9e1 295 unsigned int chipID_0=wram_read(para_chipID_0);
xshige 1:c47269f0e9e1 296 if (firstTime) printf("chipID_0:%04X\r\n",chipID_0); // debug
xshige 1:c47269f0e9e1 297 unsigned int chipID_1=wram_read(para_chipID_1);
xshige 1:c47269f0e9e1 298 if (firstTime) printf("chipID_1:%04X\r\n",chipID_1); // debug
xshige 1:c47269f0e9e1 299 unsigned int struct_version=wram_read(para_version);
xshige 1:c47269f0e9e1 300 if (firstTime) printf("structure version:%04X\r\n",struct_version); // debug
xshige 1:c47269f0e9e1 301 #endif
xshige 1:c47269f0e9e1 302 //get chip version, set clock multiplier and load patch
xshige 1:c47269f0e9e1 303 int i = (sci_read(SCI_STATUS)&0xF0)>>4;
xshige 1:c47269f0e9e1 304 if(i == 4)
xshige 1:c47269f0e9e1 305 {
xshige 1:c47269f0e9e1 306 if (firstTime) printf("Installed Chip is: VS1053\r\n");
xshige 1:c47269f0e9e1 307 sci_write(SCI_CLOCKF, (SC_MULT_XTALIx50+SC_ADD_20x));
xshige 1:c47269f0e9e1 308 #ifdef VS_PATCH
xshige 1:c47269f0e9e1 309 // loading patch
xshige 1:c47269f0e9e1 310 write_plugin(vs1053b_patch, sizeof(vs1053b_patch)/2);
xshige 1:c47269f0e9e1 311 if (firstTime) {
xshige 1:c47269f0e9e1 312 printf("VS1053b patch loaded.\r\n");
xshige 1:c47269f0e9e1 313 printf("patch size:%d bytes\r\n",sizeof(vs1053b_patch));
xshige 1:c47269f0e9e1 314 }
xshige 1:c47269f0e9e1 315 #endif
xshige 1:c47269f0e9e1 316 #ifdef VS_SPECANA
xshige 1:c47269f0e9e1 317 // loading plugin(spectrum analyzer)
xshige 1:c47269f0e9e1 318 write_plugin(vs1053b_specana, sizeof(vs1053b_specana)/2);
xshige 1:c47269f0e9e1 319 if (firstTime) printf("VS1053b specana loaded.\r\n");
xshige 1:c47269f0e9e1 320 #endif
xshige 1:c47269f0e9e1 321 }
xshige 1:c47269f0e9e1 322 else printf("??? Not Supported Chip???\r\n");
xshige 1:c47269f0e9e1 323 sdi_initialise();
xshige 1:c47269f0e9e1 324 firstTime=0; // disable message when init after 1st time
xshige 1:c47269f0e9e1 325 }