?? fat.c
字號:
/************************************************************/
/* FAT */
/* */
/************************************************************/
#include <avr/io.h>
#include <string.h>
#include <avr/eeprom.h>
#include "sd.h"
#include "fat.h"
#include "lcd.h"
extern uchar BUFFER[512];
extern uchar WorkFlag;
unsigned char FatType; //0:FAT12 1:FAT16 2:FAT32
unsigned long FAT_MASK;
unsigned int RootDirEnts; //根目錄總的項數(FAT12&FAT16)
unsigned long FirstDataSector; //數據區
unsigned int BytesPerSector;
unsigned int SectorsPerCluster;
unsigned long FirstFATSector;
ROOTDIR_INF RootDir; //目錄區FIND_FILE_INFO FindInfo;
//********************************************************************************************
//讀一個扇區
void ReadBlock(unsigned long LBA)
//********************************************************************************************
{ unsigned long temp;
temp=LBA<<9;
SD_Read_Block(temp);
}
void ReadBlockToBuff(unsigned long LBA,unsigned char *pbuff)
{
unsigned long temp;
temp=LBA<<9;
SD_Read_Block2(temp,pbuff);
}
unsigned long fatGetRootSector(void)
{
if(FatType == FAT32)
return ((RootDir.Clust-2)* SectorsPerCluster) +FirstDataSector;
return RootDir.Sector;
}
unsigned long fatGetRootClust(void)
{
if(FatType==FAT32) return RootDir.Clust;
return 0x00000000;
}
/*-----------------------------------------------------------------------
查詢數據區一個簇開始扇區號
-----------------------------------------------------------------------*/
unsigned long fatClustToSect(unsigned long clust)
{
return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
/*-----------------------------------------------------------------------
查詢一個簇所占扇區數
-----------------------------------------------------------------------*/
unsigned int fatClusterSize(void)
{
// return the number of sectors in a disk cluster
return SectorsPerCluster;
}
//文件系統初始化
unsigned char fatInit()
{
PARTRECORD PartInfo;
BPB710 *bpb=0;
ReadBlock(0); // 讀取分區表信息
PartInfo = *((PARTRECORD *) ((PARTSECTOR *)BUFFER)->psPart);
// 引導扇區號在PartInfo.prStartLBA中
ReadBlock(PartInfo.prStartLBA); //ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
bpb = (BPB710 *) &((BOOTSECTOR710 *) BUFFER)->bsBPB;
FirstDataSector = PartInfo.prStartLBA;
if(bpb->bpbFATsecs)
{
// bpbFATsecs非0,為FAT16,FAT表所占的扇區數在bpbFATsecs里
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
}
else
{
// bpbFATsecs是0,為FAT32,FAT表所占的扇區數在bpbBigFATsecs里
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
}
SectorsPerCluster = bpb->bpbSecPerClust;
BytesPerSector = bpb->bpbBytesPerSec;
FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
switch (PartInfo.prPartType)
{
case PART_TYPE_FAT12:
RootDir.Sector= FirstDataSector;
FirstDataSector += ((bpb->bpbRootDirEnts*32)/BytesPerSector);
RootDirEnts = bpb->bpbRootDirEnts;
FatType = FAT12;
FAT_MASK=FAT12_MASK;
break;
case PART_TYPE_DOSFAT16:
case PART_TYPE_FAT16:
case PART_TYPE_FAT16LBA:
RootDir.Sector = FirstDataSector;
FirstDataSector += (bpb->bpbRootDirEnts*32)/BytesPerSector;
RootDirEnts = bpb->bpbRootDirEnts;
FatType = FAT16;
FAT_MASK=FAT16_MASK;
break;
case PART_TYPE_FAT32LBA:
case PART_TYPE_FAT32:
RootDir.Clust = bpb->bpbRootClust;
FAT_MASK=FAT32_MASK;
FatType = FAT32;
break;
default:
return 0;
}
return 1;
}
#define MP3_TYPE 0
#define WMA_TYPE 1
#define MID_TYPE 2
#define LRC_TYPE 3
unsigned char filetype[][3] PROGMEM ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};
unsigned char hzk12[][11] PROGMEM =
{{"HZK12 "},
{"UNITOGB BIN"},
{". "},
{".. "}
};
unsigned char IsHzk12File(unsigned char *pbuf)
{
unsigned char i;
for(i=0;i<11;i++){
if(pgm_read_byte(hzk12[0]+i)!=pbuf[i]) break;
}
if(i==11) return 1; //find ok
return 0;
}
unsigned char IsUnitogbFile(unsigned char *pbuf)
{
unsigned char i;
for(i=0;i<11;i++){
if(pgm_read_byte(hzk12[1]+i)!=pbuf[i]) break;
}
if(i==11) return 1; //find ok
return 0;
}
unsigned char IsFatherDir(unsigned char *strName)
{
unsigned char i;
for(i=0;i<3;i++){
if(pgm_read_byte(hzk12[3]+i)!=strName[i]) break;
}
if(i==3) return 1; //是上層目錄
return 0;
}
unsigned char IsCurDir(unsigned char *strName)
{
unsigned char i;
for(i=0;i<3;i++){
if(pgm_read_byte(hzk12[2]+i)!=strName[i]) break;
}
if(i==3) return 1; //是當前目錄
return 0;
}
unsigned char IsMusicFile(unsigned char *strName)
{
unsigned char i;
for(i=0;i<3;i++){
if(pgm_read_byte(filetype[MP3_TYPE]+i)!=strName[i]) break;
}
if(i==3) return 1; //是MP3文件
for(i=0;i<3;i++){
if(pgm_read_byte(filetype[WMA_TYPE]+i)!=strName[i]) break;
}
if(i==3) return 2; //是WMA文件
/*
for(i=0;i<3;i++){
if(pgm_read_byte(filetype[MID_TYPE]+i)!=strName[i]) break;
}
if(i==3) return 3; //是MIDI文件
*/
return 0;
}
/*-----------------------------------------------------------------------
在FAT表中查詢下一個簇號
-----------------------------------------------------------------------*/
unsigned long fatNextCluster(unsigned long cluster)
{
unsigned long nextCluster=0;
unsigned long fatOffset;
unsigned long sector;
unsigned int offset;
if(FatType==FAT32 ) // 一個表項為4bytes(32 bits)
{
fatOffset = cluster << 2;
sector = FirstFATSector + (fatOffset / BytesPerSector); //計算FAT扇區號
offset = fatOffset % BytesPerSector; //計算FAT扇區號中表項的偏移地址
nextCluster=SD_Read_Dword(sector,offset);
//ReadBlock(sector); // 讀取下一個簇號
//nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) ;
}else if(FatType==FAT16){ // 一個表項為2bytes(16 bits)
fatOffset = cluster << 1; //計算FAT扇區號
sector = FirstFATSector + (fatOffset / BytesPerSector);
offset = fatOffset % BytesPerSector;//計算FAT扇區號中表項的偏移地址
nextCluster=SD_Read_Word(sector,offset);
// ReadBlock(sector);
// nextCluster = (*((unsigned int*) &((char*)BUFFER)[offset])) ;
}else if(FatType==FAT12){ // 一個表項為1.5bytes(12 bits)
fatOffset = cluster+(cluster>>1);
sector = FirstFATSector + (fatOffset / BytesPerSector);
offset = fatOffset % BytesPerSector;
// ReadBlock(sector);
if(offset==(BytesPerSector-1)){
nextCluster=SD_Read_Word(sector,offset-1)>>8;
// nextCluster=(unsigned long)BUFFER[offset]; //低位
// ReadBlock(sector+1);
nextCluster|=((SD_Read_Word(sector+1,0)<<8)&0x0000ffff);
// nextCluster|=(BUFFER[0]<<8)&0x0000ffff; //高位,必須與,否則會出現錯誤
}else{
nextCluster=SD_Read_Word(sector,offset);
// nextCluster =(*((unsigned int*) &((char*)BUFFER)[offset])) ;
}
if(cluster&0X00000001){ //取低12位地址
nextCluster>>=4;
}else{ //取高12位地址
nextCluster&=0x00000fff;
}
}
// 是否文件的結束簇
if (nextCluster >= (CLUST_EOFS & FAT_MASK))
nextCluster = CLUST_EOFE;
return nextCluster;
}
//在根目錄中查找漢字庫文件的首簇號及UNITCODE碼轉換表文件的首簇號---
//
void GetSysFileClust(unsigned long *hzk,unsigned long *unit)
{
DIRENTRY *de=0;
FIND_FILE_INFO fp;
InitSetPath(&fp,fatGetRootClust());
ReadBlock(fp.Sector); //重新讀取目錄表
(*hzk)=(*unit)=0;
do{
if(!ReadNextDirEntry(&fp)) break;
de = (DIRENTRY *)BUFFER;
de+=fp.Index;
if(*de->deName != 0xe5){
if((de->deAttributes&ATTR_LONG_FILENAME)!=ATTR_LONG_FILENAME){
if((de->deAttributes&ATTR_DIRECTORY)!= ATTR_DIRECTORY)// is it a directory ?
if(*hzk==0){
if(IsHzk12File(de->deName))
*hzk= (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
}
if(*unit==0){
if(IsUnitogbFile(de->deName))
*unit= (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
}
if((*hzk!=0)&&(*unit!=0)) break;
}
}
de++;
fp.Index++;
if(de->deName[0]==0) break;
}while (1);
}
void InitSetPath(FIND_FILE_INFO *fp,unsigned long dircluster)
{
fp->Nums=0x8000; //高位為1表示不是FAT12&fat16的根目錄
fp->Clust=dircluster;
if(dircluster==0x00000000){ //根目錄區
if(FatType==FAT32){
fp->Sector= fatClustToSect(RootDir.Clust);
fp->Clust = RootDir.Clust;
}else{
fp->Sector = RootDir.Sector; //得到目錄區的扇區號
fp->Nums = RootDirEnts;
} //此時根目錄項數是確定大小的
}else{
fp->Sector=fatClustToSect(dircluster);
}
fp->Index = 0;
fp->NumSector=0;
}
//在當前的目錄中查找歌詞文件,找到置相關數據至lyric中
//入口: 1.dircluster 當前目錄的首簇號,若是FAT12或FAT16的根目錄則為0
void FindLrcFile(unsigned long dircluster,unsigned char *strName)
{
FIND_FILE_INFO fp;
DIRENTRY *de=0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -