/************************************************************ * VS1011E Contorol Library * * 2012/9/12 Add Func: unsigned char Read_SM_CANCEL_bit(void) * Mod. PlayEnd()-> Corresponds to VS1053B * 2012/9/13 Add Func: void PlaySkip(void) ************************************************************/ #include "VS1011.h" #include /************************************* * SPI Read after Write Basic Function **************************************/ BYTE WriteSPI(BYTE output){ MP3_SPI_IF = 0; // Interrupt Flag Clear MP3_SSPBUF = output; // SPI OUT while(!MP3_SPI_IF); // Wait Input return MP3_SSPBUF; // Return to Input Data } /************************************ * VS1011 Command Out Function ************************************/ void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData){ MP3_XDCS_IO = 1; // Cancellation Data Mode while(!MP3_DREQ_IO); // Wait Ready MP3_XCS_IO = 0; // Set Command Mode WriteSPI(0x02); // Specify Write SPI WriteSPI(RegAdrs); // Output Reg Addres WriteSPI(UpData); // Output Upper Byte WriteSPI(LowData); // Output Lower Byte MP3_XCS_IO = 1; // Cancellation Command Mode } /************************************************ * VS1011 Command Out Function (Add Confirmation) *************************************************/ void CmdCheck(BYTE RegAdrs, BYTE UpData, BYTE LowData){ BYTE b1,b2; do{ MP3_XDCS_IO = 1; // Cancellation Data Mode while(!MP3_DREQ_IO); // Wait Ready MP3_XCS_IO = 0; // Set Command Mode WriteSPI(0x02); // Specify Write SPI WriteSPI(RegAdrs); // Output Reg Addres WriteSPI(UpData); // Output Upper Byte WriteSPI(LowData); // Output Lower Byte MP3_XCS_IO = 1; // Cancellation Command Mode while(!MP3_DREQ_IO); // Wait Ready MP3_XCS_IO = 0; // Confirmation Read WriteSPI(0x03); // Reading WriteSPI(RegAdrs); // Specify Reg Addres b1 = WriteSPI(0xFF); // Return UpData b2 = WriteSPI(0xFF); // Return LowData MP3_XCS_IO = 1; }while((b1 != UpData) || (b2 != LowData)); } /********************************* * VS1011 Data Out Function **********************************/ void SendData(BYTE Data){ while(!MP3_DREQ_IO); // Chack DREQ WriteSPI(Data); } /********************************** * Set Volume Level * vRight = Rch Vol * vLeft = Lch Vol * Max = 0dB (Down 0.5dB Step) **********************************/ void SetVolume(BYTE vRight, BYTE vLeft){ Command(0x0B, vRight, vLeft); } /********************************************** * Set Boost Bass Contorol * bass : Bass Gain Renge: 0dB from 15dB * gfreq: Set Fboost: 10Hz Step (0 from 15) ***********************************************/ void SetBassBoost(BYTE bass, BYTE gfreq) { BYTE temp1 = 0; /* Limit Setting Range */ if(bass > 15) bass = 15; if(gfreq > 15) gfreq = 15; /* Mixed 8bit */ temp1 = gfreq; temp1 |= (bass << 4); Command(0x02, 0xFF, temp1); // BASS return; } ////////////////////////////// // Play End Process (VS1011E) ///////////////////////////// /* void PlayEnd(void){ int i; /// TX ZERO Data 2048Byte (Clear Play Buffer) MP3_XDCS_IO = 0; // XDS ON for(i=0; i<2048; i++) SendData(0); // Transmit ZERO Data MP3_XDCS_IO = 1; // XDCS OFF /// End at Soft Reset Command(0x00, 0x08, 0x24); // Transmit SM_RESET while(!MP3_DREQ_IO); // Wait Command End } */ /********************************************* * Read SM_CANCEL bit (Corresponds to VS1053B) *********************************************/ unsigned char Read_SM_CANCEL_bit(void){ unsigned char Read_data_Hi; unsigned char Read_data_Lo; while(!MP3_DREQ_IO); // Wait VS1053 Ready MP3_XCS_IO = 0; // Active CS WriteSPI(0x03); // Read Mode WriteSPI(0x00); // Specify SCI MODE Register Read_data_Hi = WriteSPI(0xFF); // Read Hi Byte Data Read_data_Lo = WriteSPI(0xFF); // Read Lo Byte Data MP3_XCS_IO = 1; return(Read_data_Lo); } /********************************************* * Play End Process (Corresponds to VS1053B) *********************************************/ void PlayEnd(void){ int i; unsigned char read_data; /// TX ZERO Data 2052Byte (Clear Play Buffer) MP3_XDCS_IO = 0; // XDS ON for(i=0; i<2052; i++) SendData(0); // Transmit ZERO Data MP3_XDCS_IO = 1; // XDCS OFF /// Set SM_CANCEL_bit (SCI MODE Reg.) Command(0x00, 0x08, 0x28); // while(!MP3_DREQ_IO); // Wait Command End /// Check SM_CANCEL_bit (MODE_Reg bit3) do { MP3_XDCS_IO = 0; // XDS ON for(i=0; i<32; i++) SendData(0); // Transmit ZERO Data MP3_XDCS_IO = 1; // XDCS OFF read_data = Read_SM_CANCEL_bit(); } while(((read_data) & 0x08) != 0); } /********************************************* * Play Skip Process (Corresponds to VS1053B) *********************************************/ void PlaySkip(void){ int i; /// Set SM_CANCEL_bit (SCI MODE Reg.) Command(0x00, 0x08, 0x28); delay_ms(50); /// Soft Reset Command(0x00, 0x08, 0x24); /// TX ZERO Data 2052Byte (Clear Play Buffer) MP3_XDCS_IO = 0; // XDS ON for(i=0; i<2052; i++) SendData(0); // Transmit ZERO Data MP3_XDCS_IO = 1; // XDCS OFF } /******************************************** * Initialize VS1011 * Set Forward Mode, SDI TEST MODE * If communication error then forever loop *********************************************/ void VS1011_Init(void){ unsigned int val; /*** Initialize VS1011 Port ***/ MP3_XDCS_IO = 1; // DCS is Hi MP3_XCS_IO = 1; // XCS is Hi MP3_XRESET_IO = 0; // XRESET is Lo MP3_XRESET_TRIS = 0; // Valid Output TRIS MP3_DREQ_TRIS = 1; // DREQ PIN is Input MP3_XDCS_TRIS = 0; // XDCS PIN is Output MP3_XCS_TRIS = 0; // XCS PIN is Output MP3_SDI_TRIS = 1; // SDI2 PIN is Input MP3_SDO_TRIS = 0; // SDO2 PIN is Output MP3_SCK_TRIS = 0; // SCK2 PIN is Output /***** Initialize SPI2 ***/ MP3_SPICON1 = 0x003E; // Fixed SPI CLK=4M (CLK= Fosc/4), 8bit mode // Center Sample(SMP=0), Transmit is POS Edge(CKE=1) // MP3_SPICON1 = 0x0020; // Change SPI Speed = 4M -> 7.8k (Fcy(16M-> 4M)/64*8)):Used Debug // MP3_SPICON1 = 0x003D; // SPI CLK=1M -> WAV Play OK (MP3 Play NG) 110211 // MP3_SPICON1 = 0x0029; // SPI CLK=166k -> MP3 Play OK(Lage Noise), WAV Play NG 110216 // MP3_SPICON1 = 0x0037; // SPI CLK=5.3M 110304 MP3_SPICON2 = 0; // NON Frame Mode MP3_SPI_IF = 0; // Clear Interrupt Flag MP3_SPISTATbits.SPIEN = 1; // Enable SPI2 /* Cancellation RESET and Start VS1011 */ delay_ms(50); MP3_XRESET_IO = 1; // Cancellation RESET /* Mode Set */ CmdCheck(0x00, 0x08, 0x20); // Initialize Mode: New Mode, SDI TEST MODE /* Set Clock Doubler */ val = 12288 / 2 + 0x8000; CmdCheck(0x03, (BYTE)(val /256), (BYTE)val); delay_ms(10); } /*************************** * Set Sin Test Mode ****************************/ void VS1011_SineTest(void) { /* Test Mode SQ OUT */ while(!MP3_DREQ_IO); MP3_XDCS_IO = 0; // Start Sine Test WriteSPI(0x53); WriteSPI(0xEF); WriteSPI(0x6E); WriteSPI(0x7D); // 22.050kHz Out is 5kHz WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); MP3_XDCS_IO = 1; } /**************************** * Delay: Unit usec *****************************/ void delay_us(int usec){ usec = (int)(CLOCK*usec)/ 10; while(usec) { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); usec--; } } /*************************** * Delay: Unit msec ****************************/ void delay_ms(int msec){ int i; for(i=0; i< msec; i++) delay_us(1000); }