ButterflyMP3
|
00001 00036 #include <avr/io.h> 00037 #include <avr/pgmspace.h> 00038 #include <avr/interrupt.h> 00039 00040 00041 #include "types.h" 00042 #include "avrfat16.h" 00043 #include "utils.h" 00044 00045 00046 //void FAT_PrintRecord(uint8 *pRecord); 00047 extern uint32 gCluster; 00048 00049 00050 /*************************************************************************** 00051 * Name: dump_buffer 00052 * Description: Dumps the mmc_sbuf[] to the Uart 00053 * Parameters: <lines> # of lines (16 Bytes) to send starting from 0x00 00054 * Returns: none 00055 ***************************************************************************/ 00056 /* 00057 void dump_buffer(uint8 lines, uint8 buffer[]) 00058 { 00059 uint8 c,i; 00060 for (c=0;c<lines;c++){ 00061 EOL(); 00062 UART_Printfu08(c); 00063 PRINT(": "); 00064 for (i=0;i<16;i++){ 00065 UART_Printfu08(buffer[i+c*16]); 00066 PRINT(" "); 00067 } 00068 for (i=0;i<16;i++){ 00069 if ((buffer[i+c*16] > 31) && (buffer[i+c*16] <= 'z')) 00070 UART_SendByte(buffer[i+c*16]); 00071 else 00072 UART_SendByte('.'); 00073 //PRINT(" "); 00074 } 00075 } 00076 } 00077 */ 00078 00084 uint8 FAT_initFat16(void) 00085 { 00086 uint8 result,type,lba_begin,sectors_per_cluster,number_of_fats; 00087 uint16 bytes_per_sector,number_of_reserved_sectors,BPB_RootEntCnt; 00088 uint16 sectors_per_fat; 00089 00090 // Assume read and write routines have been setup and are not NULL :) 00091 00092 // read the first sector (MBR) 00093 /* 00094 check for 55 AA signature 00095 Read Partition info at 00096 446+4 = type check it's a vfat etc 00097 446+8..11 = LBA Begin 00098 446+12..15 =# of Sectors 00099 */ 00100 result = FAT_read(0); 00101 00102 if (result) 00103 return result; // abort on read error 00104 00105 if (FAT_buffer[510] != 0x55 || FAT_buffer[511] != 0xAA) 00106 return 0xAA; // abort if signature bytes not found in MBR 00107 00108 type = FAT_buffer[PARTITION_START+4]; // get type code for partition one 00109 00110 // TODO: check here for valid MMC types ie FAT16 = 0x 00111 00112 // get start of FAT partition. 00113 // *((uint8 *)&lba_begin+3) = FAT_buffer[PARTITION_START+11]; 00114 // *((uint8 *)&lba_begin+2) = FAT_buffer[PARTITION_START+10]; 00115 // *((uint8 *)&lba_begin+1) = FAT_buffer[PARTITION_START+9]; 00116 // *((uint8 *)&lba_begin+0) = FAT_buffer[PARTITION_START+8]; 00117 00118 lba_begin = FAT_buffer[PARTITION_START+11]; 00119 lba_begin <<=8; 00120 lba_begin += FAT_buffer[PARTITION_START+10]; 00121 lba_begin <<=8; 00122 lba_begin += FAT_buffer[PARTITION_START+9]; 00123 lba_begin <<=8; 00124 lba_begin += FAT_buffer[PARTITION_START+8]; 00125 00126 00127 /* Read Boot Sector at lba Begin 00128 bytes_per_sector at 0x0B 00129 sectors_per_cluster at 0x0D 00130 number_of_reserved_sectors at 0x0E 00131 number_of_fats at 0x10 00132 secters_per_fat at 0x24 00133 root_director_first_sector 0x2c 00134 */ 00135 00136 // read FAT Volume ID 00137 result = FAT_read(lba_begin); 00138 if (result) return result; // abort on read error 00139 00140 //if (FAT_buffer[510] != 0x55 || FAT_buffer[511] != 0xAA) 00141 // return 0xAA; // abort if signature bytes not found in MBR 00142 00143 00144 sectors_per_cluster= FAT_buffer[0x0D]; 00145 PRINT("SECTORS PER CLUSTOR ");UART_Printfu08(sectors_per_cluster);EOL(); 00146 00147 number_of_reserved_sectors = FAT_buffer[ 0x0f]; 00148 number_of_reserved_sectors <<=8; 00149 number_of_reserved_sectors += FAT_buffer[ 0x0e]; 00150 00151 number_of_fats = FAT_buffer[0x10]; 00152 00153 bytes_per_sector = FAT_buffer[0x0c]; 00154 bytes_per_sector <<=8; 00155 bytes_per_sector += FAT_buffer[0x0b]; 00156 00157 PRINT("BYTES PERSECTOR ");UART_Printfu16(bytes_per_sector);EOL(); 00158 00159 // BPB_FATSz16 00160 sectors_per_fat = FAT_buffer[0x17]; 00161 sectors_per_fat <<=8; 00162 sectors_per_fat += FAT_buffer[0x16]; 00163 00164 //BPB_RootEntCnt 00165 BPB_RootEntCnt = FAT_buffer[0x12]; 00166 BPB_RootEntCnt <<=8; 00167 BPB_RootEntCnt += FAT_buffer[0x11]; 00168 00169 00170 /* 00171 FOR FAT32.... 00172 sectors_per_fat = FAT_buffer[0x27]; 00173 sectors_per_fat <<=8; 00174 sectors_per_fat += FAT_buffer[0x26]; 00175 sectors_per_fat <<=8; 00176 sectors_per_fat += FAT_buffer[0x25]; 00177 sectors_per_fat <<=8; 00178 sectors_per_fat += FAT_buffer[0x24]; 00179 00180 root_director_first_sector = FAT_buffer[0x2f]; 00181 root_director_first_sector <<=8; 00182 root_director_first_sector += FAT_buffer[0x2e]; 00183 root_director_first_sector <<=8; 00184 root_director_first_sector += FAT_buffer[0x2d]; 00185 root_director_first_sector <<=8; 00186 root_director_first_sector += FAT_buffer[0x2c]; 00187 */ 00188 00189 // note: FAT16 clusters start after root directory. 00190 FAT16_fat_begin_lba = lba_begin + number_of_reserved_sectors; 00191 FAT16_root_dir_first_sector = FAT16_fat_begin_lba + ( number_of_fats * sectors_per_fat); 00192 FAT16_cluster_begin_lba = FAT16_root_dir_first_sector+ 00193 ((BPB_RootEntCnt*32) + (bytes_per_sector-1))/bytes_per_sector; 00194 // ((BPB_RootEntCnt*32) + (bytes_per_sector))/bytes_per_sector; 00195 FAT16_sectors_per_cluster = sectors_per_cluster; 00196 00197 FAT16_dir_first_sector=FAT16_root_dir_first_sector; 00198 FAT16_parent_dir_first_sector = FAT16_root_dir_first_sector; 00199 00200 return 0; 00201 } 00202 00209 /* REMOVED for space May 2007 00210 uint8 FAT_get_label(uint8 label[]) 00211 { 00212 uint8 result,i,j; 00213 00214 // read root dir 00215 result = FAT_read(FAT16_root_dir_first_sector); 00216 if (result) return result; // abort on fail 00217 00218 // find entry with ATTR_VOLUME_ID 00219 for (i=0;i<512/32;i++){ 00220 if (FAT_buffer[(i*32)+11] == FILE_ATTR_VOLUME_ID){ 00221 for (j=0;j<11;j++) 00222 label[j]=FAT_buffer[(i*32)+j]; 00223 label[11]=0; 00224 return 0;// we have a volume 00225 } 00226 } 00227 00228 return 1; 00229 00230 00231 } 00232 */ 00233 00241 uint8 FAT_readCluster(uint32 cluster, uint8 sector_offset) 00242 { 00243 uint8 result=0; 00244 uint32 lba_addr; 00245 00246 // calculate sector to read 00247 lba_addr = FAT16_cluster_begin_lba + ((cluster-2) * FAT16_sectors_per_cluster); 00248 lba_addr += sector_offset; 00249 00250 result = FAT_read(lba_addr); 00251 00252 return result; 00253 } 00254 00255 00264 uint32 FAT_NextCluster(uint32 cluster) 00265 { 00266 uint8 result=0; 00267 uint32 sector,position,next; 00268 00269 if (cluster ==0 ) cluster = 2; // check for reserved cluster mishap ;) 00270 00271 //sector = cluster / 128; for FAT32 00272 sector = cluster / 256; // for FAT16 00273 00274 result = FAT_read(FAT16_fat_begin_lba+sector); 00275 if (result) return 0; 00276 00277 //position = (cluster - (sector * 128)) * 4; for fat 32 00278 position = (cluster - (sector * 256)) * 2; // for fat 16 00279 00280 /* 00281 // read 4 bytes (FAT32) 00282 next = FAT_buffer[position+3]; 00283 next <<= 8; 00284 next += FAT_buffer[position+2]; 00285 next <<= 8; 00286 next = FAT_buffer[position+1]; 00287 next <<= 8; 00288 next += FAT_buffer[position]; 00289 */ 00290 00291 // read 2 Bytes (FAT16) 00292 next = FAT_buffer[position+1]; 00293 next <<= 8; 00294 next += FAT_buffer[position]; 00295 // *((char *)&next +1) = FAT_buffer[position+1]; 00296 // *((char *)&next +0) = FAT_buffer[position]; 00297 00298 // mask off last 4 bits (FAT32) 00299 // next &= 0x0ffffff; 00300 00301 if (next == 0xffff) next = 0xffffffff; 00302 00303 return next; 00304 } 00305 00306 00322 uint8 FAT_readFile(uint32 filenumber, uint32 dir_first_sector) 00323 { 00324 uint8 flags; 00325 #define FLG_ROOTDIR 0 00326 uint8 result,i,lfn; 00327 uint8 record,lfn_record,nmeChkSm,lfnchksm; 00328 uint8 attrib,saveattrib; 00329 uint16 lfn_entry,fat_entry; // position in buffer of entry 0-512 00330 uint16 clustersadvance,c; 00331 uint32 cluster,lfn_cluster; 00332 uint32 sector,lfn_sector; 00333 // uint16 cluster; 00334 // uint32 size; 00335 flags = 0x00; 00336 cluster =0; 00337 clustersadvance=0; 00338 record = filenumber & 0x0F; // entry number in sector 00339 sector = filenumber >> 4; // sector offset to entry 00340 fat_entry =record << 5; // byte offset of entry 00341 00342 // check if root directory 00343 if (dir_first_sector == FAT16_root_dir_first_sector){ 00344 // Root dir is all contigous sectors 00345 sector += dir_first_sector; 00346 // read the dir 00347 result = FAT_read(sector); 00348 flags |= (1<<FLG_ROOTDIR); 00349 } 00350 else{ // else need to use FAT to find correct cluster 00351 clustersadvance = (sector / FAT16_sectors_per_cluster); 00352 sector %= FAT16_sectors_per_cluster; 00353 cluster = FAT_lba2cluster(dir_first_sector); 00354 00355 // follow the cluster chain 00356 for (c = 0; c < clustersadvance; c++){ 00357 cluster = FAT_NextCluster(cluster); 00358 // UART_Printfu32(cluster);EOL(); 00359 } 00360 00361 // read the dir 00362 result = FAT_read(sector + FAT_cluster2lba(cluster)); 00363 } 00364 00365 if (result) return result; // abort on non-zero reply 00366 00367 // check firstByte 00368 if (FAT_buffer[fat_entry] == 0x00){ // end of directory 00369 FAT16_entryMAX = filenumber; 00370 return 2; 00371 } 00372 else if (FAT_buffer[fat_entry] != 0xe5){ // not used (aka deleted) 00373 00374 // exit on . and .. 00375 if (FAT_buffer[fat_entry]=='.') 00376 return 0x59; 00377 00378 // get the attrib byte 00379 attrib = FAT_buffer[fat_entry+FAT16_LDIR_Attr]; 00380 // PRINT("attr "); UART_Printfu08(attrib); EOL(); 00381 00382 if (attrib & FILE_ATTR_HIDDEN) //keep hidden files hidden 00383 return 0x59; 00384 00385 saveattrib = attrib; // save this for later 00386 00387 if (attrib & (FILE_ATTR_DIRECTORY + FILE_ATTR_ARCHIVE) ){ // entry is normal 8.3 entry 00388 00389 // construct short filename string 00390 for (i=0;i<12;i++){ 00391 FAT_scratch[i] = FAT_buffer[fat_entry+i]; 00392 } 00393 FAT_scratch[11] = '/'; 00394 if (attrib == FILE_TYPE_FILE ){ 00395 FAT_scratch[8] = '.'; 00396 FAT_scratch[9] = FAT_buffer[fat_entry+8]; 00397 FAT_scratch[10] = FAT_buffer[fat_entry+9]; 00398 FAT_scratch[11] = FAT_buffer[fat_entry+10]; 00399 } 00400 FAT_scratch[12] = 0x00; 00401 00402 00403 00404 // accept only *.mp3 files 00405 if((attrib & FILE_ATTR_DIRECTORY )|| 00406 ( FAT_scratch[9] =='M' && 00407 FAT_scratch[10] =='P' && 00408 FAT_scratch[11] =='3')){ 00409 00410 00411 // get Cluster 00412 FAT_scratch[13] = FAT_buffer[(fat_entry)+0x15]; 00413 FAT_scratch[14] = FAT_buffer[(fat_entry)+0x14]; 00414 FAT_scratch[15] = FAT_buffer[(fat_entry)+0x1B]; 00415 FAT_scratch[16] = FAT_buffer[(fat_entry)+0x1A]; 00416 //UART_Printfu08(FAT_scratch[13] = FAT_buffer[(fat_entry)+0x15]); 00417 //UART_Printfu08(FAT_scratch[14] = FAT_buffer[(fat_entry)+0x14]); 00418 //UART_Printfu08(FAT_scratch[15] = FAT_buffer[(fat_entry)+0x1B]); 00419 //UART_Printfu08(FAT_scratch[16] = FAT_buffer[(fat_entry)+0x1A]); 00420 //PRINT("\t"); 00421 00422 //get fileSize 00423 FAT_scratch[17] = FAT_buffer[(fat_entry)+0x1f]; 00424 FAT_scratch[18] = FAT_buffer[(fat_entry)+0x1e]; 00425 FAT_scratch[19] = FAT_buffer[(fat_entry)+0x1d]; 00426 FAT_scratch[20] = FAT_buffer[(fat_entry)+0x1c]; 00427 // UART_Printfu08(FAT_scratch[17] = FAT_buffer[(fat_entry)+0x1f]); 00428 // UART_Printfu08(FAT_scratch[18] = FAT_buffer[(fat_entry)+0x1e]); 00429 // UART_Printfu08(FAT_scratch[19] = FAT_buffer[(fat_entry)+0x1d]); 00430 // UART_Printfu08(FAT_scratch[20] = FAT_buffer[(fat_entry)+0x1c]); 00431 00432 // 00433 // Do Long Filename entries.... 00434 00435 //checksum of name for long entries.. 00436 nmeChkSm=FAT_ChkSum(FAT_buffer+fat_entry); 00437 00438 lfn_record = record; 00439 lfn_sector = sector; 00440 lfn_entry = lfn_record << 5; 00441 lfn_cluster = cluster; 00442 00443 // if we are in root sector is lba 00444 // so we can go back as many sectors as we need 00445 00446 do{ 00447 // look at previous FAT entry 00448 if (lfn_record > 0){ 00449 lfn_record--; 00450 }else{ 00451 if (lfn_sector > 0) { 00452 lfn_sector--; 00453 00454 if (flags & (1<<FLG_ROOTDIR)){ 00455 result = FAT_read(lfn_sector); 00456 }else{ 00457 result = FAT_read(lfn_sector+FAT_cluster2lba(lfn_cluster)); 00458 } 00459 00460 if (result){ // abort on non-zero reply 00461 PRINT("ERR RD SCTR"); 00462 break; 00463 } 00464 00465 lfn_record = 0x0F;// 15 records per sector FAT16 00466 00467 }else{ // run out of sectors get prev cluster 00468 // should only happen on non root dir. 00469 00470 lfn_cluster = FAT_lba2cluster(dir_first_sector); 00471 00472 // follow the cluster chain to 1 less cluster 00473 // than berfore 00474 for (c = 0; c < --clustersadvance; c++){ 00475 lfn_cluster = FAT_NextCluster(lfn_cluster); 00476 } 00477 00478 // set to last sector in cluster 00479 lfn_sector = FAT16_sectors_per_cluster-1; 00480 lfn_record = 0x0F;// 15 records per sector FAT16 00481 00482 result=FAT_read(lfn_sector+ FAT_cluster2lba(lfn_cluster)); 00483 if (result){ // abort on non-zero reply 00484 PRINT("ERR RD SCTR"); 00485 break; 00486 } 00487 00488 00489 } 00490 } 00491 lfn_entry = lfn_record << 5; 00492 00493 // dump record for debugging 00494 //FAT_PrintRecord(FAT_buffer+lfn_entry);EOL(); 00495 00496 // get the attrib byte 00497 attrib = FAT_buffer[lfn_entry+FAT16_LDIR_Attr]; 00498 00499 //exit if no LFN entry found 00500 if (!(attrib & FILE_ATTR_LFN_TEXT)){ 00501 PRINT("no LFN "); 00502 UART_Printfu08(attrib); 00503 EOL(); 00504 break; 00505 } 00506 00507 //get the chksm 00508 lfnchksm = FAT_buffer[lfn_entry+FAT16_LDIR_Chksum]; 00509 00510 // exit if ChkSum doesn't Match 00511 if (lfnchksm != nmeChkSm){ 00512 PRINT("CkSm err"); 00513 UART_Printfu08(nmeChkSm); 00514 UART_Printfu08(lfnchksm); 00515 EOL(); 00516 return 59; 00517 break; 00518 } 00519 00520 //look at order, select lfn section 00521 lfn = ((FAT_buffer[lfn_entry+FAT16_LDIR_Ord] & FILE_ATTR_LFN_MASK)-1) *13; 00522 // UART_Printfu08(FAT_buffer[lfn_entry]); 00523 00524 if (lfn < LFN_BUFFER_LENGTH-13) // Only allow 208 byte max LFNs 00525 { 00526 // note: only look at lower byte of unicode text. 00527 FAT16_longfilename[13+lfn] = 0x00; 00528 FAT16_longfilename[12+lfn] = FAT_buffer[lfn_entry+0x1e]; 00529 FAT16_longfilename[11+lfn] = FAT_buffer[lfn_entry+0x1c]; 00530 FAT16_longfilename[10+lfn] = FAT_buffer[lfn_entry+0x18]; 00531 FAT16_longfilename[9+lfn] = FAT_buffer[lfn_entry+0x16]; 00532 FAT16_longfilename[8+lfn] = FAT_buffer[lfn_entry+0x14]; 00533 FAT16_longfilename[7+lfn] = FAT_buffer[lfn_entry+0x12]; 00534 FAT16_longfilename[6+lfn] = FAT_buffer[lfn_entry+0x10]; 00535 FAT16_longfilename[5+lfn] = FAT_buffer[lfn_entry+0x0e]; 00536 FAT16_longfilename[4+lfn] = FAT_buffer[lfn_entry+0x09]; 00537 FAT16_longfilename[3+lfn] = FAT_buffer[lfn_entry+0x07]; 00538 FAT16_longfilename[2+lfn] = FAT_buffer[lfn_entry+0x05]; 00539 FAT16_longfilename[1+lfn] = FAT_buffer[lfn_entry+0x03]; 00540 FAT16_longfilename[lfn] = FAT_buffer[lfn_entry+0x01]; 00541 } 00542 00543 // test to see if we need to keep looking 00544 }while(FAT_buffer[lfn_entry] < FILE_ATTR_LFN_MASK); // not last entry 00545 00546 00547 // check if we made it through all entries 00548 if (FAT_buffer[lfn_entry] < FILE_ATTR_LFN_MASK){ 00549 // use short name 00550 for (i=0;i<13;i++){ 00551 FAT16_longfilename[i]=FAT_scratch[i]; 00552 } 00553 } 00554 /* 00555 if (lfn_sector != sector) {// re read original FAT sector if changed 00556 result = FAT_read(FAT16_root_dir_first_sector+sector); 00557 if (result) return result; // abort on non-zero reply 00558 } 00559 */ 00560 00561 //PRINT("\t"); 00562 //UART_Printfu32(record+(sector<<4));EOL(); 00563 //UART_Puts(FAT16_longfilename);EOL(); 00564 00565 00566 // RA Sewell - for ID3 tags and scrolling name on NOKIA 00567 FAT16_LFNTitleLen = strLen(FAT16_longfilename); 00568 FAT16_longfilename[LFN_TYPE_INDEX] = LFN_TYPE_FILENAME; 00569 00570 // prefix directories with a slash 00571 if (saveattrib & FILE_TYPE_DIR){ 00572 if (FAT16_LFNTitleLen<LFN_BUFFER_LENGTH){ 00573 FAT16_LFNTitleLen++; 00574 } 00575 for (i=LFN_BUFFER_LENGTH;i>0;i--){ 00576 FAT16_longfilename[i] = FAT16_longfilename[i-1] ; 00577 } 00578 FAT16_longfilename[0] = '/'; 00579 if (FAT16_LFNTitleLen<LFN_BUFFER_LENGTH){ 00580 FAT16_LFNTitleLen++; 00581 } 00582 FAT16_longfilename[FAT16_LFNTitleLen-1] = '/'; 00583 00584 } 00585 00586 // don't show dotfiles like .temp and .Trash, etc. 00587 if (FAT16_longfilename[0]=='.') 00588 return 0x59; 00589 00590 FAT16_filetype = saveattrib; 00591 00592 //dump_buffer(32,FAT_buffer); 00593 return 0x00; 00594 } 00595 } 00596 00597 00598 } 00599 00600 return 0x59; 00601 } 00602 00612 //uint8 FAT_readRoot(uint32 filenumber) 00613 //{ 00614 // return FAT_readFile(filenumber,FAT16_root_dir_first_sector); 00615 //} 00616 00617 00627 uint32 FAT_getNextSong(uint32 filenumber,uint32 dir_lba){ 00628 uint16 i; 00629 uint8 result=0; 00630 //uint32 nextfile; 00631 00632 if (filenumber < FAT16_entryMAX){ 00633 filenumber++; 00634 00635 // find next valid FAT entry 00636 i=1023;// time out after 1023 entries 00637 while ( (i--) && ((result = FAT_readFile(filenumber++,dir_lba))== 0x59) ); 00638 00639 //dump_buffer(32,FAT_buffer); 00640 // read last FAT entry if valid 00641 if (i && (result==0) ){ 00642 filenumber--; 00643 // PRINT("File #");UART_Printfu16(filenumber); EOL(); 00644 return filenumber; 00645 } 00646 } 00647 return 0; 00648 00649 } 00650 00651 00660 uint32 FAT_getPrevSong(uint32 filenumber,uint32 dir_lba){ 00661 uint16 i; 00662 uint8 result=0; 00663 00664 if (filenumber>FAT16_entryMIN){ 00665 filenumber--; 00666 00667 // find previous valid FAT entry 00668 i=1023; 00669 while ( (filenumber>0) && (i--) && ((result = FAT_readFile(filenumber--,dir_lba))== 0x59) ); 00670 00671 //set if valid 00672 if ((result==0) && i && filenumber){ 00673 filenumber++; 00674 // PRINT("File #");UART_Printfu16(filenumber); EOL(); 00675 return filenumber; 00676 } 00677 } 00678 00679 // return 0 if no new file found. 00680 return 0; 00681 } 00682 00697 uint32 FAT_getNumberedSong(char songNumber,uint32 dir_lba) 00698 { 00699 #if FAT_NumberedSong_EN 00700 uint16 i=1; 00701 uint8 result=0; 00702 uint8 found=0; 00703 uint32 filenumber; 00704 00705 00706 filenumber = FAT16_entryMIN; 00707 00708 while (i && found==0 && (filenumber <= FAT16_entryMAX)) 00709 { 00710 // find next valid FAT entry 00711 i=1023;// time out after 1023 entries 00712 while ( (i--) && ((result = FAT_readFile(filenumber++,dir_lba))== 0x59) ); 00713 00714 //dump_buffer(32,FAT_buffer); 00715 // read last FAT entry if valid 00716 if (i && (result==0) ) // we have a possible file 00717 { 00718 00719 //check the name (first two chars only) 00720 if ( (((songNumber & 0x0F) +'0') == FAT16_longfilename[1]) && 00721 (((songNumber >> 04) + '0') == FAT16_longfilename[0] )) 00722 { 00723 PRINT("FOUND :");UART_Puts(FAT16_longfilename);EOL(); 00724 filenumber--; 00725 return filenumber; 00726 } 00727 } 00728 00729 } 00730 PRINT("NOT FOUND :");UART_Printfu08(songNumber);EOL(); 00731 #endif 00732 return 0; 00733 } 00734 00735 00748 uint8 FAT_ChkSum(uint8 *pFcbName) 00749 { 00750 uint8 FcbNameLen; 00751 uint8 Sum; 00752 00753 Sum=0; 00754 for(FcbNameLen=11;FcbNameLen!=0;FcbNameLen--){ 00755 //NOTE:The operation is an unsignedchar rotate right 00756 Sum=((Sum&1)?0x80:0)+(Sum>>1)+*pFcbName++; 00757 00758 } 00759 00760 return(Sum); 00761 } 00762 00763 00764 /* 00765 void FAT_PrintRecord(uint8 *pRecord) 00766 { 00767 uint8 i; 00768 for (i=0;i<32;i++){ 00769 UART_Printfu08(*pRecord++); 00770 } 00771 EOL(); 00772 for (i=0;i<32;i++){ 00773 UART_SendByte(*pRecord++); 00774 } 00775 EOL(); 00776 }*/ 00777 00786 uint32 FAT_cluster2lba(uint32 cluster) 00787 { 00788 uint32 lba_addr; 00789 00790 // calculate sector to read 00791 lba_addr = FAT16_cluster_begin_lba + ((cluster-2) * FAT16_sectors_per_cluster); 00792 //UART_Printfu32(lba_addr);EOL(); 00793 00794 return lba_addr; 00795 } 00796 00805 uint32 FAT_lba2cluster(uint32 lba_addr) 00806 { 00807 uint32 cluster; 00808 00809 cluster = 2+((lba_addr-FAT16_cluster_begin_lba)/FAT16_sectors_per_cluster); 00810 00811 return cluster; 00812 } 00813 00814 00823 uint8 FAT_scanDir_lba(uint32 lba_addr) 00824 { 00825 uint8 files=0; 00826 uint32 file=-1,nextfile; 00827 uint32 saveMin,saveMax; 00828 00829 // ignore last dirs file max 00830 saveMax = FAT16_entryMAX; 00831 FAT16_entryMAX = 0xffff; 00832 00833 // get first good file 00834 saveMin = FAT16_entryMIN; 00835 FAT16_entryMIN = FAT_getNextSong(0,lba_addr); 00836 00837 //scan directory and get max File Entry. 00838 nextfile = FAT16_entryMIN; 00839 while ( nextfile ){ 00840 file = nextfile; 00841 files++; 00842 nextfile = FAT_getNextSong(file,lba_addr); 00843 } 00844 00845 if (files){ // then set working directory 00846 FAT16_entryMAX =file; // set to last valid MP3 00847 FAT16_parent_dir_first_sector = FAT16_dir_first_sector; 00848 FAT16_dir_first_sector = lba_addr; 00849 }else{ 00850 FAT16_entryMIN = saveMin; 00851 FAT16_entryMAX = saveMax; 00852 } 00853 00854 return files; 00855 } 00856 00857 00867 uint32 FAT_getParentDir(uint32 lba_addr) 00868 { 00869 uint8 result,record,fat_entry; 00870 //uint8 *p; 00871 00872 uint32 lba; 00873 00874 // no parent from the root directory 00875 if (lba_addr == FAT16_root_dir_first_sector) return 0; 00876 00877 00878 // read the dir 00879 result = FAT_read(lba_addr); 00880 if (result) return result; // abort on non-zero reply 00881 00882 //dump_buffer(6,FAT_buffer); 00883 //UART_Printfu08(FAT_buffer[fat_entry]); 00884 //UART_Printfu08(FAT_buffer[fat_entry+1]); 00885 00886 // get second entry in directory 00887 record = 0x01; 00888 fat_entry = 0x20; 00889 00890 if (FAT_buffer[fat_entry]!='.' &&FAT_buffer[fat_entry+1]!='.') return 0; 00891 00892 // get Cluster 00893 /* 00894 UART_Printfu08(FAT_scratch[13] = FAT_buffer[(fat_entry)+0x15]); 00895 UART_Printfu08(FAT_scratch[14] = FAT_buffer[(fat_entry)+0x14]); 00896 UART_Printfu08(FAT_scratch[15] = FAT_buffer[(fat_entry)+0x1B]); 00897 UART_Printfu08(FAT_scratch[16] = FAT_buffer[(fat_entry)+0x1A]); 00898 EOL(); 00899 */ 00900 00901 // this should be quicker but... 00902 // lba = 0; 00903 // *((char *)&lba + 3) = FAT_buffer[(fat_entry)+0x15]; 00904 // *((char *)&lba + 2) = FAT_buffer[(fat_entry)+0x14]; 00905 // *((char *)&lba + 1) = FAT_buffer[(fat_entry)+0x1B]; 00906 // *((char *)&lba + 0) = FAT_buffer[(fat_entry)+0x1A]; 00907 00908 // this method comnpiles smaller ?!?? 00909 lba = FAT_buffer[(fat_entry)+0x15]; 00910 lba <<= 8; 00911 lba += FAT_buffer[(fat_entry)+0x14]; 00912 lba <<= 8; 00913 lba += FAT_buffer[(fat_entry)+0x1B]; 00914 lba <<= 8; 00915 lba += FAT_buffer[(fat_entry)+0x1A]; 00916 00917 00918 // if its zero then set to root directory 00919 if (lba == 0) { 00920 lba = FAT16_root_dir_first_sector; 00921 }else{ 00922 lba = FAT_cluster2lba(lba); 00923 } 00924 00925 return lba; 00926 } 00927 00928 00935 void FAT_Scratch2Cluster(){ 00936 00937 // copy the bytes from the scratch pad into the varible 00938 *((char *)&gCluster + 0) = FAT_scratch[16]; 00939 *((char *)&gCluster + 1) = FAT_scratch[15]; 00940 *((char *)&gCluster + 2) = FAT_scratch[14]; 00941 *((char *)&gCluster + 3) = FAT_scratch[13]; 00942 00943 00944 }