📄 vs10xx.c
字号:
/** \file vs10xx.c * Functions for interfacing with the mp3 player chip. * \todo safe rewind * \todo VS1003 WMA "wma-bytes-left" variable adjustment at ff/rew */#include "vs10xx.h"#include "lcd.h"#include "filesys.h"#include "storage.h"#include "ui.h"/** Read the 16-bit value of a VS10xx register */unsigned int Mp3ReadRegister (unsigned char addressbyte){ unsigned int resultvalue = 0; Mp3SelectControl(); SPIPutCharWithoutWaiting(VS_READ_COMMAND); SPIPutChar((addressbyte)); SPIPutChar(0xff); SPIWait(); resultvalue = (SPI_RESULT_BYTE) << 8; SPIPutCharWithoutWaiting(0xff); SPIWait(); resultvalue |= (SPI_RESULT_BYTE); Mp3DeselectControl(); return resultvalue;} /** Soft Reset of VS10xx (Between songs) */void Mp3SoftReset(){ /* Soft Reset of VS10xx */ Mp3WriteRegister (SPI_MODE, 0x08, 0x04); /* Newmode, Reset, No L1-2 */ Delay(1); /* One millisecond delay */ while (!MP3_DREQ) /* wait for startup */ ; /* Set clock register, doubler etc. */#ifdef VS1003 Mp3WriteRegister(SPI_CLOCKF, 0xa6, 0x96);#else Mp3WriteRegister(SPI_CLOCKF, 156, 204);#endif Delay(1); /* One millisecond delay */ /* Send null bytes to data interface */ Mp3SelectData(); SPIPutCharWithoutWaiting(0); SPIPutChar(0); SPIPutChar(0); SPIPutChar(0); SPIWait(); Mp3DeselectData();}/** Reset VS10xx */void Mp3Reset(){ Mp3PutInReset(); Delay(1); /* Send dummy SPI byte to initialize SPI */ SPIPutCharWithoutWaiting(0xFF); /* Un-reset MP3 chip */ Mp3DeselectControl(); Mp3DeselectData(); Mp3ReleaseFromReset(); Mp3SetVolume(0xff,0xff); /* Set clock register, doubler etc. */#ifdef VS1003 Mp3WriteRegister(SPI_CLOCKF, 0xa6, 0x6c);#else Mp3WriteRegister(SPI_CLOCKF, 156, 204);#endif /* Wait for DREQ */ while (!MP3_DREQ) ; /* Slow sample rate for slow analog part startup */ Mp3WriteRegister(SPI_AUDATA, 0, 10); /* 10 Hz */ Delay(100); /* Switch on the analog parts */ Mp3SetVolume(0xfe,0xfe); Mp3WriteRegister (SPI_AUDATA, 31, 64); /* 8kHz */ Mp3SetVolume(20,20); Mp3SoftReset(); SPISetFastClock(); ConsoleWrite ("Init: VS10XX\r");}/** VS10xx Sine Test Function - Good getting started example */ void VsSineTest(){ /* Reset MP3 chip */ Mp3PutInReset(); /* Pull xRESET low -> hardware reset */ Delay(100); /* 100 ms delay */ /* Send dummy SPI byte to initialize SPI of Atmel microcontroller */ SPIPutCharWithoutWaiting(0xFF); /* Un-reset MP3 chip */ Mp3DeselectControl(); /* Pull xCS high */ Mp3DeselectData(); /* Pull xDCS high */ Mp3ReleaseFromReset(); /* Pull xRESET high */ Delay(100); /* 100 ms delay */ GREEN_LED = LED_ON; RED_LED = LED_ON; /* VS10xx Application Notes, chapter 4.8 ---------------------------------*/ /* As an example, let's write value 0x0820 to register 00 byte by byte */ Mp3SelectControl(); /* Now SPI writes go to SCI port */ SPIPutChar(0x02); /* Send SPI Byte, then wait for byte to be sent. */ SPIPutChar(0x00); /* 0x02 was WRITE command, 0x00 is register number */ SPIPutChar(0x08); /* This byte goes to MSB */ SPIPutChar(0x20); /* ..and this is LSB. (0x20=Allow Test Mode) */ SPIWait(); /* Wait until Atmel MCU signals SPI write complete */ Mp3DeselectControl(); /* Now SPI writes don't go to SCI port */ while (!MP3_DREQ) /* Wait for DREQ = 1 */ ; /* Do nothing while waiting for DREQ = 1 */ /* Send a Sine Test Header to Data port */ Mp3SelectData(); /* Now SPI writes go to SDI port */ SPIPutChar(0x53); /* - This is a special VLSI Solution test header - */ SPIPutChar(0xef); /* - that starts a sine sound. It's good for - */ SPIPutChar(0x6e); /* - testing your code, the chip and also for - */ SPIPutChar(0x44); /* - seeing if your MP3 decoder was manufactured - */ SPIPutChar(0x00); /* - by VLSI Solution oy. ------------------------ */ SPIPutChar(0x00); SPIPutChar(0x00); SPIPutChar(0x00); SPIWait(); Mp3DeselectData(); RED_LED = LED_OFF; Delay (500); /* 500 ms delay */ GREEN_LED = LED_OFF; /* Stop the sine test sound */ Mp3SelectData(); SPIPutChar(0x45); SPIPutChar(0x78); SPIPutChar(0x69); SPIPutChar(0x74); SPIPutChar(0x00); SPIPutChar(0x00); SPIPutChar(0x00); SPIPutChar(0x00); SPIWait(); Mp3DeselectData(); Delay(500); /* 500 ms delay */} /** Send 2048 zeros. */void SendZerosToVS10xx(){ Mp3SelectData(); SPIPutCharWithoutWaiting(0); for (temp.i=0; temp.i<1048; temp.i++){ /* TESTING 1048 TESTING */ while (!MP3_DREQ) ; SPIPutChar(0); } SPIWait(); Mp3DeselectData();} //Link in experimental AVI file sound track playing#define AVIPLAY#ifdef AVIPLAY#include "aviplay.c"#endif/** Send a number of disk sectors to vs10xx. * Starting from current value in global variable sectorAddress, * sends a number of disk sectors to vs10xx and returns. */unsigned char PlayDiskSectors (unsigned int nSectorsToPlay){ /** How many sectors to send between ff/rew commands */ unsigned char fallbackCount = 0;#ifdef AVIPLAY if (!PlayAvi()) return 0; //try to play AVI file soundtrack starting from //current sector, if avifile is played, return.#endif PrepareToReadDiskSector(sectorAddress.l); while (nSectorsToPlay--){ AvailableProcessorTime(); ReadDiskSector(sectorAddress.l); /* If playing state is something else than "play normally", exit returning the request number. */ if ((playingState==PS_END_OF_SONG)|| (playingState==PS_NEXT_SONG)|| (playingState==PS_RECORDING)|| (playingState==PS_PREVIOUS_SONG)){ return playingState; } /* === REWIND / FAST FORWARD FUNCTIONALITY CODE BEGINS === */ /* If you don't implement rewind / fast forward, leave these lines out */ if (playingState==PS_FALLBACK_N){ if ((--fallbackCount)==0){ playingState=PS_NORMAL; } } if (playingState==PS_FALLBACK_1){ /* Now we should have brand new sector in memory ready for sending to VS1003, so let's send zeroes between old and new data. */ ConsoleWrite("(Zeros)"); SendZerosToVS10xx(); ConsoleWrite("->Fallback to normal"); fallbackCount = 24; playingState = PS_FALLBACK_N; } if (playingState==PS_CUE){ //Request to start fast forward if (Mp3ReadRegister(SPI_HDAT1)==((int)'W'<< 8)+'m'){ ConsoleWrite("\rWmCUE->Wait"); Mp3WriteRegister(SPI_AICTRL2, 0x12, 0x34); playingState = PS_CUE_WAIT1003; }else{ playingState = PS_CUE_ACTION; } } if (playingState==PS_CUE_WAIT1003){ //Wait for permission to break data flow if (Mp3ReadRegister(SPI_AICTRL2)==0x2345){ //permission granted ConsoleWrite("->Action"); playingState = PS_CUE_ACTION; } } if (playingState==PS_CUE_ACTION){ if (nSectorsToPlay>128){ sectorAddress.l += 128; //Skip sectors nSectorsToPlay -= 128; //adjust vs1003 song left ConsoleWrite("->Fallback(5)"); playingState = PS_FALLBACK_1; //Sector already in memory still goes. } } if (playingState==PS_REWIND){ //Request to start fast forward Mp3WriteRegister(SPI_AICTRL2, 0x12, 0x34); playingState = PS_REW_WAIT1003; } if (playingState==PS_REW_WAIT1003){ //Wait for permission to break data flow if (1){ if (1 || (Mp3ReadRegister(SPI_AICTRL2)==0x2345)){ //permission granted sectorAddress.l -= 128; nSectorsToPlay += 128; playingState = PS_FALLBACK_1; //Sector already in memory still goes. } } } /* === END OF REWIND / FAST FORWARD FUNCTIONALITY CODE === */ sectorAddress.l++; if (nSectorsToPlay){ /*Do not seek after the last sector*/ PrepareToReadDiskSector(sectorAddress.l); } Mp3SelectData(); dataBufPtr = diskSect.raw.buf; while (dataBufPtr < diskSect.raw.buf+512){ if (!MP3_DREQ){ GREEN_LED = LED_ON; while (!MP3_DREQ){ Mp3DeselectData(); AvailableProcessorTime(); Mp3SelectData(); } } GREEN_LED = LED_OFF; /* Send 32 octets of disk block data to VS10xx */ SPIPutCharWithoutWaiting(*dataBufPtr++); SPIWait(); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIPutChar(*dataBufPtr++); SPIWait(); } SPIWait(); Mp3DeselectData(); } return 0; //OK Exit}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -