ButterflyMP3
|
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 }