📄 fat.c
字号:
#include "fat.h"
#include <string.h>
extern unsigned char sdBuffer[512];
//===========Data========================
//-----------SYSTEM-------------
unsigned char partitionType;//1=fat16,2=fat32
//unsigned long patitionBegin;
unsigned long fatBeginSector;
unsigned long dirBeginCluster;
unsigned long clusterBeginSector;
unsigned short dirEntries;
unsigned long sectorsPerFAT;
unsigned char sectorsPerCluster;
//-------------File-------------
unsigned long fileCurrentCluster;
unsigned long fileDirSector;
unsigned short fileDirIndex;
unsigned char fileCurrentSectorInCluster;
unsigned long fileSize = 0;
//=========Functions======================
unsigned char fatInit()
{
unsigned char tempChar;
unsigned short *pShort;
unsigned long partitionFirstSector;
unsigned short numReservedSectors;
//1. Init SD CARD
if(sdInitCard())
return FATERR_NOCARD;
//2. Read MBR (master boot record)
//2.1 Read the first sector of SD card
if(sdReadData(0))
return FATERR_NOCARD;
//2.2 check MBR/BPB validity
if(sdBuffer[510]!=0x55 || sdBuffer[511]!=0xAA)
return FATERR_UNFORMATTED;
//2.3 whether the first sector is MBR or BPB(boot sector)
if(strncmp(sdBuffer+0x36,"FAT16",5)==0) //BPB && FAT16
{
partitionType = 1;
partitionFirstSector = 0;
}
else if (strncmp(sdBuffer+0x52,"FAT32",5)==0)
{
partitionType = 2;
partitionFirstSector = 0;
}
else //MBR
{
tempChar = sdBuffer[(0x1BE)+(0x04)];
switch(tempChar)
{
case 0x0B:
case 0x0C: //FAT32
partitionType = 2;
break;
case 0x04:
case 0x06:
case 0x0E:
partitionType = 1;
break;
default:
return FATERR_UNFORMATTED;
}
partitionFirstSector = *((unsigned long*)(sdBuffer+((0x1BE)+(0x08))));
}
//3. Read BPB (volume ID / Boot Record)
if(sdReadData(partitionFirstSector<<9))
return FATERR_NOCARD;
if(sdBuffer[510]!=0x55 || sdBuffer[511]!=0xAA) //Check signature
return FATERR_UNFORMATTED;
if(sdBuffer[0x10]!=2) //Check number of FAT==2
return FATERR_UNFORMATTED;
pShort = (unsigned short*)(sdBuffer+0x0B);
if((*pShort)!=(unsigned short)512) //Check Bytes Per Sector ==512
return FATERR_UNFORMATTED;
sectorsPerCluster = sdBuffer[0x0D];
numReservedSectors = *((unsigned short*)(sdBuffer+0x0E));
if(partitionType == 1)//FAT16
sectorsPerFAT = *((unsigned short*)(sdBuffer+0x16));
else
sectorsPerFAT = *((unsigned long*)(sdBuffer+0x24));
fatBeginSector = partitionFirstSector+numReservedSectors;
if (partitionType==2)//FAT32
dirBeginCluster = *((unsigned long*)(sdBuffer+0x2C));
else
{
dirBeginCluster = 0;
dirEntries = *((unsigned short*)(sdBuffer+0x11));
}
if(partitionType==1)
clusterBeginSector = partitionFirstSector+numReservedSectors+sectorsPerFAT*2+(dirEntries>>4)-sectorsPerCluster*2;
else
clusterBeginSector = partitionFirstSector+numReservedSectors+sectorsPerFAT*2-sectorsPerCluster*2;
return FATERR_NOERR;
}
unsigned char fileCreateSequential(const char filenamePrefix[], unsigned char fileIndexLength, const char filenameExt[])
{
unsigned short usTemp;
unsigned long ulTemp,ulTemp1;
unsigned char ucTemp;
unsigned char *pucTemp;
unsigned long fileIndexSearch = 0;
unsigned long fileIndexMax = 1;
unsigned char currentFilename[11];
unsigned char fileIndexUsed = 0;
// unsigned long fileDirSector;
// unsigned long dirSearchCluster;
// unsigned char fileDirIndex;
unsigned char dirFound = 0;
//1. Search an empty cluster
fileCurrentCluster = 0; //Reset current cluster
ucTemp = fatNextEmptyCluster();
if(ucTemp)
return ucTemp;
fileCurrentSectorInCluster = 0;
//2. Search an available filename
for(usTemp=0;usTemp<fileIndexLength;usTemp++)
fileIndexMax *= 10;
fileIndexMax -= 1;
//generate fixed part of filename
for(usTemp=0;usTemp<8-fileIndexLength;usTemp++)
currentFilename[usTemp]=filenamePrefix[usTemp];
for(usTemp=0;usTemp<3;usTemp++)
currentFilename[usTemp+8]=filenameExt[usTemp];
for(fileIndexSearch=0;fileIndexSearch<fileIndexMax;fileIndexSearch++)
{
fileIndexUsed = 0;
//2.1 Generate the filename
ulTemp = fileIndexSearch;
for(ucTemp=0;ucTemp<fileIndexLength;ucTemp++)
{
ulTemp1 = ulTemp/10;
currentFilename[7-ucTemp] = ulTemp-ulTemp1*10+48;
ulTemp = ulTemp1;
}
//2.1 Go to the first DIR entry
ucTemp = fatDirReset();
if(ucTemp) return ucTemp;
//2.2 search the DIR
while(fileDirIndex<=17) //fileDirIndex =0xFFFF when reach the end
{
//Lower to upper case
pucTemp = sdBuffer+(fileDirIndex<<5);
for(ucTemp=0;ucTemp<11;ucTemp++)
{
if(*pucTemp>='a' && *pucTemp<='z')
*pucTemp -= 'a'-'A';
pucTemp++;
}
if(!strncmp (currentFilename,sdBuffer+(fileDirIndex<<5),11))
{
fileIndexUsed = 1;
break;
}
//Switch to next sector
ucTemp = fatDirNext();
if(ucTemp)
return ucTemp;
}//while search DIR
if(!fileIndexUsed)
break; // A valid file index found!!!
}//for (file index)
if(fileIndexUsed)
return FATERR_FILEINDEXFULL;
//3. search an empty DIR entry
ucTemp = fatDirReset();
if(ucTemp) return ucTemp;
//3.2 search the DIR
dirFound = 0;
while(fileDirIndex<=17) //fileDirIndex =0xFFFF when reach the end
{
//search current entry
if ((sdBuffer[fileDirIndex<<5]==0xe5 && (sdBuffer[(fileDirIndex<<5)+0x0B]&0x0f)!=0x0f)
|| sdBuffer[fileDirIndex<<5]==0x00)
{
dirFound = 1;
break;
}
if(dirFound) break; //empty entry found
//Switch to next sector
ucTemp = fatDirNext();
if(ucTemp)
return ucTemp;
}//while search DIR
if(!dirFound && partitionType==1)
return FATERR_ROOTFULL;
if(!dirFound && partitionType==2)
{
ucTemp = fatCreateNewDirCluster();
if(ucTemp)
return ucTemp;
}
//4. Fill in the DIR entry
usTemp = fileDirIndex<<5;
//4.1 fill filename
strncpy(sdBuffer+usTemp,currentFilename,11);
//4.2 fill attribute
sdBuffer[usTemp+0x0B] = 0x00;
//4.3 fill Cluster
if(partitionType==1) //FAT16
*(unsigned short*)(sdBuffer+usTemp+0x1A) = fileCurrentCluster;
else //FAT32
{
*(unsigned short*)(sdBuffer+usTemp+0x14) = fileCurrentCluster>>16;
*(unsigned short*)(sdBuffer+usTemp+0x1A) = fileCurrentCluster&0xFFFF;
}
//4.4 fill Time Date
*(unsigned short*)(sdBuffer+usTemp+0x0E) = 0;
*(unsigned short*)(sdBuffer+usTemp+0x10) = 0;
*(unsigned short*)(sdBuffer+usTemp+0x12) = 0;
*(unsigned short*)(sdBuffer+usTemp+0x16) = 0;
*(unsigned short*)(sdBuffer+usTemp+0x18) = 0;
//4.5 fill file size
fileSize = 0;
*(unsigned long*)(sdBuffer+usTemp+0x1C) = fileSize;
//4.6 write back
if(sdWriteData(fileDirSector<<9))
return FATERR_NOCARD;
return FATERR_NOERR;
}
unsigned char fileWriteBuffer()
{
unsigned char ucTemp;
unsigned long filePreviourCluster;
unsigned long currentSector;
//1. write buffer to current sector
currentSector = clusterBeginSector;
currentSector += fileCurrentCluster*sectorsPerCluster;
currentSector += fileCurrentSectorInCluster;
if(sdWriteData(currentSector<<9))
return FATERR_NOCARD;
fileSize += 512;
//2. step to next sector
fileCurrentSectorInCluster++;
//3. if cluster full switch to next cluster
if(fileCurrentSectorInCluster>=sectorsPerCluster)
{
//3.1 find next empty cluster
filePreviourCluster = fileCurrentCluster;
ucTemp = fatNextEmptyCluster();
if(ucTemp)
{
if(ucTemp==FATERR_DISKFULL)
fileWriteEOF();
return ucTemp;
}
//3.2 write 2 FAT
ucTemp = fatWriteFAT(filePreviourCluster,fileCurrentCluster);
if(ucTemp)
return ucTemp;
//3.3 fileCurrentSectorInCluster=0
fileCurrentSectorInCluster = 0;
}
return FATERR_NOERR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -