ButterflyMP3

vs1001.c

Go to the documentation of this file.
00001 
00033 #include <avr/io.h>
00034 #include <avr/pgmspace.h>
00035 #include "types.h"
00036 #include "delay.h"
00037 #include "vs1001.h"
00038 #include "mmc.h" // for SPI routines
00039 
00040 //
00041 // VS1001 commands
00042 //
00043 #define VS1001_READ     0x03
00044 #define VS1001_WRITE    0x02
00045 
00046 #define write_byte_spi(data) (SpiByte(data))
00047 
00048 /*
00049 uint8 write_byte_spi(uint8 data)
00050 {
00051         outp(data, SPDR);
00052         loop_until_bit_is_set(SPSR, SPIF);    
00053         
00054         return inp(SPDR);
00055 }       
00056 
00057 */
00058 
00059 // used for the sine_test function
00060 const uint8     __attribute__ ((progmem)) SINETESTSTART[8]  = {0x53,0xef,0x6e,0x22,0,0,0,0};
00061 const uint8     __attribute__ ((progmem)) SINETESTSTOP[8]   = {0x45,0x78,0x69,0x74,0,0,0,0};
00062 
00063 
00067 void vs1001_read(uint8 address, uint16 count, uint16 *pData)
00068 {
00069         uint8 i;
00070 
00071 #ifdef VS1000_NEW
00072         SBI( xDCS_PORT, xDCS_PIN );     // xDCS hi
00073 #else
00074         CBI( BSYNC_PORT, BSYNC_PIN );   // byte sync lo
00075 #endif
00076         
00077         CBI( MP3_PORT, MP3_PIN);        // xCS lo
00078         write_byte_spi(VS1001_READ);
00079         write_byte_spi(address);
00080 
00081         while (count--)
00082         {
00083                 *pData = write_byte_spi(0) << 8;
00084                 *pData++ |= write_byte_spi(0);
00085         }
00086 
00087         SBI( MP3_PORT, MP3_PIN);        // xCS hi
00088 
00089         //this is absolutely neccessary!
00090         //delay(5); //wait 5 microseconds after sending data to control port
00091         for (i=0;i<8;i++)
00092                 asm volatile("nop");
00093 
00094 }
00095 
00096 
00097 
00101 void vs1001_write(uint8 address, uint16 count, uint16 *pData)
00102 {
00103         uint8 i;
00104         
00105 #ifdef VS1000_NEW
00106         SBI( xDCS_PORT, xDCS_PIN );     // xDCS hi
00107 #else
00108         CBI( BSYNC_PORT, BSYNC_PIN );   // byte sync lo
00109 #endif  
00110         
00111         CBI( MP3_PORT, MP3_PIN);        // xCS lo
00112         
00113         write_byte_spi(VS1001_WRITE);
00114         write_byte_spi(address);
00115 
00116         while (count--)
00117         {
00118                 write_byte_spi((uint8)((*pData) >> 8));
00119                 write_byte_spi((uint8)*pData);
00120                 pData++;
00121         }
00122         
00123         SBI( MP3_PORT, MP3_PIN);        // xCS hi
00124 
00125         //this is absolutely neccessary!
00126         //delay(5); //wait 5 microseconds after sending data to control port
00127         for (i=0;i<8;i++)
00128                 asm volatile("nop");
00129 }
00130 
00131 
00132 /****************************************************************************
00133 **
00134 ** MPEG Data Stream
00135 **
00136 ****************************************************************************/
00137 
00138 
00139 /* !!! WARNING !!!
00140         
00141 ALL data on the spi lines is read as
00142 input to the MPEG Stream by the vs1001 when :
00143 -the BSYNC line is high and compiled in standard (vs1001 compatability) mode.
00144 -the xDCS line is low in new (VS1002) mode.
00145 
00146 If in New mode 
00147 
00148 */
00149 
00153 inline void vs1001_send_data(unsigned char b)
00154 {
00155         char i;
00156 #ifdef VS1000_NEW
00157         CBI( xDCS_PORT,   xDCS_PIN );           //  XDCS lo
00158 #else
00159         SBI( BSYNC_PORT,   BSYNC_PIN );         // byte sync hi
00160 #endif
00161         //      outp(b, SPDR);                  // send data
00162         SPDR = b;                               // send data
00163         
00164         // release BSYNC before end of byte
00165 #ifndef VS1000_NEW
00166         asm volatile("nop");
00167         asm volatile("nop"); 
00168         asm volatile("nop"); 
00169         CBI( BSYNC_PORT,   BSYNC_PIN );         // byte sync lo
00170 #endif  
00171         // wait for data to be sent
00172         loop_until_bit_is_set(SPSR, SPIF); 
00173         
00174         //release xDCS after byte has been sent
00175 #ifdef VS1000_NEW
00176         SBI( xDCS_PORT,   xDCS_PIN );           // byte XDCS hi
00177 #endif
00178         i = SPDR;                               // clear SPIF
00179         
00180 
00181 }
00182 
00183 
00187 inline void vs1001_send_32(unsigned char *p)
00188 {
00189         int j;
00190 
00191         
00192 #ifdef VS1000_NEW
00193         CBI( xDCS_PORT,   xDCS_PIN );           // xDCS lo
00194 #else
00195         SBI( BSYNC_PORT,   BSYNC_PIN );         // byte sync hi
00196 #endif
00197         for (j=0;j<31;j++) 
00198         {
00199                 SPDR = *p++ ;           // send data
00200                 // wait for data to be sent
00201                 loop_until_bit_is_set(SPSR, SPIF);   
00202         }
00203                 
00204         SPDR = *p++ ;           // send last byte
00205                 
00206 #ifndef VS1000_NEW
00207         // release BSYNC before last bit of last byte.
00208         asm volatile("nop");
00209         asm volatile("nop");
00210         asm volatile("nop"); 
00211         CBI( BSYNC_PORT,   BSYNC_PIN );         // byte sync lo
00212 #endif  
00213         // wait for data to be sent
00214         loop_until_bit_is_set(SPSR, SPIF);   
00215 
00216 #ifdef VS1000_NEW
00217         SBI( xDCS_PORT,   xDCS_PIN );           // xDCS hi
00218 #endif
00219         j = SPDR; // clear SPIF
00220 }
00221 
00222 
00223 
00224 /****************************************************************************
00225 **
00226 ** Init and helper functions
00227 **
00228 ****************************************************************************/
00229 
00230 
00233 void vs1001_init_io(void)
00234 {
00235 #ifdef VS1000_NEW
00236         // setup xDCS (same as pin as BSYNC AFAIK)
00237         SBI( xDCS_DDR , xDCS_PIN );             // pin is output for xDCS 
00238         SBI( xDCS_PORT, xDCS_PIN );             // output High
00239 #else
00240         // setup BSYNC
00241         SBI( BSYNC_DDR , BSYNC_PIN );           // pin is output for BSYNC
00242         CBI( BSYNC_PORT, BSYNC_PIN );           // output low
00243 #endif
00244         // set the MP3/ChipSelect pin hi
00245         SBI( MP3_DDR , MP3_PIN);                // pin output for xCS
00246         SBI( MP3_PORT, MP3_PIN);                // output hi (deselect MP3)
00247 
00248         // set the /Reset pin hi
00249         SBI( RESET_DDR , RESET_PIN);            // pin output 
00250         SBI( RESET_PORT, RESET_PIN);            // output hi
00251 
00252         // Setup DREQ Pin
00253         CBI(DREQ_DDR , DREQ_PIN);               // pin input
00254         CBI(DREQ_PORT, DREQ_PIN);               // no pullup
00255 
00256 }
00257 
00258 
00260 void vs1001_init_chip(void)
00261 {
00262         //we use a hardware reset, works much better 
00263         //than software rest, but makes a click noise.
00264 
00265         Delay(3);
00266         vs1001_reset(HARD_RESET);
00267 
00268         Delay(3);
00269         vs1001_nulls(32);
00270         vs1001_reset(SOFT_RESET);
00271 
00272     vs1001_sine_test();
00273 }
00274 
00275 
00276 
00278 void vs1001_reset(reset_e r)
00279 {
00280 
00281         uint16 buf[2];
00282 
00283         if (r == SOFT_RESET)
00284         {
00285                 
00286         //      Delay(200);             // 200 mS
00287                 SPSR = (0<<SPI2X);                      //set spi to Fosc/4
00288                 
00289                 // set SW reset bit     
00290                 buf[0] = SM_RESET ;
00291                 vs1001_write(SCI_MODE,1,buf);   // set bit 2
00292 
00293                 Delay(2);               // 2 mS
00294 
00295                 while( !((DREQ_PORT) & (1<<DREQ_PIN)) ); //wait for DREQ
00296 
00297 #ifdef VS1000_NEW
00298         buf[0] = SM_SDINEW ; 
00299         vs1001_write(SCI_MODE,1, buf);
00300 #endif
00301         // set CLOCKF for 24.576 MHz
00302                 // change to doubler //nick 7/7/04
00303                 buf[0] = 0x9800;
00304                 vs1001_write(SCI_CLOCKF,1,buf); 
00305 
00306 #ifdef VS1001   
00307                 // Force clock doubler see pg32 of VS10XX appl.notes
00308                 buf[0] = 0x8008;
00309                 vs1001_write(SCI_INT_FCTLH,1,buf);
00310 #endif
00311                 vs1001_nulls(32);
00312             
00313                 SPSR = (1<<SPI2X);                      //set spi to Fosc/2
00314         }
00315         else if (r == HARD_RESET)
00316         {
00317                 CBI(RESET_PORT, RESET_PIN);     // RESET- lo
00318                 Delay(1);       // 1 mS     
00319                 SBI(RESET_PORT, RESET_PIN);     // RESET- hi
00320                 Delay(5);       // 5 mS     
00321         }
00322 }
00323 
00327 void vs1001_nulls(unsigned int nNulls)
00328 {
00329         while (nNulls--)
00330                 vs1001_send_data(0);
00331 }
00332 
00336 void vs_1001_setvolume(unsigned char left, unsigned char right)
00337 {
00338         uint16 buf[2];
00339 
00340         buf[0] = (((uint16)left) << 8) | (uint16)right;
00341 
00342         vs1001_write(SCI_VOL, 1, buf);
00343 }
00344         
00348 void vs1001_sine_test(void)
00349 {
00350     uint16 buf[2];
00351     int i,j ;
00352     
00353     buf[0]=0;
00354     
00355 #ifdef VS1000_NEW
00356 //    • Set New Mode by writing four SCI bytes: 0x2, 0x0, 0x8, 0x20 
00357     buf[0] |= SM_SDINEW ;
00358 #endif
00359 #if defined (VS1011) || defined(VS1053)
00360     buf[0] |= SM_TESTS;
00361 #endif
00362     
00363     vs1001_write(SCI_MODE,1,buf);
00364     
00365     for(j=0; j<5;j++){
00366     //  • Activate the sine test by writing the following eight bytes to SDI: 0x53 0xEF 0x6E 0x22, 0, 0, 0, 0
00367         for (i=0;i<8;i++) {
00368             vs1001_send_data(pgm_read_byte(&SINETESTSTART[i]));   
00369         }  
00370     //  • Wait for example 500 ms. 
00371         Delay(500);
00372                              
00373     //  • Deactivate the sine test by writing to SDI: 0x45 0x78 0x69 0x74. 
00374         for (i=0;i<8;i++){
00375             vs1001_send_data(pgm_read_byte(&SINETESTSTOP[i]));   
00376          }          
00377                              
00378     //  • Wait for example 500 ms. 
00379          Delay(500);                    
00380     }
00381 }
 All Files Functions Variables Typedefs Enumerations Enumerator Defines