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