ButterflyMP3

avrfat16.c

Go to the documentation of this file.
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 }
 All Files Functions Variables Typedefs Enumerations Enumerator Defines