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 File Reference

Functions for interfacing with the mp3 player chip. More...

#include "vs10xx.h"
#include "lcd.h"
#include "filesys.h"
#include "storage.h"
#include "ui.h"
#include "aviplay.c"

Include dependency graph for vs10xx.c:

Include dependency graph

Go to the source code of this file.

Defines

#define AVIPLAY

Functions

unsigned int Mp3ReadRegister (unsigned char addressbyte)
 Read the 16-bit value of a VS10xx register.

void Mp3SoftReset ()
 Soft Reset of VS10xx (Between songs).

void Mp3Reset ()
 Reset VS10xx.

void VsSineTest ()
 Execute VS1011/VS1002 Sine Test Function.

void SendZerosToVS10xx ()
 Send 2048 zeros.

unsigned char PlayDiskSectors (unsigned int nSectorsToPlay)
 Play disk sectors from disk.


Detailed Description

Functions for interfacing with the mp3 player chip.

Todo:
safe rewind

VS1003 WMA "wma-bytes-left" variable adjustment at ff/rew

Definition in file vs10xx.c.


Define Documentation

#define AVIPLAY
 

Definition at line 191 of file vs10xx.c.


Function Documentation

unsigned int Mp3ReadRegister unsigned char  addressbyte  ) 
 

Read the 16-bit value of a VS10xx register.

Definition at line 17 of file vs10xx.c.

References Mp3DeselectControl, Mp3SelectControl, SPI_RESULT_BYTE, SPIPutChar, SPIPutCharWithoutWaiting, SPIWait, and VS_READ_COMMAND.

Referenced by AvailableProcessorTime(), PlayDiskSectors(), Record(), and ScreenSetPlayTime().

00017 { 00018 unsigned int resultvalue = 0; 00019 00020 Mp3SelectControl(); 00021 SPIPutCharWithoutWaiting(VS_READ_COMMAND); 00022 SPIPutChar((addressbyte)); 00023 SPIPutChar(0xff); 00024 SPIWait(); 00025 resultvalue = (SPI_RESULT_BYTE) << 8; 00026 SPIPutCharWithoutWaiting(0xff); 00027 SPIWait(); 00028 resultvalue |= (SPI_RESULT_BYTE); 00029 Mp3DeselectControl(); 00030 return resultvalue; 00031 }

void Mp3Reset  ) 
 

Reset VS10xx.

Definition at line 69 of file vs10xx.c.

References Delay(), MP3_DREQ, Mp3DeselectControl, Mp3DeselectData, Mp3PutInReset, Mp3ReleaseFromReset, Mp3SetVolume, Mp3SoftReset(), Mp3WriteRegister, SPI_AUDATA, SPI_CLOCKF, SPIPutCharWithoutWaiting, and SPISetFastClock.

Referenced by main(), and Record().

00069 { 00070 00071 Mp3PutInReset(); 00072 Delay(1); 00073 00074 /* Send dummy SPI byte to initialize SPI */ 00075 SPIPutCharWithoutWaiting(0xFF); 00076 00077 /* Un-reset MP3 chip */ 00078 Mp3DeselectControl(); 00079 Mp3DeselectData(); 00080 Mp3ReleaseFromReset(); 00081 Mp3SetVolume(0xff,0xff); 00082 00083 /* Set clock register, doubler etc. */ 00084 #ifdef VS1003 00085 Mp3WriteRegister(SPI_CLOCKF, 0xa6, 0x6c); 00086 #else 00087 Mp3WriteRegister(SPI_CLOCKF, 156, 204); 00088 #endif 00089 00090 /* Wait for DREQ */ 00091 while (!MP3_DREQ) 00092 ; 00093 00094 /* Slow sample rate for slow analog part startup */ 00095 Mp3WriteRegister(SPI_AUDATA, 0, 10); /* 10 Hz */ 00096 Delay(100); 00097 00098 /* Switch on the analog parts */ 00099 Mp3SetVolume(0xfe,0xfe); 00100 Mp3WriteRegister (SPI_AUDATA, 31, 64); /* 8kHz */ 00101 Mp3SetVolume(20,20); 00102 Mp3SoftReset(); 00103 SPISetFastClock(); 00104 00105 00106 ConsoleWrite ("Init: VS10XX\r"); 00107 00108 }

Here is the call graph for this function:

void Mp3SoftReset  ) 
 

Soft Reset of VS10xx (Between songs).

Definition at line 35 of file vs10xx.c.

References Delay(), MP3_DREQ, Mp3DeselectData, Mp3SelectData, Mp3WriteRegister, SPI_CLOCKF, SPI_MODE, SPIPutChar, SPIPutCharWithoutWaiting, and SPIWait.

Referenced by main(), and Mp3Reset().

00035 { 00036 00037 /* Soft Reset of VS10xx */ 00038 Mp3WriteRegister (SPI_MODE, 0x08, 0x04); /* Newmode, Reset, No L1-2 */ 00039 00040 Delay(1); /* One millisecond delay */ 00041 while (!MP3_DREQ) /* wait for startup */ 00042 ; 00043 00044 /* Set clock register, doubler etc. */ 00045 #ifdef VS1003 00046 Mp3WriteRegister(SPI_CLOCKF, 0xa6, 0x96); 00047 #else 00048 Mp3WriteRegister(SPI_CLOCKF, 156, 204); 00049 #endif 00050 00051 Delay(1); /* One millisecond delay */ 00052 00053 00054 /* Send null bytes to data interface */ 00055 Mp3SelectData(); 00056 SPIPutCharWithoutWaiting(0); 00057 SPIPutChar(0); 00058 SPIPutChar(0); 00059 SPIPutChar(0); 00060 SPIWait(); 00061 Mp3DeselectData(); 00062 00063 }

Here is the call graph for this function:

unsigned char PlayDiskSectors unsigned int  nSectorsToPlay  ) 
 

Play disk sectors from disk.

Starting from current value in global variable sectorAddress, sends a number of disk sectors to vs10xx and returns.

How many sectors to send between ff/rew commands

Definition at line 202 of file vs10xx.c.

References AvailableProcessorTime(), DiskBlock::Raw::buf, dataBufPtr, diskSect, GREEN_LED, Address::l, LED_OFF, LED_ON, MP3_DREQ, Mp3DeselectData, Mp3ReadRegister(), Mp3SelectData, Mp3WriteRegister, PlayAvi(), playingState, PrepareToReadDiskSector(), PS_CUE, PS_CUE_ACTION, PS_CUE_WAIT1003, PS_END_OF_SONG, PS_FALLBACK_1, PS_FALLBACK_N, PS_NEXT_SONG, PS_NORMAL, PS_PREVIOUS_SONG, PS_RECORDING, PS_REW_WAIT1003, PS_REWIND, DiskBlock::raw, ReadDiskSector(), sectorAddress, SendZerosToVS10xx(), SPI_AICTRL2, SPI_HDAT1, SPIPutChar, SPIPutCharWithoutWaiting, and SPIWait.

Referenced by PlayCurrentFile().

00202 { 00203 00205 unsigned char fallbackCount = 0; 00206 00207 00208 #ifdef AVIPLAY 00209 if (!PlayAvi()) return 0; //try to play AVI file soundtrack starting from 00210 //current sector, if avifile is played, return. 00211 #endif 00212 00213 00214 PrepareToReadDiskSector(sectorAddress.l); 00215 while (nSectorsToPlay--){ 00216 00217 AvailableProcessorTime(); 00218 00219 ReadDiskSector(sectorAddress.l); 00220 00221 /* If playing state is something else than "play normally", 00222 exit returning the request number. */ 00223 if ((playingState==PS_END_OF_SONG)|| 00224 (playingState==PS_NEXT_SONG)|| 00225 (playingState==PS_RECORDING)|| 00226 (playingState==PS_PREVIOUS_SONG)){ 00227 return playingState; 00228 } 00229 00230 00231 /* === REWIND / FAST FORWARD FUNCTIONALITY CODE BEGINS === */ 00232 /* If you don't implement rewind / fast forward, leave these lines out */ 00233 00234 if (playingState==PS_FALLBACK_N){ 00235 if ((--fallbackCount)==0){ 00236 playingState=PS_NORMAL; 00237 } 00238 } 00239 00240 if (playingState==PS_FALLBACK_1){ 00241 /* Now we should have brand new sector in memory ready for sending to 00242 VS1003, so let's send zeroes between old and new data. */ 00243 ConsoleWrite("(Zeros)"); 00244 SendZerosToVS10xx(); 00245 ConsoleWrite("->Fallback to normal"); 00246 fallbackCount = 24; 00247 playingState = PS_FALLBACK_N; 00248 } 00249 00250 00251 if (playingState==PS_CUE){ //Request to start fast forward 00252 if (Mp3ReadRegister(SPI_HDAT1)==((int)'W'<< 8)+'m'){ 00253 ConsoleWrite("\rWmCUE->Wait"); 00254 Mp3WriteRegister(SPI_AICTRL2, 0x12, 0x34); 00255 playingState = PS_CUE_WAIT1003; 00256 }else{ 00257 playingState = PS_CUE_ACTION; 00258 } 00259 } 00260 00261 if (playingState==PS_CUE_WAIT1003){ //Wait for permission to break data flow 00262 if (Mp3ReadRegister(SPI_AICTRL2)==0x2345){ //permission granted 00263 ConsoleWrite("->Action"); 00264 playingState = PS_CUE_ACTION; 00265 } 00266 } 00267 00268 if (playingState==PS_CUE_ACTION){ 00269 if (nSectorsToPlay>128){ 00270 sectorAddress.l += 128; //Skip sectors 00271 nSectorsToPlay -= 128; 00272 //adjust vs1003 song left 00273 ConsoleWrite("->Fallback(5)"); 00274 playingState = PS_FALLBACK_1; //Sector already in memory still goes. 00275 } 00276 } 00277 00278 if (playingState==PS_REWIND){ //Request to start fast forward 00279 Mp3WriteRegister(SPI_AICTRL2, 0x12, 0x34); 00280 playingState = PS_REW_WAIT1003; 00281 } 00282 00283 if (playingState==PS_REW_WAIT1003){ //Wait for permission to break data flow 00284 if (1){ 00285 if (1 || (Mp3ReadRegister(SPI_AICTRL2)==0x2345)){ //permission granted 00286 sectorAddress.l -= 128; 00287 nSectorsToPlay += 128; 00288 playingState = PS_FALLBACK_1; //Sector already in memory still goes. 00289 } 00290 } 00291 } 00292 00293 00294 /* === END OF REWIND / FAST FORWARD FUNCTIONALITY CODE === */ 00295 00296 00297 00298 sectorAddress.l++; 00299 if (nSectorsToPlay){ 00300 /*Do not seek after the last sector*/ 00301 PrepareToReadDiskSector(sectorAddress.l); 00302 } 00303 00304 Mp3SelectData(); 00305 00306 dataBufPtr = diskSect.raw.buf; 00307 while (dataBufPtr < diskSect.raw.buf+512){ 00308 00309 if (!MP3_DREQ){ 00310 GREEN_LED = LED_ON; 00311 while (!MP3_DREQ){ 00312 Mp3DeselectData(); 00313 AvailableProcessorTime(); 00314 Mp3SelectData(); 00315 } 00316 } 00317 GREEN_LED = LED_OFF; 00318 00319 /* Send 32 octets of disk block data to VS10xx */ 00320 SPIPutCharWithoutWaiting(*dataBufPtr++); 00321 SPIWait(); 00322 SPIPutChar(*dataBufPtr++); 00323 SPIPutChar(*dataBufPtr++); 00324 SPIPutChar(*dataBufPtr++); 00325 SPIPutChar(*dataBufPtr++); 00326 SPIPutChar(*dataBufPtr++); 00327 SPIPutChar(*dataBufPtr++); 00328 SPIPutChar(*dataBufPtr++); 00329 SPIPutChar(*dataBufPtr++); 00330 SPIPutChar(*dataBufPtr++); 00331 SPIPutChar(*dataBufPtr++); 00332 SPIPutChar(*dataBufPtr++); 00333 SPIPutChar(*dataBufPtr++); 00334 SPIPutChar(*dataBufPtr++); 00335 SPIPutChar(*dataBufPtr++); 00336 SPIPutChar(*dataBufPtr++); 00337 SPIPutChar(*dataBufPtr++); 00338 SPIPutChar(*dataBufPtr++); 00339 SPIPutChar(*dataBufPtr++); 00340 SPIPutChar(*dataBufPtr++); 00341 SPIPutChar(*dataBufPtr++); 00342 SPIPutChar(*dataBufPtr++); 00343 SPIPutChar(*dataBufPtr++); 00344 SPIPutChar(*dataBufPtr++); 00345 SPIPutChar(*dataBufPtr++); 00346 SPIPutChar(*dataBufPtr++); 00347 SPIPutChar(*dataBufPtr++); 00348 SPIPutChar(*dataBufPtr++); 00349 SPIPutChar(*dataBufPtr++); 00350 SPIPutChar(*dataBufPtr++); 00351 SPIPutChar(*dataBufPtr++); 00352 SPIPutChar(*dataBufPtr++); 00353 SPIWait(); 00354 } 00355 00356 00357 SPIWait(); 00358 Mp3DeselectData(); 00359 } 00360 00361 00362 return 0; //OK Exit 00363 }

Here is the call graph for this function:

void SendZerosToVS10xx  ) 
 

Send 2048 zeros.

Todo:
Timeouts for all DREQ busy loop waits!

Definition at line 178 of file vs10xx.c.

References Temp::i, MP3_DREQ, Mp3DeselectData, Mp3SelectData, SPIPutChar, SPIPutCharWithoutWaiting, SPIWait, and temp.

Referenced by PlayCurrentFile(), and PlayDiskSectors().

00178 { 00179 Mp3SelectData(); 00180 SPIPutCharWithoutWaiting(0); 00181 for (temp.i=0; temp.i<1048; temp.i++){ /* TESTING 1048 TESTING */ 00182 while (!MP3_DREQ) 00183 ; 00184 SPIPutChar(0); 00185 } 00186 SPIWait(); 00187 Mp3DeselectData(); 00188 }

void VsSineTest  ) 
 

Execute VS1011/VS1002 Sine Test Function.

Definition at line 112 of file vs10xx.c.

References Delay(), GREEN_LED, LED_OFF, LED_ON, MP3_DREQ, Mp3DeselectControl, Mp3DeselectData, Mp3PutInReset, Mp3ReleaseFromReset, Mp3SelectControl, Mp3SelectData, RED_LED, SPIPutChar, SPIPutCharWithoutWaiting, and SPIWait.

00112 { 00113 00114 /* Reset MP3 chip */ 00115 Mp3PutInReset(); /* Pull xRESET low -> hardware reset */ 00116 Delay(100); /* 100 ms delay */ 00117 00118 /* Send dummy SPI byte to initialize SPI of Atmel microcontroller */ 00119 SPIPutCharWithoutWaiting(0xFF); 00120 00121 /* Un-reset MP3 chip */ 00122 Mp3DeselectControl(); /* Pull xCS high */ 00123 Mp3DeselectData(); /* Pull xDCS high */ 00124 Mp3ReleaseFromReset(); /* Pull xRESET high */ 00125 Delay(100); /* 100 ms delay */ 00126 00127 GREEN_LED = LED_ON; 00128 RED_LED = LED_ON; 00129 00130 /* VS10xx Application Notes, chapter 4.8 ---------------------------------*/ 00131 /* As an example, let's write value 0x0820 to register 00 byte by byte */ 00132 Mp3SelectControl(); /* Now SPI writes go to SCI port */ 00133 SPIPutChar(0x02); /* Send SPI Byte, then wait for byte to be sent. */ 00134 SPIPutChar(0x00); /* 0x02 was WRITE command, 0x00 is register number */ 00135 SPIPutChar(0x08); /* This byte goes to MSB */ 00136 SPIPutChar(0x20); /* ..and this is LSB. (0x20=Allow Test Mode) */ 00137 SPIWait(); /* Wait until Atmel MCU signals SPI write complete */ 00138 Mp3DeselectControl(); /* Now SPI writes don't go to SCI port */ 00139 00140 while (!MP3_DREQ) /* Wait for DREQ = 1 */ 00141 ; /* Do nothing while waiting for DREQ = 1 */ 00142 00143 /* Send a Sine Test Header to Data port */ 00144 Mp3SelectData(); /* Now SPI writes go to SDI port */ 00145 00146 SPIPutChar(0x53); /* - This is a special VLSI Solution test header - */ 00147 SPIPutChar(0xef); /* - that starts a sine sound. It's good for - */ 00148 SPIPutChar(0x6e); /* - testing your code, the chip and also for - */ 00149 SPIPutChar(0x44); /* - seeing if your MP3 decoder was manufactured - */ 00150 SPIPutChar(0x00); /* - by VLSI Solution oy. ------------------------ */ 00151 SPIPutChar(0x00); 00152 SPIPutChar(0x00); 00153 SPIPutChar(0x00); 00154 SPIWait(); 00155 Mp3DeselectData(); 00156 00157 RED_LED = LED_OFF; 00158 Delay (500); /* 500 ms delay */ 00159 GREEN_LED = LED_OFF; 00160 00161 /* Stop the sine test sound */ 00162 Mp3SelectData(); 00163 SPIPutChar(0x45); 00164 SPIPutChar(0x78); 00165 SPIPutChar(0x69); 00166 SPIPutChar(0x74); 00167 SPIPutChar(0x00); 00168 SPIPutChar(0x00); 00169 SPIPutChar(0x00); 00170 SPIPutChar(0x00); 00171 SPIWait(); 00172 Mp3DeselectData(); 00173 00174 Delay(500); /* 500 ms delay */ 00175 }

Here is the call graph for this function:


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