00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <avr/io.h>
00024 #include <avr/string.h>
00025 #include <avr/progmem.h>
00026
00027 #include "ata_if.h"
00028 #include "uart.h"
00029
00030 #include "fat.h"
00031
00032
00033
00034
00035
00036 unsigned char *SectorBuffer = (unsigned char *) SECTOR_BUFFER1_ADDR;
00037 unsigned char *long_name_buffer = (unsigned char *) LONGNAME_BUFFER_ADDR;
00038 unsigned char *dir_name_buffer = (unsigned char *) DIRNAME_BUFFER_ADDR;
00039
00040 struct partrecord PartInfo;
00041 unsigned char Fat32Enabled;
00042 unsigned long FirstDataSector;
00043 unsigned int BytesPerSector;
00044 unsigned int SectorsPerCluster;
00045 unsigned long FirstFATSector;
00046 unsigned long FirstDirSector;
00047 unsigned long FileSize;
00048 unsigned long FatInCache = 0;
00049
00050
00051
00052
00053
00054 unsigned long clust2sect(unsigned long clust)
00055 {
00056 return ((clust-2) * SectorsPerCluster) + FirstDataSector;
00057 }
00058
00059 unsigned int fatClusterSize(void)
00060 {
00061
00062 return SectorsPerCluster;
00063 }
00064
00065 unsigned char fatInit( unsigned char device)
00066 {
00067
00068 struct bpb710 *bpb;
00069
00070
00071
00072 ataReadSectors(DRIVE0, 0, 1, SectorBuffer);
00073
00074
00075 PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart);
00076
00077
00078
00079
00080 ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
00081 bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;
00082
00083
00084 FirstDataSector = PartInfo.prStartLBA;
00085 if(bpb->bpbFATsecs)
00086 {
00087
00088 FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
00089 }
00090 else
00091 {
00092
00093 FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
00094 }
00095 SectorsPerCluster = bpb->bpbSecPerClust;
00096 BytesPerSector = bpb->bpbBytesPerSec;
00097 FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
00098
00099 switch (PartInfo.prPartType)
00100 {
00101 case PART_TYPE_DOSFAT16:
00102 case PART_TYPE_FAT16:
00103 case PART_TYPE_FAT16LBA:
00104
00105 FirstDirSector = CLUST_FIRST;
00106
00107
00108 Fat32Enabled = FALSE;
00109 break;
00110 case PART_TYPE_FAT32LBA:
00111 case PART_TYPE_FAT32:
00112
00113 FirstDirSector = bpb->bpbRootClust;
00114
00115
00116 Fat32Enabled = TRUE;
00117 break;
00118 default:
00119 uartPrintfProgStrM("Found: No Partition!\r\n");
00120
00121 break;
00122 }
00123
00124
00125 #ifdef DEBUG_FAT
00126 switch (PartInfo.prPartType)
00127 {
00128 case PART_TYPE_DOSFAT16:
00129 uartPrintfProgStrM("Found: DOSFAT 16\r\n");
00130 break;
00131 case PART_TYPE_FAT16:
00132 uartPrintfProgStrM("Found: FAT16\r\n");
00133 break;
00134 case PART_TYPE_FAT16LBA:
00135 uartPrintfProgStrM("Found: FAT16 LBA\r\n");
00136 break;
00137 case PART_TYPE_FAT32LBA:
00138 uartPrintfProgStrM("Found: FAT32 LBA\r\n");
00139 break;
00140 case PART_TYPE_FAT32:
00141 uartPrintfProgStrM("Found: FAT32\r\n");
00142
00143 break;
00144 default:
00145 uartPrintfProgStrM("Found: No Partition!\r\n");
00146
00147 break;
00148 }
00149
00150 uartPrintfProgStrM("First sector : ");
00151 uartPrintfu32(PartInfo.prStartLBA);
00152 uartPrintfCRLF();
00153 uartPrintfProgStrM("Size : ");
00154 uartPrintfu32(PartInfo.prSize);
00155 uartPrintfCRLF();
00156
00157 uartPrintfProgStrM("bytes/sector : ");
00158 uartPrintfu16(bpb->bpbBytesPerSec);
00159 uartPrintfCRLF();
00160
00161 uartPrintfProgStrM("sectors/cluster : ");
00162 uartPrintfu08(bpb->bpbSecPerClust);
00163 uartPrintfCRLF();
00164
00165 uartPrintfProgStrM("reserved sectors: ");
00166 uartPrintfu16(bpb->bpbResSectors);
00167 uartPrintfCRLF();
00168
00169 uartPrintfProgStrM("FatSectors : ");
00170 uartPrintfu16(bpb->bpbFATsecs);
00171 uartPrintfCRLF();
00172
00173 uartPrintfProgStrM("BigFatSectors : ");
00174 uartPrintfu32(bpb->bpbBigFATsecs);
00175 uartPrintfCRLF();
00176
00177 uartPrintfProgStrM("Number of Fats : ");
00178 uartPrintfu08(bpb->bpbFATs);
00179 uartPrintfCRLF();
00180
00181 uartPrintfProgStrM("First Fat Sector: ");
00182 uartPrintfu32(FirstFATSector);
00183 uartPrintfCRLF();
00184
00185 uartPrintfProgStrM("First Data Sect : ");
00186 uartPrintfu32(FirstDataSector);
00187 uartPrintfCRLF();
00188
00189 uartPrintfProgStrM("First Dir Clust : ");
00190 uartPrintfu32(FirstDirSector);
00191 uartPrintfCRLF();
00192 #endif
00193
00194 return 0;
00195 }
00196
00197
00198
00199
00200 unsigned int baseentry = 0;
00201 unsigned int entrycount = 0;
00202
00203
00204 unsigned long fatGetDirEntry(unsigned int entry, unsigned int count)
00205 {
00206 unsigned long sector;
00207 struct direntry *de = 0;
00208 struct winentry *we;
00209 unsigned int hasBuffer;
00210 unsigned int b;
00211 int i,index;
00212 char *p;
00213
00214 if (count == 0)
00215 {
00216 entrycount = 0;
00217 *dir_name_buffer = 0;
00218 }
00219
00220
00221 sector = clust2sect(FirstDirSector);
00222
00223 hasBuffer = 0;
00224
00225 index = 16;
00226 do
00227 {
00228 if (index == 16)
00229 {
00230 ataReadSectors( DRIVE0, sector++, 1, SectorBuffer);
00231 de = (struct direntry *) SectorBuffer;
00232 index = 0;
00233 }
00234
00235 if (*de->deName != 0xE5)
00236 {
00237
00238 if (de->deAttributes == ATTR_LONG_FILENAME)
00239 {
00240 we = (struct winentry *) de;
00241 b = 13 *( (we->weCnt-1) & 0x0f);
00242 p = &long_name_buffer[b];
00243 for (i=0;i<5;i++) *p++ = we->wePart1[i*2];
00244 for (i=0;i<6;i++) *p++ = we->wePart2[i*2];
00245 for (i=0;i<2;i++) *p++ = we->wePart3[i*2];
00246 if (we->weCnt & 0x40) *p = 0;
00247 if ((we->weCnt & 0x0f) == 1) hasBuffer = 1;
00248 }
00249 else
00250 {
00251 if (hasBuffer)
00252 {
00253 if (de->deAttributes == ATTR_DIRECTORY)
00254 {
00255 unsigned long save = FirstDirSector;
00256 unsigned int save2 = baseentry;
00257 unsigned long rval;
00258
00259 strcpy(dir_name_buffer,long_name_buffer);
00260 strcat(dir_name_buffer,"/");
00261
00262
00263
00264
00265 FirstDirSector = ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
00266 rval = fatGetDirEntry(entry,1);
00267 FirstDirSector = save;
00268 baseentry = save2;
00269 if (rval)
00270 return rval;
00271 else
00272 {
00273
00274 ataReadSectors( DRIVE0, sector-1, 1, SectorBuffer);
00275 entrycount--;
00276 *dir_name_buffer = 0;
00277 }
00278 }
00279 else
00280 if (entrycount == entry)
00281 break;
00282 hasBuffer = 0;
00283 entrycount++;
00284 }
00285
00286 }
00287 }
00288 de++;
00289 index++;
00290 } while (*de->deName || index == 16);
00291
00292 if (hasBuffer == 0)
00293 return 0;
00294
00295 FileSize = de->deFileSize;
00296 return (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
00297 }
00298
00299
00300
00301 unsigned long fatGetFilesize(void)
00302 {
00303 return FileSize;
00304 }
00305
00306
00307
00308 char* fatGetFilename(void)
00309 {
00310 return long_name_buffer;
00311 }
00312
00313
00314
00315 char* fatGetDirname(void)
00316 {
00317 return dir_name_buffer;
00318 }
00319
00320
00321
00322 void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
00323 {
00324 register unsigned char i;
00325
00326
00327 for(i=0; i<SectorsPerCluster; i++)
00328 {
00329
00330
00331
00332 ataReadSectors( DRIVE0, clust2sect(cluster+8)+i, 1, buffer+(i<<9) );
00333 }
00334 }
00335
00336
00337
00338 unsigned long fatNextCluster(unsigned long cluster)
00339 {
00340 unsigned long nextCluster;
00341 unsigned long fatMask;
00342 unsigned long fatOffset;
00343 unsigned long sector;
00344 unsigned int offset;
00345
00346
00347 if(Fat32Enabled)
00348 {
00349
00350 fatOffset = cluster << 2;
00351
00352 fatMask = FAT32_MASK;
00353 }
00354 else
00355 {
00356
00357 fatOffset = cluster << 1;
00358
00359 fatMask = FAT16_MASK;
00360 }
00361
00362
00363 sector = FirstFATSector + (fatOffset / BytesPerSector);
00364
00365 offset = fatOffset % BytesPerSector;
00366
00367
00368 if (sector != FatInCache)
00369 {
00370
00371 while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
00372 FatInCache = sector;
00373 }
00374
00375
00376 nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
00377
00378
00379 if (nextCluster == (CLUST_EOFE & fatMask))
00380 nextCluster = 0;
00381
00382 #ifdef DEBUG_FAT
00383 uartPrintfProgStrM(">");
00384 uartPrintfu32(nextCluster);
00385 uartPrintfCRLF();
00386 #endif
00387
00388 return nextCluster;
00389 }