00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <avr/io.h>
00027 #include <avr/pgmspace.h>
00028 #include <string.h>
00029
00030 #include "ata.h"
00031 #include "rprintf.h"
00032 #include "debug.h"
00033
00034 #include "fat.h"
00035 #include "fatconf.h"
00036
00037
00038
00039 unsigned char *SectorBuffer = (unsigned char *) FAT_SECTOR_BUFFER_ADDR;
00040 unsigned char *FileNameBuffer = (unsigned char *) FAT_FILENAME_BUFFER_ADDR;
00041 unsigned char *PathNameBuffer = (unsigned char *) FAT_PATHNAME_BUFFER_ADDR;
00042
00043
00044 struct partrecord PartInfo;
00045 unsigned char Fat32Enabled;
00046 unsigned long FirstDataSector;
00047 unsigned short BytesPerSector;
00048 unsigned short SectorsPerCluster;
00049 unsigned long FirstFATSector;
00050 unsigned long RootDirStartCluster;
00051
00052
00053 unsigned long CurrentDirStartCluster;
00054 struct FileInfoStruct FileInfo;
00055 unsigned long FatInCache = 0;
00056
00057
00058
00059
00060
00061
00062 unsigned long fatClustToSect(unsigned long clust)
00063 {
00064 return ((clust-2) * SectorsPerCluster) + FirstDataSector;
00065 }
00066
00067 unsigned int fatClusterSize(void)
00068 {
00069
00070 return SectorsPerCluster;
00071 }
00072
00073 unsigned char fatInit( unsigned char device)
00074 {
00075
00076 struct bpb710 *bpb;
00077
00078
00079
00080 ataReadSectors(DRIVE0, 0, 1, SectorBuffer);
00081
00082
00083 PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart);
00084
00085
00086
00087
00088 ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
00089 bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;
00090
00091
00092 FirstDataSector = PartInfo.prStartLBA;
00093 if(bpb->bpbFATsecs)
00094 {
00095
00096 FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
00097 }
00098 else
00099 {
00100
00101 FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
00102 }
00103 SectorsPerCluster = bpb->bpbSecPerClust;
00104 BytesPerSector = bpb->bpbBytesPerSec;
00105 FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
00106
00107 switch (PartInfo.prPartType)
00108 {
00109 case PART_TYPE_DOSFAT16:
00110 case PART_TYPE_FAT16:
00111 case PART_TYPE_FAT16LBA:
00112
00113 RootDirStartCluster = CLUST_FIRST;
00114
00115
00116 Fat32Enabled = FALSE;
00117 break;
00118 case PART_TYPE_FAT32LBA:
00119 case PART_TYPE_FAT32:
00120
00121 RootDirStartCluster = bpb->bpbRootClust;
00122
00123
00124 Fat32Enabled = TRUE;
00125 break;
00126 default:
00127 rprintfProgStrM("Found: No Partition!\r\n");
00128
00129 break;
00130 }
00131
00132
00133 CurrentDirStartCluster = RootDirStartCluster;
00134 PathNameBuffer[0] = '\\';
00135 PathNameBuffer[1] = 0;
00136
00137
00138
00139 #ifdef DEBUG_FAT
00140 switch (PartInfo.prPartType)
00141 {
00142 case PART_TYPE_DOSFAT16:
00143 rprintfProgStrM("Found: DOSFAT 16\r\n");
00144 break;
00145 case PART_TYPE_FAT16:
00146 rprintfProgStrM("Found: FAT16\r\n");
00147 break;
00148 case PART_TYPE_FAT16LBA:
00149 rprintfProgStrM("Found: FAT16 LBA\r\n");
00150 break;
00151 case PART_TYPE_FAT32LBA:
00152 rprintfProgStrM("Found: FAT32 LBA\r\n");
00153 break;
00154 case PART_TYPE_FAT32:
00155 rprintfProgStrM("Found: FAT32\r\n");
00156
00157 break;
00158 default:
00159 rprintfProgStrM("Found: No Partition!\r\n");
00160
00161 break;
00162 }
00163
00164 rprintfProgStrM("First sector : "); rprintfu32(PartInfo.prStartLBA); rprintfCRLF();
00165 rprintfProgStrM("Size : "); rprintfu32(PartInfo.prSize); rprintfCRLF();
00166 rprintfProgStrM("bytes/sector : "); rprintfu16(bpb->bpbBytesPerSec); rprintfCRLF();
00167 rprintfProgStrM("sectors/cluster : "); rprintfu08(bpb->bpbSecPerClust); rprintfCRLF();
00168 rprintfProgStrM("reserved sectors: "); rprintfu16(bpb->bpbResSectors); rprintfCRLF();
00169 rprintfProgStrM("FatSectors : "); rprintfu16(bpb->bpbFATsecs); rprintfCRLF();
00170 rprintfProgStrM("BigFatSectors : "); rprintfu32(bpb->bpbBigFATsecs); rprintfCRLF();
00171 rprintfProgStrM("Number of Fats : "); rprintfu08(bpb->bpbFATs); rprintfCRLF();
00172 rprintfProgStrM("First Fat Sector: "); rprintfu32(FirstFATSector); rprintfCRLF();
00173 rprintfProgStrM("First Data Sect : "); rprintfu32(FirstDataSector); rprintfCRLF();
00174 rprintfProgStrM("RootDirStartClus: "); rprintfu32(RootDirStartCluster); rprintfCRLF();
00175 #endif
00176
00177 return 0;
00178 }
00179
00180
00181
00182 unsigned char fatGetDirEntry(unsigned short entry)
00183 {
00184 unsigned long sector;
00185 struct direntry *de = 0;
00186 struct winentry *we;
00187 unsigned char haveLongNameEntry;
00188 unsigned char gotEntry;
00189 unsigned short b;
00190 int i,index;
00191 char *fnbPtr;
00192 unsigned short entrycount = 0;
00193
00194
00195 sector = fatClustToSect(CurrentDirStartCluster);
00196
00197 haveLongNameEntry = 0;
00198 gotEntry = 0;
00199
00200 index = 16;
00201
00202
00203 while(1)
00204 {
00205 if(index == 16)
00206 {
00207 ataReadSectors( DRIVE0, sector++, 1, SectorBuffer);
00208 de = (struct direntry *) SectorBuffer;
00209 index = 0;
00210 }
00211
00212
00213 if(de->deName[0] == 0x00)
00214 {
00215
00216 gotEntry = 0;
00217 break;
00218 }
00219 else if(de->deName[0] == 0xE5)
00220 {
00221
00222
00223 }
00224 else
00225 {
00226
00227
00228 if(de->deAttributes == ATTR_LONG_FILENAME)
00229 {
00230
00231
00232 we = (struct winentry *) de;
00233
00234 b = WIN_ENTRY_CHARS*( (we->weCnt-1) & 0x0f);
00235 fnbPtr = &FileNameBuffer[b];
00236 for (i=0;i<5;i++) *fnbPtr++ = we->wePart1[i*2];
00237 for (i=0;i<6;i++) *fnbPtr++ = we->wePart2[i*2];
00238 for (i=0;i<2;i++) *fnbPtr++ = we->wePart3[i*2];
00239 if (we->weCnt & WIN_LAST) *fnbPtr = 0;
00240 if ((we->weCnt & 0x0f) == 1) haveLongNameEntry = 1;
00241 }
00242 else
00243 {
00244
00245
00246
00247
00248 if(haveLongNameEntry)
00249 {
00250
00251 if(entrycount == entry)
00252 {
00253
00254 gotEntry = 1;
00255 break;
00256 }
00257
00258 haveLongNameEntry = 0;
00259 entrycount++;
00260 }
00261 else
00262 {
00263
00264
00265 fnbPtr = FileNameBuffer;
00266 for (i=0;i<8;i++) *fnbPtr++ = de->deName[i];
00267 *fnbPtr++ = '.';
00268 for (i=0;i<3;i++) *fnbPtr++ = de->deExtension[i];
00269 *fnbPtr = 0;
00270
00271 if(entrycount == entry)
00272 {
00273
00274 gotEntry = 1;
00275 break;
00276 }
00277
00278 entrycount++;
00279 }
00280 }
00281 }
00282
00283 de++;
00284
00285 index++;
00286 }
00287
00288
00289
00290 FileInfo.StartCluster = (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
00291
00292
00293 FileInfo.Size = de->deFileSize;
00294
00295 FileInfo.Attr = de->deAttributes;
00296
00297 FileInfo.CreateTime = de->deCTime[0] | de->deCTime[1]<<8;
00298
00299 FileInfo.CreateTime = de->deCDate[0] | de->deCDate[1]<<8;
00300
00301 return gotEntry;
00302 }
00303
00304
00305 unsigned char fatChangeDirectory(unsigned short entry)
00306 {
00307
00308 if( fatGetDirEntry(entry) )
00309 {
00310
00311 if(FileInfo.Attr & ATTR_DIRECTORY)
00312 {
00313
00314
00315 if(FileInfo.StartCluster)
00316 {
00317
00318 CurrentDirStartCluster = FileInfo.StartCluster;
00319 }
00320 else
00321 {
00322
00323
00324
00325 CurrentDirStartCluster = RootDirStartCluster;
00326 }
00327
00328
00329 strcat(PathNameBuffer, FileNameBuffer);
00330 strcat(PathNameBuffer, "\\");
00331
00332 return TRUE;
00333 }
00334 else
00335 {
00336
00337 return FALSE;
00338 }
00339 }
00340 else
00341 {
00342
00343 return FALSE;
00344 }
00345 }
00346
00347 void fatPrintDirEntry(void)
00348 {
00349
00350
00351 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_MONTH_MASK)>>DD_MONTH_SHIFT );
00352 rprintfChar('/');
00353 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_DAY_MASK)>>DD_DAY_SHIFT );
00354 rprintfChar('/');
00355 rprintfNum(10, 4, FALSE, '0', (FileInfo.CreateDate&DD_YEAR_MASK)>>DD_YEAR_SHIFT );
00356 rprintfChar(' ');
00357
00358
00359 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_HOURS_MASK)>>DT_HOURS_SHIFT );
00360 rprintfChar(':');
00361 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_MINUTES_MASK)>>DT_MINUTES_SHIFT );
00362 rprintfChar(':');
00363 rprintfNum(10, 2, FALSE, '0', 2*(FileInfo.CreateTime&DT_2SECONDS_MASK)>>DT_2SECONDS_SHIFT );
00364 rprintfChar(' ');
00365
00366
00367 if(FileInfo.Attr & ATTR_VOLUME) rprintfChar('V'); else rprintfChar('-');
00368 if(FileInfo.Attr & ATTR_DIRECTORY) rprintfChar('D'); else rprintfChar('-');
00369 if(FileInfo.Attr & ATTR_READONLY) rprintfChar('R'); else rprintfChar('-');
00370 if(FileInfo.Attr & ATTR_HIDDEN) rprintfChar('H'); else rprintfChar('-');
00371 if(FileInfo.Attr & ATTR_SYSTEM) rprintfChar('S'); else rprintfChar('-');
00372 if(FileInfo.Attr & ATTR_ARCHIVE) rprintfChar('A'); else rprintfChar('-');
00373 rprintfChar(' ');
00374
00375
00376 rprintfNum(10, 8, FALSE, ' ', FileInfo.Size);
00377 rprintfChar(' ');
00378
00379
00380 rprintfStr(FileNameBuffer);
00381 }
00382
00383 void fatDumpDirSlot(unsigned short slot)
00384 {
00385 unsigned long sector;
00386
00387 sector = fatClustToSect(CurrentDirStartCluster);
00388 sector += slot/DIRENTRIES_PER_SECTOR;
00389
00390 debugPrintHexTable(32, SectorBuffer+(slot<<5) );
00391 }
00392
00393 struct FileInfoStruct* fatGetFileInfo(void)
00394 {
00395 return &FileInfo;
00396 }
00397
00398
00399 unsigned long fatGetFilesize(void)
00400 {
00401 return FileInfo.Size;
00402 }
00403
00404
00405 char* fatGetFilename(void)
00406 {
00407 return FileNameBuffer;
00408 }
00409
00410
00411 char* fatGetDirname(void)
00412 {
00413 return PathNameBuffer;
00414 }
00415
00416
00417 void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
00418 {
00419 register unsigned char i;
00420
00421
00422 for(i=0; i<SectorsPerCluster; i++)
00423 {
00424 ataReadSectors( DRIVE0, fatClustToSect(cluster)+i, 1, buffer+(i<<9) );
00425
00426
00427
00428 }
00429 }
00430
00431
00432
00433 unsigned long fatNextCluster(unsigned long cluster)
00434 {
00435 unsigned long nextCluster;
00436 unsigned long fatMask;
00437 unsigned long fatOffset;
00438 unsigned long sector;
00439 unsigned int offset;
00440
00441
00442 if(Fat32Enabled)
00443 {
00444
00445 fatOffset = cluster << 2;
00446
00447 fatMask = FAT32_MASK;
00448 }
00449 else
00450 {
00451
00452 fatOffset = cluster << 1;
00453
00454 fatMask = FAT16_MASK;
00455 }
00456
00457
00458 sector = FirstFATSector + (fatOffset / BytesPerSector);
00459
00460 offset = fatOffset % BytesPerSector;
00461
00462
00463 if (sector != FatInCache)
00464 {
00465
00466 while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
00467 FatInCache = sector;
00468 }
00469
00470
00471 nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
00472
00473
00474 if (nextCluster == (CLUST_EOFE & fatMask))
00475 nextCluster = 0;
00476
00477 #ifdef DEBUG_FAT
00478 rprintfProgStrM(">");
00479 rprintfu32(nextCluster);
00480 rprintfCRLF();
00481 #endif
00482
00483 return nextCluster;
00484 }