/*************************************************************/
/* FAT操作函数库 */
/* 环境WinAVR 20060421 */
/* 作者:Bozai(章其波) */
/* E-mail:sudazqb@163.com */
/* 2007年2月13日 */
/*************************************************************/
/* 20071109: add & modify function for any directory music file playing */
/* 20071103: add function for lyric display */
/*History: 2007年2月13日 */
/* 添加了适合于RAM丰富的AVR单片机操作 的FAT表函数 */
/* 改进了查找FAT表的函数,使在硬盘操作时不需频繁去读FAT表. */
/* 注: 只适合RAM足够多的单片机 */
/*************************************************************/
#include"FAT.h"
DWORD FirstDirClust; //first directory cluster
DWORD FirstDataSector; // The first sector number of data
WORD BytesPerSector; // Bytes per sector
DWORD FATsectors; // The amount sector a FAT occupied
WORD SectorsPerClust; // Sector per cluster
DWORD FirstFATSector; // The first FAT sector
DWORD FirstDirSector; // The first Dir sector
DWORD RootDirSectors; // The sector number a Root dir occupied
DWORD RootDirCount; // The count of directory in root dir
BYTE FAT32_Enable;
BYTE TABLE_READ = 0;
DWORD START_CLUSTER = 0x0ffffff8; //when the mcu has large ram
//BYTE FAT_TABLE[512]; //when the mcu has large ram
BYTE LongNameBuffer[MAX_LONG_NAME_SIZE];
BYTE LongNameFlag = 0;
BYTE (* FAT_ReadSector)(DWORD,BYTE *);
BYTE (* FAT_WriteSector)(DWORD,BYTE *);
DWORD (* FAT_ReadCapacity)(void);
//函数指针指向sd卡的读写函数
//BYTE (* FAT_ReadSector)(DWORD sector, BYTE * buffer) = CH375_ReadOneSector;
//BYTE (* FAT_WriteSector)(DWORD sector, BYTE * buffer) = CH375_WriteOneSector;
//BYTE (* FAT_ReadSector)(DWORD sector, BYTE * buffer)=MMC_SD_ReadSingleBlock;//device read
//BYTE (* FAT_WriteSector)(DWORD sector, BYTE * buffer)=MMC_SD_WriteSingleBlock;//device write
struct FileInfoStruct FileInfo;//temporarily buffer for file information
//FAT初始化,不含SD的初始化,用之前应先调用sd的初始化
unsigned char FAT_Init()//Initialize of FAT need initialize SD first
{
struct bootsector710 *bs = 0;
struct bpb710 *bpb = 0;
// struct partsector *ps = 0;
struct partrecord *pr = 0;
BYTE buffer[512];
DWORD hidsec=0;
DWORD Capacity;
Capacity = FAT_ReadCapacity();
if(Capacity<0xff)return 1;
if(FAT_ReadSector(0,buffer))return 1;
bs = (struct bootsector710 *)buffer;
pr = (struct partrecord *)((struct partsector *)buffer)->psPart;//first partition
hidsec = pr->prStartLBA;//the hidden sectors
if(hidsec >= Capacity/512)
{
hidsec = 0;
}
else
{
if(FAT_ReadSector(pr->prStartLBA,buffer))return 1;//read the bpb sector
bs = (struct bootsector710 *)buffer;
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)
{
hidsec = 0;
if(FAT_ReadSector(0,buffer))return 1;//read the bpb sector
bs = (struct bootsector710 *)buffer;
}
}
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)//对付没有bootsect的sd卡 //dead with the card which has no bootsect
{
return 1;
}
bpb = (struct bpb710 *)bs->bsBPB;
if(bpb->bpbFATsecs)//detemine thd FAT type //do not support FAT12
{
FAT32_Enable=0; //FAT16
FATsectors = bpb->bpbFATsecs;//FAT占用的扇区数 //the sectors number occupied by one fat talbe
FirstDirClust = 2;
}
else
{
FAT32_Enable=1; //FAT32
FATsectors = bpb->bpbBigFATsecs;//FAT占用的扇区数 //the sectors number occupied by one fat talbe
FirstDirClust = bpb->bpbRootClust;
}
BytesPerSector = bpb->bpbBytesPerSec;//每扇区字节数
SectorsPerClust = (BYTE)bpb->bpbSecPerClust;//每簇扇区数
FirstFATSector = bpb->bpbResSectors+hidsec;//第一个FAT表扇区
RootDirCount = bpb->bpbRootDirEnts;//根目录项数
RootDirSectors = (RootDirCount*32)>>9;//根目录占用的扇区数
FirstDirSector = FirstFATSector+bpb->bpbFATs*FATsectors;//第一个目录扇区
FirstDataSector = FirstDirSector+RootDirSectors;//第一个数据扇区
return 0;
}
//读一个簇中的一个扇区
unsigned char FAT_LoadPartCluster(unsigned long cluster,unsigned part,BYTE * buffer)
{
DWORD sector;
sector=(DWORD)FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;//calculate the actual sector number
if(FAT_ReadSector(sector+part,buffer))return 1;
else return 0;
}
/*
//读整个簇
//Read the a cluster
//Not suitable for system which has few data RAM
unsigned char FAT_LoadCluster(unsigned long cluster,BYTE * buffer)
{
DWORD sector;
unsigned char i;
sector=FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;//calculate the actual sector number
for(i=0;i<SectorsPerClust;i++)
{
if(FAT_ReadSector(sector+i,buffer+(i<<9)))break;
}
if(i==SectorsPerClust)return 0;
else return 1;
}*/
//读下一簇簇号
//Return the cluster number of next cluster of file
//Suitable for system which has limited RAM
unsigned long FAT_NextCluster(unsigned long cluster)
{
BYTE buffer[512];
DWORD sector;
DWORD offset;
if(FAT32_Enable)offset = cluster/128;
else offset = cluster/256;
if(cluster<2)return 0x0ffffff8;
sector=FirstFATSector+offset;//calculate the actual sector
if(FAT_ReadSector(sector,buffer))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured
if(FAT32_Enable)
{
offset=cluster%128;//find the position
sector=((unsigned long *)buffer)[offset];
}
else
{
offset=cluster%256;//find the position
sector=((unsigned int *)buffer)[offset];
}
return (unsigned long)sector;//return the cluste number
}
/*unsigned long FAT_NextCluster_NEW(unsigned long cluster)
{
//BYTE buffer[512];
BYTE temp;
DWORD sector;
DWORD offset;
if(cluster<2)return 0x0ffffff8;
if(FAT32_Enable)temp = 127;
else temp = 255;
offset = cluster/(temp+1);
sector=FirstFATSector+offset;//calculate the actual sector where the FAT placed
offset=cluster%(temp+1);//find the position //计算出在表中的偏移量
cluster -= offset;//找出需要的起始位置 ,以便于当前保存的起始簇号比较
if(TABLE_READ == 0 || cluster != START_CLUSTER)//从未读过 or 不在已有的FAT表内 需重新读
{
if(FAT_ReadSector(sector,FAT_TABLE))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured
START_CLUSTER = cluster;
TABLE_READ = 1;
}
// if(cluster != START_CLUSTER)//不在已有的FAT表内 需重新读
// {
// if(FAT_ReadSector(sector,FAT_TABLE))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured
// START_CLUSTER = cluster;
// TABLE_READ = 1;
// }
if(FAT32_Enable)
{
// offset=cluster%128;//find the position
sector=((unsigned long *)FAT_TABLE)[offset];
}
else
{
// offset=cluster%256;//find the position
sector=((unsigned int *)FAT_TABLE)[offset];
}
return (unsigned long)sector;//return the cluste number
}*/
//在FAT表内找空簇
//Find a free cluster return the cluster number
unsigned long FAT_FindFreeCluster()
{
BYTE buffer[512];
//DWORD sector;
unsigned int i;
unsigned long cnt;
// sector=FirstFATSector+offset;//calculate the actual sector
//sector=FirstFATSector;
if(FAT32_Enable)
{
for(cnt=0;cnt<FATsectors;cnt++)//find in the FAT table
{
if(FAT_ReadSector(FirstFATSector+cnt,buffer))return 1;//error
for(i=0;i<128;i++)
{
if(((unsigned long *)buffer)[i]==0x00000000)break;//an unused cluster
}
if(i!=128)
{
cnt=cnt*128+i;
return cnt;//return the free cluster number
}
}
}
else
{
for(cnt=0;cnt<FATsectors;cnt++)//find in the FAT table
{
if(FAT_ReadSector(FirstFATSector+cnt,buffer))return 1;//error
for(i=0;i<256;i++)
{
if(((unsigned int *)buffer)[i]==0x0000)break;//an unused cluster
}
if(i!=256)
{
cnt=cnt*256+i;
return cnt;//return the free cluster number
}
}
}
return 1;/