📄 fat.c
字号:
/****************************************Copyright (c)**************************************************
** 上海新时达电气有限公司
** 研 发 中 心
** 研发一部
**
** http://www.stepelevatar.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: fat.c
**创 建 人: 吕海安
**最后修改日期: 2007年05月31日
**描 述: fat 文件系统
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 吕海安
** 版 本: v1.0
** 日 期: 2007年05月31日
** 描 述: 原始版本
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <string.h>
#include "comm.h"
#include "sd.h"
#include "fat.h"
extern INT8U BUFFER[512];
extern INT8U WorkFlag;
extern INT8S *IntToStr(INT16S Number);
INT8U FatType; // 0:FAT12 1:FAT16 2:FAT32
INT32U FAT_MASK;
INT16U RootDirEnts; // 根目录总的项数(FAT12&FAT16)
INT32U FirstDataSector; // 数据区
INT16U BytesPerSector;
INT16U SectorsPerCluster;
INT32U FirstFATSector;
ROOTDIR_INF RootDir; // 目录区
FIND_FILE_INFO FindInfo;
/*****************************************************************************************
* 名称:ReadBlock
* 功能:读一个扇区
* 输入:INT32U LBA
* 返回:无
*****************************************************************************************/
void ReadBlock(INT32U LBA)
{
INT32U temp;
temp = LBA << 9; // LBA * 512 SD卡以512个字节读取
SD_Read_Block(temp);
}
/*****************************************************************************************
* 名称:ReadBlockToBuff
* 功能:读一个扇区至 pbuff[]
* 输入:INT32U LBA
INT8U *pbuff
* 返回:无
*****************************************************************************************/
void ReadBlockToBuff(INT32U LBA,INT8U *pbuff)
{
INT32U temp;
temp = LBA << 9; // LBA * 512 SD卡以512个字节读取
SD_Read_Block2(temp,pbuff);
}
/*****************************************************************************************
* 名称:fatGetRootSector
* 功能:查询 FAT 得启动扇区
* 输入:无
* 返回:INT32U 启动扇区
*****************************************************************************************/
INT32U fatGetRootSector(void)
{
if(FatType == FAT32)
{
return ((RootDir.Clust - 2) * SectorsPerCluster) + FirstDataSector;
}
return RootDir.Sector;
}
/*****************************************************************************************
* 名称:fatGetRootClust
* 功能:查询 FAT 得启动簇
* 输入:无
* 返回:INT32U 启动簇
*****************************************************************************************/
INT32U fatGetRootClust(void)
{
if(FatType == FAT32)
{
return RootDir.Clust;
}
return 0x00000000;
}
/*****************************************************************************************
* 名称:fatGetRootClust
* 功能:查询数据区一个簇开始扇区号
* 输入:INT32U clust :簇号
* 返回:INT32U 开始扇区号
*****************************************************************************************/
INT32U fatClustToSect(INT32U clust)
{
return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
/*****************************************************************************************
* 名称:fatClusterSize
* 功能:查询一个簇所占扇区数
* 输入:无
* 返回:INT16U SectorsPerCluster : 扇区数 / 簇
*****************************************************************************************/
INT16U fatClusterSize(void)
{
// return the number of sectors in a disk cluster
return SectorsPerCluster;
}
/*****************************************************************************************
* 名称:fatInit
* 功能:文件系统初始化
* 输入:无
* 返回:1: 初始化成功
0: 初始化失败
*****************************************************************************************/
INT8U fatInit(void)
{
PARTRECORD PartInfo; // 分区信息格式化
BOOTSECTOR710 *pp;
BPB710 bpbBuf, *bpb = &bpbBuf;
bpb->bpbBytesPerSec = BUFFER[11] | (BUFFER[12] << 8);
bpb->bpbSecPerClust = BUFFER[13];
bpb->bpbResSectors = BUFFER[14] | (BUFFER[15] << 8);
bpb->bpbFATs = BUFFER[16];
bpb->bpbRootDirEnts = BUFFER[17] | (BUFFER[18] << 8);
bpb->bpbSectors = BUFFER[19] | (BUFFER[20] << 8);
bpb->bpbMedia = BUFFER[21];
bpb->bpbFATsecs = BUFFER[22] | (BUFFER[23] << 8);
bpb->bpbSecPerTrack = BUFFER[24] | (BUFFER[25] << 8);
bpb->bpbHeads = BUFFER[26] | (BUFFER[27] << 8);
bpb->bpbHiddenSecs = BUFFER[28] | (BUFFER[29] << 8) | (BUFFER[30] << 16) | (BUFFER[31] << 24);
bpb->bpbHugeSectors = BUFFER[32] | (BUFFER[33] << 8) | (BUFFER[34] << 16) | (BUFFER[35] << 24);
bpb->bpbBigFATsecs = BUFFER[36] | (BUFFER[37] << 8) | (BUFFER[38] << 16) | (BUFFER[39] << 24);
bpb->bpbExtFlags = BUFFER[40] | (BUFFER[41] << 8);
bpb->bpbFSVers = BUFFER[42] | (BUFFER[43] << 8);
bpb->bpbRootClust = BUFFER[44] | (BUFFER[45] << 8) | (BUFFER[46] << 16) | (BUFFER[47] << 24);
bpb->bpbFSInfo = BUFFER[48] | (BUFFER[49] << 8);
bpb->bpbBackup = BUFFER[50] | (BUFFER[51] << 8);
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) // 只处理 FAT12 , FAT16 ,FAT32
{
case PART_TYPE_FAT12: // FAT12
RootDir.Sector= FirstDataSector;
FirstDataSector += ((bpb->bpbRootDirEnts*32)/BytesPerSector);
RootDirEnts = bpb->bpbRootDirEnts;
FatType = FAT12;
FAT_MASK = FAT12_MASK;
break;
case PART_TYPE_DOSFAT16: // DOSFAT16
case PART_TYPE_FAT16: // FAT16
case PART_TYPE_FAT16LBA: // FAT16LBA
RootDir.Sector = FirstDataSector;
FirstDataSector += (bpb->bpbRootDirEnts*32)/BytesPerSector;
RootDirEnts = bpb->bpbRootDirEnts;
FatType = FAT16;
FAT_MASK = FAT16_MASK;
break;
case PART_TYPE_FAT32LBA: // FAT32LBA
case PART_TYPE_FAT32: // FAT32
RootDir.Clust = bpb->bpbRootClust;
FAT_MASK = FAT32_MASK;
FatType = FAT32;
break;
default:
return 0;
}
return 1;
}
/****************************************************************************************/
/*********************************** Macro **********************************************/
#define MP3_TYPE 0
#define WMA_TYPE 1
#define MID_TYPE 2
#define LRC_TYPE 3
INT8U filetype[][3] ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};
INT8U hzk12[][11] =
{{"HZK12 "},
{"UNITOGB BIN"},
{". "},
{".. "}
};
/****************************************************************************************/
/****************************************************************************************/
/*****************************************************************************************
* 名称:IsHzk12File
* 功能:查询是否是HZK12文件
* 输入:INT8U *pbuf
* 返回:1: 查询成功
0: 查询失败
*****************************************************************************************/
INT8U IsHzk12File(INT8U *pbuf)
{
INT8U i;
for(i=0; i<11; i++)
{
if(hzk12[0][i]!= pbuf[i]) break;
}
if(i==11) return 1; // find ok
return 0;
}
/*****************************************************************************************
* 名称:IsUnitogbFile
* 功能:查询是否是 Unitogb 文件
* 输入:INT8U *pbuf
* 返回:1: 查询成功
0: 查询失败
*****************************************************************************************/
INT8U IsUnitogbFile(INT8U *pbuf)
{
INT8U i;
for(i=0; i<11; i++)
{
if(hzk12[1][i] != pbuf[i]) break;
}
if(i==11) return 1; // find ok
return 0;
}
/*****************************************************************************************
* 名称:IsFatherDir
* 功能:查询是否是上层目录
* 输入:INT8U *strName
* 返回:1: 查询成功
0: 查询失败
*****************************************************************************************/
INT8U IsFatherDir(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(hzk12[3][i]!= strName[i]) break;
}
if(i==3) return 1; // 是上层目录
return 0;
}
/*****************************************************************************************
* 名称:IsCurDir
* 功能:查询是否是当前目录
* 输入:INT8U *strName
* 返回:1: 查询成功
0: 查询失败
*****************************************************************************************/
INT8U IsCurDir(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(hzk12[2][i]!= strName[i]) break;
}
if(i==3) return 1; // 是当前目录
return 0;
}
/*****************************************************************************************
* 名称:IsMusicFile
* 功能:查询是否是音乐文件
* 输入:INT8U *strName
* 返回:1: 是 MP3 文件
2: 是 WMA 文件
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -