VLSI Solution Oy VLSI Solution Oy Evaluation MP3 Player Source Code Documentation

Main Page | Class List | File List | Class Members | File Members | Related Pages

vs10xx.c

Go to the documentation of this file.
00001 00007 #include "vs10xx.h" 00008 #include "lcd.h" 00009 #include "filesys.h" 00010 #include "storage.h" 00011 #include "ui.h" 00012 00013 00014 00015 00016 00017 #define SKIP_PLUGIN_VARNAME 00018 const unsigned short patch[] = { 00019 #include "vorbis53b.plg" 00020 }; 00021 00022 00023 void LoadUserPatch(void) { 00024 int i = 0; 00025 00026 while (i<sizeof(patch)/sizeof(patch[0])) { 00027 unsigned short addr, n, val; 00028 addr = patch[i++]; 00029 n = patch[i++]; 00030 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00031 n &= 0x7FFF; 00032 val = patch[i++]; 00033 while (n--) { 00034 Mp3WriteRegister(addr, val>>8, val & 0xff); 00035 } 00036 } else { /* Copy run, copy n samples */ 00037 while (n--) { 00038 val = patch[i++]; 00039 Mp3WriteRegister(addr, val>>8, val & 0xff); 00040 } 00041 } 00042 } 00043 Delay(1); 00044 while (!MP3_DREQ) 00045 ; 00046 } 00047 00048 00050 unsigned int Mp3ReadRegister (unsigned char addressbyte){ 00051 unsigned int resultvalue = 0; 00052 00053 Mp3SelectControl(); 00054 SPIPutCharWithoutWaiting(VS_READ_COMMAND); 00055 SPIPutChar((addressbyte)); 00056 SPIPutChar(0xff); 00057 SPIWait(); 00058 resultvalue = (SPI_RESULT_BYTE) << 8; 00059 SPIPutCharWithoutWaiting(0xff); 00060 SPIWait(); 00061 resultvalue |= (SPI_RESULT_BYTE); 00062 Mp3DeselectControl(); 00063 return resultvalue; 00064 } 00065 00066 00067 00068 00069 00070 00072 void Mp3SoftReset(){ 00073 /* Soft Reset of VS10xx */ 00074 Mp3WriteRegister (SPI_MODE, 0x08, 0x04); /* Newmode, Reset, No L1-2 */ 00075 Delay(1); 00076 while (!MP3_DREQ) /* wait for startup */ 00077 ; 00078 /* Set clock register, doubler etc. */ 00079 Mp3WriteRegister(SPI_CLOCKF, 0xa0, 0x00); 00080 while (!MP3_DREQ) 00081 ; 00082 LoadUserPatch(); 00083 00084 } 00085 00086 00088 void Mp3Reset(){ 00089 //ConsolePutChar(13); 00090 00091 Mp3PutInReset(); 00092 Delay(1); 00093 00094 /* Send dummy SPI byte to initialize atmel SPI */ 00095 SPIPutCharWithoutWaiting(0xFF); 00096 00097 /* Un-reset MP3 chip */ 00098 Mp3DeselectControl(); 00099 Mp3DeselectData(); 00100 Mp3ReleaseFromReset(); 00101 00102 while (!MP3_DREQ) 00103 ; 00104 00105 #if 0 00106 ConsoleWrite("ClockF:"); 00107 ConsolePutUInt(Mp3ReadRegister(SPI_CLOCKF)); 00108 ConsolePutChar(13); 00109 #endif 00110 00111 /* Set clock register, doubler etc. */ 00112 Mp3WriteRegister(SPI_CLOCKF, 0xa0, 0x00); 00113 Delay(1); 00114 /* Wait for DREQ */ 00115 while (!MP3_DREQ) 00116 ; 00117 00118 00119 #if 0 00120 ConsoleWrite("ClockF:"); 00121 ConsolePutUInt(Mp3ReadRegister(SPI_CLOCKF)); 00122 ConsolePutChar(13); 00123 Mp3WriteRegister(SPI_WRAMADDR, 0xc0, 0x13); 00124 ConsoleWrite("0xC013:"); 00125 ConsolePutUInt (Mp3ReadRegister(SPI_WRAM)); 00126 ConsolePutUInt (Mp3ReadRegister(SPI_WRAM)); 00127 ConsolePutChar(13); 00128 #endif 00129 00130 00131 Mp3SoftReset(); 00132 00133 #if 1 00134 ConsoleWrite("ClockF:"); 00135 ConsolePutUInt(Mp3ReadRegister(SPI_CLOCKF)); 00136 ConsolePutChar(13); 00137 #endif 00138 00139 00140 Mp3WriteRegister(SPI_WRAMADDR, 0xc0, 0x13); 00141 ConsoleWrite("0xC013:"); 00142 ConsolePutUInt (Mp3ReadRegister(SPI_WRAM)); 00143 ConsolePutUInt (Mp3ReadRegister(SPI_WRAM)); 00144 ConsolePutChar(13); 00145 00146 00147 /* Switch on the analog parts */ 00148 Mp3SetVolume(20,20); 00149 00150 SPISetFastClock(); 00151 ConsoleWrite ("Init: VS10XX\r"); 00152 00153 } 00154 00155 00157 void VsSineTest(){ 00158 00159 ConsoleWrite("Not For VS1053!"); /* Needs adjustment */ 00160 00161 /* Reset MP3 chip */ 00162 Mp3PutInReset(); /* Pull xRESET low -> hardware reset */ 00163 Delay(100); /* 100 ms delay */ 00164 00165 /* Send dummy SPI byte to initialize SPI of Atmel microcontroller */ 00166 SPIPutCharWithoutWaiting(0xFF); 00167 00168 /* Un-reset MP3 chip */ 00169 Mp3DeselectControl(); /* Pull xCS high */ 00170 Mp3DeselectData(); /* Pull xDCS high */ 00171 Mp3ReleaseFromReset(); /* Pull xRESET high */ 00172 Delay(100); /* 100 ms delay */ 00173 00174 GREEN_LED = LED_ON; 00175 RED_LED = LED_ON; 00176 00177 /* VS10xx Application Notes, chapter 4.8 ---------------------------------*/ 00178 /* As an example, let's write value 0x0820 to register 00 byte by byte */ 00179 Mp3SelectControl(); /* Now SPI writes go to SCI port */ 00180 SPIPutChar(0x02); /* Send SPI Byte, then wait for byte to be sent. */ 00181 SPIPutChar(0x00); /* 0x02 was WRITE command, 0x00 is register number */ 00182 SPIPutChar(0x08); /* This byte goes to MSB */ 00183 SPIPutChar(0x20); /* ..and this is LSB. (0x20=Allow Test Mode) */ 00184 SPIWait(); /* Wait until Atmel MCU signals SPI write complete */ 00185 Mp3DeselectControl(); /* Now SPI writes don't go to SCI port */ 00186 00187 while (!MP3_DREQ) /* Wait for DREQ = 1 */ 00188 ; /* Do nothing while waiting for DREQ = 1 */ 00189 00190 /* Send a Sine Test Header to Data port */ 00191 Mp3SelectData(); /* Now SPI writes go to SDI port */ 00192 00193 SPIPutChar(0x53); /* - This is a special VLSI Solution test header - */ 00194 SPIPutChar(0xef); /* - that starts a sine sound. It's good for - */ 00195 SPIPutChar(0x6e); /* - testing your code, the chip and also for - */ 00196 SPIPutChar(0x44); /* - seeing if your MP3 decoder was manufactured - */ 00197 SPIPutChar(0x00); /* - by VLSI Solution oy. ------------------------ */ 00198 SPIPutChar(0x00); 00199 SPIPutChar(0x00); 00200 SPIPutChar(0x00); 00201 SPIWait(); 00202 Mp3DeselectData(); 00203 00204 RED_LED = LED_OFF; 00205 Delay (500); /* 500 ms delay */ 00206 GREEN_LED = LED_OFF; 00207 00208 /* Stop the sine test sound */ 00209 Mp3SelectData(); 00210 SPIPutChar(0x45); 00211 SPIPutChar(0x78); 00212 SPIPutChar(0x69); 00213 SPIPutChar(0x74); 00214 SPIPutChar(0x00); 00215 SPIPutChar(0x00); 00216 SPIPutChar(0x00); 00217 SPIPutChar(0x00); 00218 SPIWait(); 00219 Mp3DeselectData(); 00220 00221 Delay(500); /* 500 ms delay */ 00222 } 00223 00225 void SendZerosToVS10xx(){ 00226 Mp3SelectData(); 00227 SPIPutCharWithoutWaiting(0); 00228 for (temp.i=0; temp.i<1048; temp.i++){ /* TESTING 1048 TESTING */ 00229 while (!MP3_DREQ) 00230 ; 00231 SPIPutChar(0); 00232 } 00233 SPIWait(); 00234 Mp3DeselectData(); 00235 } 00236 00237 //Link in experimental AVI file sound track playing 00238 #define AVIPLAY 00239 00240 #ifdef AVIPLAY 00241 #include "aviplay.c" 00242 #endif 00243 00244 00245 00249 unsigned char PlayDiskSectors (unsigned int nSectorsToPlay){ 00250 00252 unsigned char fallbackCount = 0; 00253 00254 00255 #ifdef AVIPLAY 00256 if (!PlayAvi()) return 0; //try to play AVI file soundtrack starting from 00257 //current sector, if avifile is played, return. 00258 #endif 00259 00260 00261 PrepareToReadDiskSector(sectorAddress.l); 00262 while (nSectorsToPlay--){ 00263 00264 AvailableProcessorTime(); 00265 00266 ReadDiskSector(sectorAddress.l); 00267 00268 /* If playing state is something else than "play normally", 00269 exit returning the request number. */ 00270 if ((playingState==PS_END_OF_SONG)|| 00271 (playingState==PS_NEXT_SONG)|| 00272 (playingState==PS_RECORDING)|| 00273 (playingState==PS_PREVIOUS_SONG)){ 00274 return playingState; 00275 } 00276 00277 00278 /* === REWIND / FAST FORWARD FUNCTIONALITY CODE BEGINS === */ 00279 /* If you don't implement rewind / fast forward, leave these lines out */ 00280 00281 if (playingState==PS_FALLBACK_N){ 00282 if ((--fallbackCount)==0){ 00283 playingState=PS_NORMAL; 00284 } 00285 } 00286 00287 if (playingState==PS_FALLBACK_1){ 00288 /* Now we should have brand new sector in memory ready for sending to 00289 VS1003, so let's send zeroes between old and new data. */ 00290 ConsoleWrite("(Zeros)"); 00291 SendZerosToVS10xx(); 00292 ConsoleWrite("->Fallback to normal"); 00293 fallbackCount = 24; 00294 playingState = PS_FALLBACK_N; 00295 } 00296 00297 00298 if (playingState==PS_CUE){ //Request to start fast forward 00299 if (Mp3ReadRegister(SPI_HDAT1)==((int)'W'<< 8)+'m'){ 00300 ConsoleWrite("\rWmCUE->Wait"); 00301 Mp3WriteRegister(SPI_AICTRL2, 0x12, 0x34); 00302 playingState = PS_CUE_WAIT1003; 00303 }else{ 00304 playingState = PS_CUE_ACTION; 00305 } 00306 } 00307 00308 if (playingState==PS_CUE_WAIT1003){ //Wait for permission to break data flow 00309 if (Mp3ReadRegister(SPI_AICTRL2)==0x2345){ //permission granted 00310 ConsoleWrite("->Action"); 00311 playingState = PS_CUE_ACTION; 00312 } 00313 } 00314 00315 if (playingState==PS_CUE_ACTION){ 00316 if (nSectorsToPlay>128){ 00317 sectorAddress.l += 128; //Skip sectors 00318 nSectorsToPlay -= 128; 00319 //adjust vs1003 song left 00320 ConsoleWrite("->Fallback(5)"); 00321 playingState = PS_FALLBACK_1; //Sector already in memory still goes. 00322 } 00323 } 00324 00325 if (playingState==PS_REWIND){ //Request to start fast forward 00326 Mp3WriteRegister(SPI_AICTRL2, 0x12, 0x34); 00327 playingState = PS_REW_WAIT1003; 00328 } 00329 00330 if (playingState==PS_REW_WAIT1003){ //Wait for permission to break data flow 00331 if (1){ 00332 if (1 || (Mp3ReadRegister(SPI_AICTRL2)==0x2345)){ //permission granted 00333 sectorAddress.l -= 128; 00334 nSectorsToPlay += 128; 00335 playingState = PS_FALLBACK_1; //Sector already in memory still goes. 00336 } 00337 } 00338 } 00339 00340 00341 /* === END OF REWIND / FAST FORWARD FUNCTIONALITY CODE === */ 00342 00343 00344 00345 sectorAddress.l++; 00346 if (nSectorsToPlay){ 00347 /*Do not seek after the last sector*/ 00348 PrepareToReadDiskSector(sectorAddress.l); 00349 } 00350 00351 Mp3SelectData(); 00352 00353 dataBufPtr = diskSect.raw.buf; 00354 while (dataBufPtr < diskSect.raw.buf+512){ 00355 00356 if (!MP3_DREQ){ 00357 GREEN_LED = LED_ON; 00358 while (!MP3_DREQ){ 00359 Mp3DeselectData(); 00360 AvailableProcessorTime(); 00361 Mp3SelectData(); 00362 } 00363 } 00364 GREEN_LED = LED_OFF; 00365 00366 /* Send 32 octets of disk block data to VS10xx */ 00367 00368 //Mp3WriteRegister (SPI_MODE, 0x0C, 0x00); /* Newmode, No L1-2 */ 00369 00370 SPIPutCharWithoutWaiting(*dataBufPtr++); 00371 SPIWait(); 00372 SPIPutChar(*dataBufPtr++); 00373 SPIPutChar(*dataBufPtr++); 00374 SPIPutChar(*dataBufPtr++); 00375 SPIPutChar(*dataBufPtr++); 00376 SPIPutChar(*dataBufPtr++); 00377 SPIPutChar(*dataBufPtr++); 00378 SPIPutChar(*dataBufPtr++); 00379 SPIPutChar(*dataBufPtr++); 00380 SPIPutChar(*dataBufPtr++); 00381 SPIPutChar(*dataBufPtr++); 00382 SPIPutChar(*dataBufPtr++); 00383 SPIPutChar(*dataBufPtr++); 00384 SPIPutChar(*dataBufPtr++); 00385 SPIPutChar(*dataBufPtr++); 00386 SPIPutChar(*dataBufPtr++); 00387 SPIPutChar(*dataBufPtr++); 00388 SPIPutChar(*dataBufPtr++); 00389 SPIPutChar(*dataBufPtr++); 00390 SPIPutChar(*dataBufPtr++); 00391 SPIPutChar(*dataBufPtr++); 00392 SPIPutChar(*dataBufPtr++); 00393 SPIPutChar(*dataBufPtr++); 00394 SPIPutChar(*dataBufPtr++); 00395 SPIPutChar(*dataBufPtr++); 00396 SPIPutChar(*dataBufPtr++); 00397 SPIPutChar(*dataBufPtr++); 00398 SPIPutChar(*dataBufPtr++); 00399 SPIPutChar(*dataBufPtr++); 00400 SPIPutChar(*dataBufPtr++); 00401 SPIPutChar(*dataBufPtr++); 00402 SPIPutChar(*dataBufPtr++); 00403 SPIWait(); 00404 00405 //Mp3WriteRegister (SPI_MODE, 0x08, 0x00); /* Newmode, No L1-2 */ 00406 00407 00408 } 00409 00410 00411 SPIWait(); 00412 Mp3DeselectData(); 00413 } 00414 00415 00416 return 0; //OK Exit 00417 } 00418 00419

All software copyright 2000-2004 VLSI Solution OY. Redistribution of these software modules are limited to promotional use only and only with the VS1011 / VS1002 / VS1003 MP3-Evakit evaluation boards. Free or commercial use of these software modules in MP3 players is ok if the product includes MP3 decoder chip(s) from VLSI. You can request the complete (compilable) package from mp3@vlsi.fi