ButterflyMP3
|
00001 00039 #include <avr/io.h> 00040 #include <avr/pgmspace.h> 00041 #include <avr/interrupt.h> 00042 #include "main.h" 00043 #include "types.h" 00044 #include "uart.h" 00045 #include "delay.h" 00046 #include "vs1001.h" 00047 #include "mmc.h" 00048 #include "avrfat16.h" 00049 #include "timer0.h" 00050 #include "button.h" 00051 #include "eeprom.h" 00052 #include "lcdgraphics.h" 00053 #include "power.h" 00054 #include "utils.h" 00055 #include "BCD.h" // for getnumbered song 00056 00057 //#include "testing.h" 00058 00060 const char VERSIONINFO1[] PROGMEM = "ButterflyMP3_sf_net V0.7"; 00062 const char VERSIONINFO2[] PROGMEM = __DATE__ __TIME__ ; 00063 00064 00065 #ifdef NOKIA 00066 extern uint8 fbXY[]; 00067 #endif 00068 00069 // player option variables 00070 uint8 gmusic_vol = DEFAULT_MUSIC_VOLUME; 00071 volatile uint8 gbass_boost =0; 00072 volatile uint8 gFastForward =0; 00073 00074 // player state variables 00075 uint8 gMode =0; 00076 BOOL gLCD_Refresh; 00077 // @TODO: move these into file struct 00078 uint32 gFAT_entry =0; 00079 uint32 gCluster; 00080 uint32 gFileSectorSize; 00081 uint32 gFileSectorsPlayed; 00082 BOOL gFile_good; 00083 char cluster_pos=0; 00084 char buff_pos=16; 00085 00086 //volatile uint16 gBatteryVoltage; ///< last ADC battery Voltage reading 00087 00088 #if FAT_NumberedSong_EN 00089 uint8 gCurrentSongNum=0; 00090 #endif 00091 00092 volatile uint16 gPlayTimeSeconds; 00093 uint8 gDisplayTimeOut=0; 00094 00096 const uint8 __attribute__ ((progmem)) volume_val[10] = {160,128,112, 96, 80, 64, 48, 32, 16, 0}; 00097 00098 // internal Function Prototypes 00099 //uint8 FAT_readRoot(uint32 filenumber); 00100 void flush_decoder(char reset_type); 00101 void cue_file(void); 00102 void streaming (void); 00103 void handle_interface(void); 00104 void update_LCD(void); 00105 void mainTimer(void); 00106 uint8 init_mmc_fat(void); 00107 uint8 handle_mmc(uint8 MMC_present); 00108 00109 /* ..Removed to save space. 00110 void DumpGlobals(void) 00111 { 00112 #ifdef ALPHA 00113 extern volatile signed char gScroll; 00114 extern volatile char gScrollMode; 00115 #endif 00116 00117 UART_Printfu08(gmusic_vol);EOL(); 00118 UART_Printfu08(gbass_boost);EOL(); 00119 UART_Printfu08(gMode);EOL(); 00120 UART_Printfu08(gLCD_Refresh);EOL(); 00121 UART_Printfu08(gFile_good);EOL(); 00122 UART_Printfu08(gDisplayTimeOut);EOL(); 00123 #ifdef ALPHA 00124 UART_Printfu08(gScroll);EOL(); 00125 UART_Printfu08(gScrollMode);EOL(); 00126 #endif 00127 UART_Printfu16(gPlayTimeSeconds);EOL(); 00128 00129 UART_Printfu32(gFAT_entry);EOL(); 00130 UART_Printfu32(gCluster);EOL(); 00131 UART_Printfu32(gFileSectorSize);EOL(); 00132 UART_Printfu32(gFileSectorsPlayed);EOL(); 00133 } 00134 */ 00135 00136 00142 void init_HW(void) 00143 { 00144 // boost IntRC to 8Mhz 00145 //OSCCAL_calibration(); 00146 CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable 00147 CLKPR = (0<<CLKPS1)|(0<<CLKPS0); // set prescaler = 1, Internal RC 8Mhz 00148 00149 // Disable Analog Comparator (power save) 00150 ACSR = (1<<ACD); 00151 00152 // Disable Analog to Digital converter (power save) 00153 //ADCSRA = 0; 00154 00155 // Disable Digital input on PF0-7 (power save) 00156 DIDR1 = 0xFF; 00157 00158 #ifdef PWR_CHK_INTERVAL 00159 Power_Init(); // init power monitoring 00160 // abort power up if battery is low. 00161 if (Power_check()<PWR_MIN_V) { 00162 //Jump to Bootloader 00163 WDTCR = (1<<WDCE) | (1<<WDE); //Enable Watchdog Timer to give reset 00164 while(1); 00165 } 00166 #endif 00167 00168 // setup IO 00169 UART_Init(); // init RS-232 link 00170 /* enable interrupts */ 00171 sei(); 00172 SpiInit(); // init spi pins (mmc & VS1001) 00173 vs1001_init_io(); // init IO pins 00174 vs1001_init_chip(); // Reset Chip 00175 Timer0_Init(); // setup timers for debounce and scroll 00176 Button_Init(); // setup joystick. 00177 LCD_Initialize(); // SETUP lcd 00178 00179 //register timer routine 00180 Timer0_RegisterCallbackFunction(mainTimer); 00181 00182 // Read settings (volume and stuff from eeprom or flash) 00183 load_player_options(); 00184 vs_1001_setvolume(pgm_read_byte(volume_val+gmusic_vol), pgm_read_byte(volume_val+gmusic_vol)); 00185 00186 00187 00188 // say hello on Serial 00189 PRINT("AVR ButterflyMP3 Player "__DATE__" "__TIME__);EOL(); 00190 00191 // set up the FAT variables 00192 FAT_buffer = mmc_sbuf; // 512 byte buffer for sector reads/writes 00193 FAT_scratch = mmc_scratch; 00194 FAT_read = MMC_Read; // pointer to read block function 00195 //FAT_write = MMC_Write;// pointer to write block function 00196 FAT16_entryMAX =-1; 00197 FAT16_entryMIN = 0; 00198 } 00199 00200 00201 00202 void mainTimer(void) 00203 { 00204 static uint16 timeout_count=0; 00205 static uint16 second_timer=TIMER0_TICKSPERSECOND; 00206 #ifdef PWR_CHK_INTERVAL 00207 static uint8 power_timer=PWR_CHK_INTERVAL; 00208 uint16 batteryVoltage; 00209 #endif 00210 extern unsigned char gButtonTimeout; // Variable from "button.c" to prevent button-bouncing 00211 00212 00213 00214 00215 /**************** Button timeout for the button.c, START ****************/ 00216 if(!gButtonTimeout) 00217 { 00218 timeout_count++; 00219 00220 if(timeout_count > BUTTON_TIMEOUT_VALUE) 00221 { 00222 // UART_Printfu08(timeout_count);EOL(); 00223 timeout_count = 0; 00224 // long_timeout_count=0; 00225 gButtonTimeout = TRUE; 00226 } 00227 00228 } 00229 /* 00230 if(!gButtonLongTimeout){ // start the hold down timer 00231 long_timeout_count++; 00232 00233 if(long_timeout_count > 1000){ 00234 gButtonLongTimeout = TRUE; 00235 KEY_SHIFT=TRUE; 00236 KEY_VALID=TRUE; 00237 timeout_count = 0; 00238 long_timeout_count=0; 00239 } 00240 00241 }*/ 00242 00243 /**************** Button timeout for the button.c, END ******************/ 00244 00245 00246 // RA Sewell - other half a second 00247 if (second_timer == TIMER0_TICKSPERSECOND/2) 00248 { 00249 gLCD_Refresh = TRUE; 00250 } 00251 00252 if (!second_timer--){ 00253 second_timer=TIMER0_TICKSPERSECOND; 00254 if (gMode != MODE_PLAY){ 00255 gPowerSaveTimer++; 00256 //UART_Printfu08(gPowerSaveTimer);EOL(); 00257 }else{ 00258 gPlayTimeSeconds++; 00259 } 00260 gLCD_Refresh = TRUE; 00261 00262 #ifdef PWR_CHK_INTERVAL 00263 if ((power_timer--)==0){ 00264 power_timer = PWR_CHK_INTERVAL; 00265 batteryVoltage = Power_check(); 00266 if (batteryVoltage>PWR_GOOD_V){ 00267 //PRINT("Battery GOOD"); 00268 //EOL(); 00269 }else if (batteryVoltage>PWR_LOW_V){ 00270 //PRINT("Battery OK"); 00271 //EOL(); 00272 }else if (batteryVoltage>PWR_MIN_V){ 00273 //PRINT("Battery LOW"); 00274 //EOL(); 00275 }else if (batteryVoltage>PWR_ABS_MIN_V){ 00276 //PRINT("Battery FLAT"); 00277 //EOL(); 00278 }else { 00279 PRINT("LOW BTRY PWR DWN"); 00280 EOL(); 00281 // stop playing and power down 00282 gMode = MODE_PAUSE; 00283 // save everything to eeprom 00284 //save current settings 00285 save_player_options(); 00286 00287 //TODO: Write MMC Serial Number to EEPROM 00288 00289 //write current song to EEPROM 00290 save_player_state(); 00291 00292 gPowerSaveTimer=AUTOPOWEROFF_TIMEOUT; 00293 } 00294 } 00295 #endif 00296 00297 if(gDisplayTimeOut){ 00298 if (gDisplayTimeOut==1){ 00299 #ifdef ALPHA 00300 // Display back to normal 00301 LCD_FileName(TRUE); 00302 #endif 00303 gDisplayTimeOut = 0; 00304 }else{ 00305 // continue the count down 00306 gDisplayTimeOut--; 00307 } 00308 } 00309 00310 } 00311 00312 } 00313 00314 uint8 open_Dir(uint32 dir_lba){ 00315 uint8 files =0; 00316 00317 // display mode on LCD 00318 LCD_Scanning(); 00319 00320 files = FAT_scanDir_lba(dir_lba); 00321 00322 gFAT_entry= FAT16_entryMIN; 00323 cue_file(); // load the file into memory 00324 00325 // Display back to normal 00326 LCD_FileName(TRUE); 00327 00328 //PRINT("1ST FLE @ ");UART_Printfu16(FAT16_entryMIN); 00329 //PRINT(" LST FLE @ ");UART_Printfu16(FAT16_entryMAX);EOL(); 00330 //UART_Printfu08(files);PRINT("files");EOL(); 00331 00332 return files; 00333 } 00334 00341 uint8 restore_player(void) 00342 { 00343 uint8 MMC_present,mode; 00344 uint16 time; 00345 uint32 file,sector,played,dir; 00346 00347 mode=0; file=0; sector=0; played=0; time=0; 00348 00349 // check for an mmc on startup 00350 MMC_present = handle_mmc(FALSE); 00351 00352 if (!MMC_present){ //Can't restore no MMC 00353 //PRINT("NO MMC. Rstre abortd");EOL(); 00354 return MMC_present; 00355 } 00356 00357 // read last song details from EEPROM 00358 load_player_state(&mode,&file,§or,&played,&time,&dir); 00359 00360 // Debug loading info 00361 // PRINT("Loaded from EEPROM");EOL(); 00362 // UART_Printfu08(mode);EOL(); 00363 // UART_Printfu32(file);EOL(); 00364 // UART_Printfu16(time);EOL(); 00365 // UART_Printfu32(sector);EOL(); 00366 // UART_Printfu32(played);EOL(); 00367 // UART_Printfu32(dir);EOL(); 00368 00369 if ((mode != MODE_PAUSE)&&( mode != MODE_IDLE)){ // nothing to restore 00370 //PRINT("MODE != PAUSE");EOL(); 00371 return MMC_present; 00372 } 00373 00374 // todo: check if mmc is same mmc 00375 00376 // check song is available 00377 if ( FAT_getNextSong(file-1,dir) == file){ // song found 00378 open_Dir( dir); 00379 gFAT_entry = file; // select file 00380 cue_file(); // load the file into memory 00381 gMode = mode; 00382 gCluster = sector; // move to last played position 00383 gFileSectorsPlayed = played; 00384 gPlayTimeSeconds = time; 00385 gLCD_Refresh=TRUE; 00386 }else{ // song not found 00387 gFAT_entry =FAT16_entryMIN; 00388 } 00389 return MMC_present; 00390 } 00391 00392 00393 00401 uint8 init_mmc_fat(void) 00402 { 00403 uint8 result; 00404 00405 //DumpGlobals(); 00406 gFAT_entry = 0; 00407 FAT16_entryMIN = 0; 00408 FAT16_entryMAX = -1; 00409 00410 result = MMC_Reset(); // init mmc 00411 if (result) return result; 00412 00413 result = FAT_initFat16(); 00414 if (result) return result; // abort on non-zero reply 00415 00416 UART_Printfu32(FAT16_root_dir_first_sector);EOL(); 00417 00418 result = open_Dir(FAT16_root_dir_first_sector); 00419 00420 //return 0 if files found, 1 if 0 files 00421 return !result; 00422 } 00423 00424 00425 00432 void flush_decoder(char reset_type) 00433 { 00434 uint16 buf[2]; 00435 00436 // reset VS1001 and set clock doubler 00437 vs1001_reset(reset_type); 00438 00439 // send VS1001 settings 00440 vs_1001_setvolume(pgm_read_byte(volume_val+gmusic_vol), pgm_read_byte(volume_val+gmusic_vol)); 00441 00442 vs1001_read(SCI_MODE, 1, buf); 00443 00444 // this whole bass boost thing is wrong.... has it ever worked??? 00445 #ifdef VS1001 00446 buf[0] &= ~SM_MP12; 00447 if (gbass_boost){ 00448 buf[0] |= SM_BASS; 00449 }else{ 00450 buf[0] &= ~SM_BASS; 00451 } 00452 // if (gFastForward){ 00453 // buf[0] != SM_FFWD; 00454 // }else{ 00455 // buf[0] &= ~SM_FFWD; 00456 // } 00457 #endif 00458 00459 #ifdef VS1000_NEW 00460 buf[0] |= SM_SDINEW ; 00461 #endif 00462 vs1001_write(SCI_MODE,1,buf); 00463 00464 if (gFastForward){ 00465 buf[0] = 0x8600; 00466 }else { 00467 buf[0] = 0x9800;} 00468 vs1001_write(SCI_CLOCKF,1,buf); 00469 00470 } 00471 00472 00481 void cue_file(void) 00482 { 00483 uint8 check; 00484 // uint8 temp; 00485 uint32 ID3index; 00486 uint8 i; 00487 uint16 j; 00488 uint32 offset; 00489 uint16 ID3_Bytes; 00490 uint32 ID3_clusters; 00491 uint16 ID3_sectors; 00492 uint32 nextCluster=0; 00493 00494 00495 // read file data and check gFAT_entry is aValid file entry. 00496 check = FAT_readFile(gFAT_entry,FAT16_dir_first_sector); 00497 if (check) return; 00498 00499 if (FAT16_filetype & FILE_TYPE_DIR) return; 00500 /* 00501 //skip or recurse Directories 00502 if (FAT16_filetype & FILE_TYPE_DIR){ 00503 if (RECURSE_DIRECTORIES){ 00504 // scan a new directory.... 00505 // get cluster address from fat entry 00506 gCluster = FAT_scratch[13]; 00507 gCluster <<= 8; 00508 gCluster += FAT_scratch[14]; 00509 gCluster <<= 8; 00510 gCluster += FAT_scratch[15]; 00511 gCluster <<= 8; 00512 gCluster += FAT_scratch[16]; 00513 00514 // check for files and exit on no files(always 2 entries . and ..) 00515 //if (open_Dir(gCluster)<3) { 00516 // return; 00517 //} 00518 00519 nextCluster = FAT_readFile(FAT16_entryMIN,FAT16_dir_first_sector); 00520 00521 }else{ 00522 if (PLAY_NEXT_SONG){ // cue up next song and play it. 00523 nextCluster = FAT_getNextSong(gFAT_entry,FAT16_dir_first_sector); 00524 if(nextCluster){// play next song 00525 gFAT_entry = nextCluster; 00526 gLCD_Refresh=TRUE; 00527 gMode = MODE_PLAY; 00528 }else if(PLAY_REPEAT_ALL){ 00529 gFAT_entry = FAT16_entryMIN; 00530 gLCD_Refresh=TRUE; 00531 gMode = MODE_PLAY; 00532 } 00533 } 00534 } 00535 } 00536 */ 00537 nextCluster=0; 00538 00539 // get first Cluster 00540 FAT_Scratch2Cluster(); 00541 // gCluster = FAT_scratch[13]; 00542 // gCluster <<= 8; 00543 // gCluster += FAT_scratch[14]; 00544 // gCluster <<= 8; 00545 // gCluster += FAT_scratch[15]; 00546 // gCluster <<= 8; 00547 // gCluster += FAT_scratch[16]; 00548 00549 //get fileSize in whole sectors 00550 /* 00551 *((char *)&gFileSectorSize+2) = FAT_scratch[17]; 00552 *((char *)&gFileSectorSize+1)= FAT_scratch[18]; 00553 *((char *)&gFileSectorSize+0) = FAT_scratch[19]; 00554 00555 */ 00556 00557 gFileSectorSize += FAT_scratch[17]; 00558 gFileSectorSize <<= 8; 00559 gFileSectorSize += FAT_scratch[18]; 00560 gFileSectorSize <<= 8; 00561 gFileSectorSize += FAT_scratch[19]; 00562 00563 cluster_pos = 0; 00564 buff_pos = 0; 00565 FAT_readCluster(gCluster,0); 00566 00567 gFile_good = TRUE; 00568 gFileSectorsPlayed = 0; 00569 00570 // Detect and Skip ID3 Info at start of file 00571 // (we ignore tags at end of file) 00572 00573 // Version 1.x 00574 if (FAT_buffer[0] == 'T' && FAT_buffer[1] == 'A' && FAT_buffer[2]=='G') { 00575 //PRINT("ID3 v1 TAG");EOL(); 00576 // jump to byte 128 00577 buff_pos = 4; 00578 }else 00579 00580 // Version 2.x - now with very basic interpretation! 00581 if (FAT_buffer[0] == 'I' && FAT_buffer[1] == 'D' 00582 && FAT_buffer[2]=='3'){ 00583 //PRINT("ID3 v2."); 00584 //UART_Printfu08(FAT_buffer[5]); 00585 //UART_Printfu08(FAT_buffer[4]); 00586 //PRINT(" TAG"); 00587 00588 00589 /* 00590 An ID3v2 tag can be detected with the following pattern: 00591 $49 44 33 yy yy xx zz zz zz zz 00592 Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80. 00593 z = ID3 tag length. 00594 */ 00595 00596 offset = 0; 00597 for(i=6;i<10;i++){ 00598 offset <<= 7; // only shift by 7 as MSB is unused. 00599 offset += FAT_buffer[i]; 00600 } 00601 00602 00603 00604 00605 offset += 10; //include length of header 00606 //UART_Printfu32(offset);PRINT("B");EOL(); 00607 00608 // offset is now equal to the the length of the TAG 00609 ID3index = 10; // skip header 00610 00611 #if ID3_EN 00612 switch (FAT_buffer[3]) 00613 { 00614 case 2: 00615 // Search for song / artist frame and replace long filename with them 00616 while ((ID3index < offset) && (ID3index < 512)) 00617 { 00618 if (FAT_buffer[ID3index] == 'T' && 00619 FAT_buffer[ID3index+1] == 'T' && 00620 FAT_buffer[ID3index+2] == '2') 00621 { 00622 //PRINT(" SONG"); 00623 00624 // For some reason, all strings have a Null at the front of the 00625 // name - I think this indicates the encoding type - we'll assume 00626 // its always 00, string! (this is what the -1 is for) 00627 // other -1 is for the null on the end of the string 00628 for (i=0; (i<FAT_buffer[ID3index+5]-1) && (i<LFN_TITLE_LENGTH-1); i++) 00629 { 00630 FAT16_longfilename[LFN_TITLE_INDEX+i] = FAT_buffer[ID3index+7+i]; 00631 } 00632 FAT16_longfilename[LFN_TITLE_INDEX+i] = '\0'; 00633 00634 // Recalculate string length / add a blank 00635 FAT16_LFNTitleLen = strLen(FAT16_longfilename+LFN_TITLE_INDEX); 00636 00637 // Indicate TITLE found 00638 FAT16_longfilename[LFN_TYPE_INDEX] |= LFN_TYPE_ID3_TITLE; 00639 } 00640 else if (FAT_buffer[ID3index] == 'T' && 00641 FAT_buffer[ID3index+1] == 'P' && 00642 FAT_buffer[ID3index+2] == '1') 00643 { 00644 //PRINT(" ARTIST"); 00645 for (i=0; (i<FAT_buffer[ID3index+5]-1) && (i<LFN_ARTIST_LENGTH-1); i++) 00646 { 00647 FAT16_longfilename[LFN_ARTIST_INDEX+i] = FAT_buffer[ID3index+7+i]; 00648 } 00649 FAT16_longfilename[LFN_ARTIST_INDEX+i] = '\0'; 00650 00651 // Recalculate string length / add a blank 00652 FAT16_LFNArtistLen = strLen(FAT16_longfilename+LFN_ARTIST_INDEX); 00653 00654 // Indicate ARTIST found 00655 FAT16_longfilename[LFN_TYPE_INDEX] |= LFN_TYPE_ID3_ARTIST; 00656 } 00657 00658 // Skip to next ID3 'frame' 00659 ID3index += FAT_buffer[ID3index+5] + 6; 00660 //PRINT(" I:"); 00661 //UART_Printfu08(ID3index); 00662 } 00663 00664 00665 break; 00666 00667 case 3: 00668 case 4: 00669 00670 // Search for song / artist frame and replace long filename with them 00671 while ((ID3index < offset) && (ID3index < 512)) 00672 { 00673 if (FAT_buffer[ID3index] == 'T' && 00674 FAT_buffer[ID3index+1] == 'I' && 00675 FAT_buffer[ID3index+2] == 'T' && 00676 FAT_buffer[ID3index+3] == '2') 00677 { 00678 //PRINT(" SONG"); 00679 00680 // For some reason, all strings have a Null at the front of the 00681 // name - I think this indicates the encoding type - we'll assume 00682 // its always 00, string! (this is what the -1 is for) 00683 // other -1 is for the null on the end of the string 00684 for (i=0; (i<FAT_buffer[ID3index+7]-1) && (i<LFN_TITLE_LENGTH-1); i++) 00685 { 00686 FAT16_longfilename[LFN_TITLE_INDEX+i] = FAT_buffer[ID3index+11+i]; 00687 } 00688 FAT16_longfilename[LFN_TITLE_INDEX+i] = '\0'; 00689 00690 // Recalculate string length / add a blank 00691 FAT16_LFNTitleLen = strLen(FAT16_longfilename+LFN_TITLE_INDEX); 00692 00693 // Indicate TITLE found 00694 FAT16_longfilename[LFN_TYPE_INDEX] |= LFN_TYPE_ID3_TITLE; 00695 } 00696 else if (FAT_buffer[ID3index] == 'T' && 00697 FAT_buffer[ID3index+1] == 'P' && 00698 FAT_buffer[ID3index+2] == 'E' && 00699 FAT_buffer[ID3index+3] == '1') 00700 { 00701 //PRINT(" ARTIST"); 00702 for (i=0; (i<FAT_buffer[ID3index+7]-1) && (i<LFN_ARTIST_LENGTH-1); i++) 00703 { 00704 FAT16_longfilename[LFN_ARTIST_INDEX+i] = FAT_buffer[ID3index+11+i]; 00705 } 00706 FAT16_longfilename[LFN_ARTIST_INDEX+i] = '\0'; 00707 00708 // Recalculate string length / add a blank 00709 FAT16_LFNArtistLen = strLen(FAT16_longfilename+LFN_ARTIST_INDEX); 00710 00711 // Indicate ARTIST found 00712 FAT16_longfilename[LFN_TYPE_INDEX] |= LFN_TYPE_ID3_ARTIST; 00713 } 00714 00715 // Skip to next ID3 'frame' 00716 ID3index += FAT_buffer[ID3index+7] + 10; 00717 //PRINT(" I:"); 00718 //UART_Printfu08(ID3index); 00719 } 00720 00721 00722 break; 00723 default: 00724 ; // Unknown version, do nothing 00725 } 00726 #endif 00727 // skip through to end of ID3 00728 ID3_clusters = (offset/512) / FAT16_sectors_per_cluster; 00729 ID3_sectors = (offset/512) % FAT16_sectors_per_cluster; 00730 ID3_Bytes = offset % 512; 00731 00732 //UART_Printfu32(ID3_clusters);EOL(); 00733 //UART_Printfu16(ID3_sectors);EOL(); 00734 //UART_Printfu16(ID3_Bytes);EOL(); 00735 00736 // find first cluster of actual song 00737 for (j=0;j<ID3_clusters;j++){ 00738 00739 nextCluster = FAT_NextCluster(gCluster); 00740 // UART_Printfu16(j);UART_SendByte(0x09); 00741 // UART_Printfu32(nextCluster);EOL(); 00742 if (nextCluster == 0xffffffff){ 00743 gFile_good = FALSE; 00744 PRINT("EOF: ID3 Tag @ Clstr "); 00745 UART_Printfu32(gCluster); 00746 EOL(); 00747 return; 00748 } 00749 gCluster = nextCluster; 00750 } 00751 00752 00753 // Adjust variables for new position. 00754 gFileSectorsPlayed = (offset / 512); 00755 buff_pos = (ID3_Bytes/32); 00756 cluster_pos = ID3_sectors; 00757 00758 /* 00759 while(FAT_readCluster(gCluster,cluster_pos)){ 00760 MMC_Reset(); 00761 } 00762 */ 00763 00764 /*PRINT("ID3 Tag skipped. First ten bytes of MP3 stream are ... "); 00765 for (i=0;i<10;i++){ 00766 UART_Printfu08(FAT_buffer[i+ID3_Bytes]); 00767 } 00768 EOL(); 00769 */ 00770 j=ID3_Bytes % 32; 00771 if (j){//we need to play(skip;) some bytes 00772 buff_pos++; // skips to next 32 byte chunk of buffer 00773 } 00774 }else{ //dump first 10 bytes of file 00775 /* 00776 for (i=0;i<10;i++){ 00777 UART_Printfu08(FAT_buffer[i]); 00778 } 00779 EOL(); 00780 */ 00781 } 00782 00783 // send params to vs1001k 00784 flush_decoder(SOFT_RESET); 00785 00786 //reset play timer... 00787 gPlayTimeSeconds = 0; 00788 return; 00789 } 00790 00791 00798 void streaming (void) 00799 { 00800 // uint16 c; 00801 uint8 abort=0; 00802 // uint16 tmp=0; 00803 // uint16 state[2]; 00804 uint32 nextfile; 00805 00806 00807 if (!gFile_good) return; // only run if we have a valid file. 00808 00809 if (buff_pos>15) { // we need to get a new sector 00810 00811 gFileSectorsPlayed++; 00812 00813 if (cluster_pos>FAT16_sectors_per_cluster-1){ // need new cluster 00814 cluster_pos=0; 00815 gCluster = FAT_NextCluster(gCluster); 00816 00817 } 00818 00819 if (gCluster == 0xffffffff) { // finished song. on to next ? 00820 00821 // Stop all playing and reset everything 00822 gFile_good = FALSE; 00823 gMode = MODE_STOP; 00824 MMC_Reset(); 00825 flush_decoder(SOFT_RESET); 00826 00827 #if SAMPLEMODE_UNINTERUPTIBLE && SAMPLEMODE_CONTROLOUT_EN 00828 SAMPLEMODE_CONTROLOUT_PORT &= ~(1<<SAMPLEMODE_CONTROLOUT_PIN ) ; // clear sample interupted output 00829 #endif 00830 00831 if (PLAY_NEXT_SONG){ // cue up next song and play it. 00832 nextfile = FAT_getNextSong(gFAT_entry,FAT16_dir_first_sector); 00833 if (RECURSE_DIRECTORIES == 0){ // then skip directories 00834 while (FAT16_filetype & FILE_TYPE_DIR) { 00835 nextfile = FAT_getNextSong(nextfile,FAT16_dir_first_sector); 00836 } 00837 } 00838 if(nextfile){// play next song 00839 gFAT_entry = nextfile; 00840 gLCD_Refresh=TRUE; 00841 cue_file(); 00842 gMode = MODE_PLAY; 00843 }else if(PLAY_REPEAT_ALL){ 00844 gFAT_entry = FAT16_entryMIN; 00845 gLCD_Refresh=TRUE; 00846 cue_file(); 00847 gMode = MODE_PLAY; 00848 } 00849 } 00850 return; 00851 } 00852 00853 // read sector from MMC up to 255 times 00854 while (FAT_readCluster(gCluster,cluster_pos)&& (--abort)){ 00855 MMC_Reset(); // reset if read failed. 00856 } 00857 00858 buff_pos=0; 00859 cluster_pos++; // increment for next time 00860 } 00861 00862 // need to send data to mp3? 00863 // send at most the rest of sector in memory. 00864 while (bit_is_set(DREQ_PORT,DREQ_PIN) && (buff_pos<16)){ 00865 vs1001_send_32(FAT_buffer+(32*buff_pos++)); 00866 } 00867 00868 return; 00869 } 00870 00871 00881 uint8 handle_mmc(uint8 MMC_present) 00882 { 00883 uint16 c; 00884 // uint32 mmc_size=0; 00885 // uint32 nextfile; 00886 00887 #ifdef SW_MMC_IDENTIFY 00888 if (MMC_present == FALSE) { 00889 MMC_Reset(); 00890 } 00891 c = (((MMC_Check() & 0xFF00) == 0) ? TRUE : FALSE); 00892 #else 00893 c = MMC_Detect(); // detect mmc 00894 #endif 00895 00896 if (c && ( MMC_present == FALSE) ){ // mmc just inserted 00897 gPowerSaveTimer=0; // don't time out I just put a card in. 00898 00899 // startup mmc, FAT and find first File 00900 if (!init_mmc_fat()){ // mmc and Fat init okay.. 00901 MMC_present = TRUE; 00902 //mmc_size = MMC_Capacity(); // get capacity in Bytes 00903 //PRINT("MMC :");UART_Printfu32(mmc_size); 00904 //update_LCD(); 00905 gLCD_Refresh=TRUE; 00906 00907 if((FAT16_entryMIN==0) && (FAT16_entryMAX==-1)){// NO SONGS! 00908 gMode= MODE_IDLE; 00909 PRINT("NO MP3");EOL(); 00910 //FAT_tester(); 00911 }else{ 00912 gFAT_entry = FAT16_entryMIN; 00913 gMode= MODE_STOP; 00914 } 00915 00916 } 00917 00918 00919 }else if ((c == FALSE) && MMC_present ){ //mmc just removed 00920 // PRINT("No MMC\t");UART_Printfu16(c);EOL(); 00921 // gFAT_entry=0; // reset FAT to beginning 00922 gMode = MODE_IDLE; 00923 gLCD_Refresh=TRUE; 00924 gFile_good= FALSE; 00925 MMC_present = FALSE; 00926 //update_LCD(); 00927 gPowerSaveTimer=0; //don't time out we're changing cards 00928 } 00929 00930 return MMC_present; 00931 } 00932 00933 00940 void play_track_number( uint8 num ) 00941 { 00942 #if FAT_NumberedSong_EN 00943 uint32 nextfile; 00944 00945 #if SAMPLEMODE_UNINTERUPTIBLE 00946 if (gMode != MODE_PLAY){ 00947 #if SAMPLEMODE_CONTROLOUT_EN 00948 SAMPLEMODE_CONTROLOUT_PORT &= ~(1<<SAMPLEMODE_CONTROLOUT_PIN ) ; // clear sample interupted output 00949 #endif 00950 #endif 00951 00952 nextfile = FAT_getNumberedSong(CHAR2BCD2( num),FAT16_dir_first_sector); 00953 if(nextfile){// get next song 00954 gCurrentSongNum = num; 00955 gFAT_entry = nextfile; 00956 gLCD_Refresh=TRUE; 00957 cue_file(); 00958 gMode = MODE_PLAY; 00959 } 00960 00961 #if SAMPLEMODE_UNINTERUPTIBLE 00962 }else{ // signal sample currently playing 00963 #if SAMPLEMODE_CONTROLOUT_EN 00964 SAMPLEMODE_CONTROLOUT_PORT |= (1<<SAMPLEMODE_CONTROLOUT_PIN) ; //set sample interupted output 00965 #endif 00966 } 00967 #endif 00968 00969 #endif 00970 } 00971 00972 00973 void volume_up(void) 00974 { 00975 gmusic_vol++; 00976 if (gmusic_vol>9) 00977 gmusic_vol=9; 00978 vs_1001_setvolume(pgm_read_byte(volume_val+gmusic_vol), pgm_read_byte(volume_val+gmusic_vol)); 00979 gLCD_Refresh=TRUE; 00980 } 00981 00982 void volume_down(void) 00983 { 00984 gmusic_vol--; 00985 if (gmusic_vol>9) // overflow to 255 00986 gmusic_vol=0; 00987 vs_1001_setvolume(pgm_read_byte(volume_val+gmusic_vol), pgm_read_byte(volume_val+gmusic_vol)); 00988 gLCD_Refresh=TRUE; 00989 } 00990 00991 00997 void handle_interface(void) 00998 { 00999 char c; 01000 uint32 nextfile; 01001 //uint16 buf[2]; 01002 01003 01004 c = getkey(); // get key press 01005 01006 if (c == KEY_NULL && UART_HasChar() ){ // check for serial 01007 c = UART_ReceiveByte(); 01008 switch(c){ 01009 case 'j': c = KEY_PREV; break; 01010 case 'k': c = KEY_MINUS; break; 01011 case 'l': c = KEY_NEXT; break; 01012 case 'i': c = KEY_PLUS; break; 01013 case ' ': c = KEY_ENTER; break; 01014 #ifdef SERIAL_EXTENDED 01015 case '0': case '1': case '2': case '3': case '4': 01016 case '5': case '6': case '7': case '8': case '9': 01017 play_track_number(c-'0'); 01018 c = KEY_NULL; 01019 break; 01020 case '+':volume_up(); c = KEY_NULL; break; 01021 case '-':volume_down(); c = KEY_NULL; break; 01022 case 't':vs1001_sine_test(); c= KEY_NULL;break; 01023 #endif 01024 default : c = KEY_NULL; break; 01025 } 01026 01027 } 01028 01029 if (c != KEY_NULL){ // check for button press 01030 gPowerSaveTimer = 0; // Reset the Auto Power Down timer 01031 01032 PRINT("KEY: ") ;UART_Printfu08(c);EOL(); 01033 if ((c>KEY_JOYSTICKMAX) || SAMPLEMODE_ALLBUTONS){ // just play track #c 01034 play_track_number(c); 01035 }else{ 01036 switch (c){ 01037 case KEY_ENTER : 01038 // change mode. 01039 if (gMode == MODE_PLAY){// currently playing 01040 gMode = MODE_PAUSE; // stop 01041 }else if (gMode == MODE_PAUSE){ 01042 UART_Printfu08(FAT16_filetype); 01043 UART_Printfu08(FILE_TYPE_DIR);EOL(); 01044 if (FAT16_filetype & FILE_TYPE_DIR){ 01045 //PRINT("DIR");EOL(); 01046 01047 // scan a new directory.... 01048 FAT_readFile(gFAT_entry,FAT16_dir_first_sector); 01049 01050 // get cluster address from fat entry 01051 FAT_Scratch2Cluster(); 01052 01053 // check for files and exit on no files(always 2 entries . and ..) 01054 open_Dir(FAT_cluster2lba(gCluster)); 01055 01056 // return; 01057 gFAT_entry = FAT16_entryMIN; 01058 01059 }else{ 01060 gMode = MODE_PLAY; 01061 } 01062 01063 }else if (gMode == MODE_STOP){ 01064 if (FAT16_filetype & FILE_TYPE_DIR){ 01065 // PRINT("DIR");EOL(); 01066 // scan a new directory.... 01067 FAT_readFile(gFAT_entry,FAT16_dir_first_sector); 01068 01069 // get cluster address from fat entry 01070 FAT_Scratch2Cluster(); 01071 01072 // check for files and exit on no files(always 2 entries . and ..) 01073 open_Dir(FAT_cluster2lba(gCluster)); 01074 01075 // return; 01076 gFAT_entry = FAT16_entryMIN; 01077 01078 }else{ 01079 gMode = MODE_PLAY; 01080 cue_file(); 01081 } 01082 01083 }else if ((gMode == MODE_IDLE) && gFile_good){ 01084 gMode = MODE_STOP; 01085 } 01086 01087 // decoder will have shut down if stream has stoped. 01088 // so we need to restart 01089 flush_decoder(SOFT_RESET); 01090 gLCD_Refresh=TRUE; 01091 01092 // TODO: add long short presses. 01093 01094 break; 01095 01096 case KEY_NEXT : // find next file 01097 if (SCAN_JUMPTOSTART && (gFAT_entry==FAT16_entryMAX)){ 01098 gFAT_entry=FAT16_entryMIN; 01099 gLCD_Refresh = TRUE; 01100 cue_file(); 01101 }else{ 01102 nextfile = FAT_getNextSong(gFAT_entry,FAT16_dir_first_sector); 01103 if(nextfile){// get next song 01104 gFAT_entry = nextfile; 01105 gLCD_Refresh=TRUE; 01106 cue_file(); 01107 } 01108 } 01109 break; 01110 01111 case KEY_PREV ://find previous file 01112 #if EXPERIMENTAL_FF==1 01113 gFastForward = !gFastForward; 01114 flush_decoder(SOFT_RESET); 01115 #else 01116 if (SCAN_JUMPTOSTART && (gFAT_entry==FAT16_entryMIN)){ 01117 gFAT_entry=FAT16_entryMAX; 01118 gLCD_Refresh = TRUE; 01119 cue_file(); 01120 }else{ 01121 nextfile = FAT_getPrevSong(gFAT_entry,FAT16_dir_first_sector); 01122 if(nextfile){// play next song 01123 gFAT_entry = nextfile; 01124 gLCD_Refresh = TRUE; 01125 cue_file(); 01126 } 01127 } 01128 #endif 01129 break; 01130 01131 case KEY_PLUS: 01132 //if (gMode == MODE_PAUSE && !(FAT16_filetype & FILE_TYPE_DIR)){ // toggle Bass boost 01133 // gbass_boost = !gbass_boost; 01134 // gLCD_Refresh=TRUE; 01135 //}else 01136 01137 // no mmc? then go to options 01138 if(gMode == MODE_PLAY){ // increase the volume 01139 volume_up(); 01140 01141 }else {//if(((gMode == MODE_PAUSE) || (gMode == MODE_IDLE)) ){ 01142 // && (FAT16_filetype & FILE_TYPE_DIR) ){ 01143 // go up a directory? 01144 01145 // NOTE: gCluster is an lba here not a cluster address 01146 if ((FAT_getParentDir(FAT16_dir_first_sector)) != 0x00){ 01147 gCluster =FAT_getParentDir(FAT16_dir_first_sector); 01148 open_Dir(gCluster); 01149 //PRINT("fdg");EOL(); 01150 gFAT_entry = FAT16_entryMIN; 01151 cue_file(); 01152 } 01153 } 01154 break; 01155 01156 case KEY_MINUS: 01157 if ((gMode == MODE_PAUSE) || (gMode == MODE_IDLE)|| 01158 (gMode == MODE_STOP)){ // Power OFF 01159 Power_off(); 01160 }else { 01161 volume_down(); 01162 } 01163 break; 01164 01165 default : break; 01166 } 01167 } 01168 } 01169 } 01170 01171 01172 01180 void update_LCD(void) 01181 { 01182 uint16 voltage; 01183 uint8 percentage; 01184 static uint8 vol = -1,mode = -1,second = -1; 01185 static uint16 file = -1; 01186 01187 #ifdef ALPHA 01188 if (gLCD_Refresh){ 01189 // LCD_Blank(); // clear LCD 01190 01191 if (gMode == MODE_PLAY){ 01192 if (file!=(uint16) gFAT_entry) LCD_FileName(FALSE); 01193 if (mode!=gMode) LCD_Play(); 01194 if (vol !=gmusic_vol) LCD_Vol(gmusic_vol, gbass_boost); 01195 if (second !=(uint8) gPlayTimeSeconds) LCD_Time(gPlayTimeSeconds); 01196 01197 }else if (gMode == MODE_PAUSE){ 01198 if (file!= (uint16) gFAT_entry) LCD_FileName(FALSE); 01199 if (mode!=gMode) LCD_Pause(); 01200 if (vol !=gmusic_vol) LCD_Vol(gmusic_vol, gbass_boost); 01201 01202 }else if (gMode == MODE_STOP){ 01203 if (file!= (uint16) gFAT_entry) LCD_FileName(FALSE); 01204 if (mode!=gMode) LCD_Stop(); 01205 if (vol !=gmusic_vol) LCD_Vol(gmusic_vol, gbass_boost); 01206 01207 }else if (gMode == MODE_IDLE){ 01208 if (mode!=gMode) { 01209 LCD_Blank(); // clear LCD 01210 LCD_Tester(); // Print the welcome screen and info. 01211 01212 //display battery status 01213 voltage = Power_check(); 01214 01215 percentage = Power_pcnt(voltage); 01216 //UART_Printfu08(percentage);EOL(); 01217 LCD_Battery(percentage); 01218 01219 // revert to filname after seconds 01220 gDisplayTimeOut=(2*STAT_DISPLAY_TIME)+1; 01221 } 01222 } 01223 01224 mode=gMode; 01225 vol=gmusic_vol; 01226 file= (uint16) gFAT_entry; 01227 second =(uint8) gPlayTimeSeconds; 01228 01229 01230 gLCD_Refresh =FALSE; 01231 } 01232 01233 #endif // ALPHA 01234 01235 #ifdef NOKIA 01236 01237 if (gLCD_Refresh){ 01238 01239 if ((mode!=gMode) || (file!=(uint16) gFAT_entry)) LCD_Blank(); // clear LCD 01240 01241 // Always display battery status 01242 voltage = Power_check(); 01243 percentage = Power_pcnt(voltage); 01244 LCD_Battery(percentage); 01245 01246 01247 if (gMode == MODE_PLAY){ 01248 LCD_FileName((file!=(uint16) gFAT_entry)); 01249 LCD_Play(); 01250 LCD_Vol(gmusic_vol, gbass_boost); 01251 LCD_Time(gPlayTimeSeconds); 01252 01253 }else if (gMode == MODE_PAUSE){ 01254 LCD_FileName((file!=(uint16) gFAT_entry)); 01255 LCD_Pause(); 01256 LCD_Vol(gmusic_vol, gbass_boost); 01257 LCD_Time(gPlayTimeSeconds); 01258 01259 }else if (gMode == MODE_STOP){ 01260 LCD_FileName((file!=(uint16) gFAT_entry)); 01261 LCD_Stop(); 01262 LCD_Vol(gmusic_vol, gbass_boost); 01263 01264 }else if (gMode == MODE_IDLE){ 01265 // Print the welcome screen and info. 01266 LCD_Tester(); 01267 01268 // revert to filname after seconds 01269 gDisplayTimeOut=(2*STAT_DISPLAY_TIME)+1; 01270 01271 } 01272 01273 01274 mode=gMode; 01275 vol=gmusic_vol; 01276 file= (uint16) gFAT_entry; 01277 second =(uint8) gPlayTimeSeconds; 01278 01279 01280 gLCD_Refresh =FALSE; 01281 } 01282 #endif // NOKIA 01283 01284 } 01285 01286 01294 int main(void) 01295 { 01296 uint8 MMC_present,j; 01297 01298 //******************************** 01299 //* Initialize 01300 //******************************** 01301 init_HW(); // Do hardware Initialization. 01302 gMode=MODE_IDLE; 01303 gLCD_Refresh=TRUE; 01304 update_LCD(); // make sure NOKIA screen displayed b4 scanning MMC 01305 gLCD_Refresh=TRUE; 01306 MMC_present = restore_player(); // Restore saved position. 01307 gPowerSaveTimer =0; 01308 01309 //******************************** 01310 //* Main Loop 01311 //******************************** 01312 while (1) 01313 { 01314 // check for button press 01315 handle_interface(); 01316 01317 // update lcd 01318 update_LCD(); 01319 01320 // check for MMC removal or insertion. 01321 MMC_present = handle_mmc(MMC_present); 01322 01323 if (MMC_present){ 01324 01325 // check mode ie playing idle sleep nommc 01326 if(gMode == MODE_PLAY){ 01327 // keep streaming if mp3 decoder can take it 01328 // (up to 40 sectors at a time). 01329 j=40; 01330 while (bit_is_set(DREQ_PORT,DREQ_PIN) && j--) 01331 streaming(); 01332 } 01333 else{ 01334 Power_idle(); 01335 #if (AUTOPOWEROFF_TIMEOUT>0) 01336 if (gPowerSaveTimer >= AUTOPOWEROFF_TIMEOUT) 01337 Power_off(); 01338 #endif 01339 } 01340 } 01341 else{ 01342 Power_idle(); 01343 #if (AUTOPOWEROFF_TIMEOUT>0) 01344 if (gPowerSaveTimer >= AUTOPOWEROFF_TIMEOUT) 01345 Power_off(); 01346 #endif 01347 } 01348 01349 } 01350 return 0; 01351 } 01352 01353