📄 fat32_base.c
字号:
/************************************************************************
* File : fat32_base.c
* Processor : ADSP-BF533
* IDDE : VisualDSP++3.5
* Description : FAT driver functions which is mainly cluster-based operation, includes:
*
* Wait_Ready();
* Wait_ReadyBusy();
* CheckforError();
* IdeStandby();
* IdeIdle();
*
*************************************************************************/
#include "FAT/filesystem.h"
#include "FAT/fat32.h"
#include "IDE/ide_access.h"
#include "IDE/ide_base.h"
#include "type.h"
#define FAT_BUFFER_SIZE 1048576 //1M
#define FAT_GROUP_NUM_M 3 //2^3=8
#define FAT_GROUP_SIZE_M 17 //2^17= 128K
#define FAT_GROUP_DWORD_SIZE_M FAT_GROUP_SIZE_M-2
#define FAT_GROUP_SECTOR_NUM (1<<(FAT_GROUP_DWORD_SIZE_M-7))
#define FAT_GROUP_NUM (1<<FAT_GROUP_NUM_M)
#define FAT_GROUP_SIZE (1<<FAT_GROUP_SIZE_M)
#pragma align 4
section("sdram0") BYTE fat_chain[FAT_GROUP_NUM][FAT_GROUP_SIZE];
BYTE fat_group_index[FAT_GROUP_NUM]={ 0, 0, 0, 0, 0, 0, 0, 0};
BYTE next_fat_group=1;
FS_t *current_fs;
extern unsigned int cycles[100];
/******************************************************************
* Function : fnFAT32_LBAofCluster
* Description : get cluster number and LBA of start sector in the cluster
* Input : DWORD Cluster_Number-cluster number
* Output : DWORD LBA of start sector in the cluster
*******************************************************************/
DWORD fnFAT32_LBAofCluster(DWORD Cluster_Number)
{
return ((current_fs->cluster_begin_lba + ((Cluster_Number-2)*current_fs->bpb.sector_per_cluster)));
}
/******************************************************************
* Function : fnFATChainInit
* Description : cluster chain initialization-read fist 128K FAT data to FAT buffer in SDRAM
* Input : none
* Output : none
*******************************************************************/
void fnFATChainInit()
{
BYTE i,j;
BUFFER *fat_sector;
fat_sector = (BUFFER *)(fat_chain[0]);
// Read the first 256 sectors to SDRAM
fnIDE_BufferSector(fat_sector,partition_table[0]->fs->fat_begin_lba,FAT_GROUP_SECTOR_NUM);
}
/******************************************************************
* Function : fnFAT32_init
* Description : FAT32 partition initialization-get FAT32 partition information
* Input :
* FS_t *fs - pointer to structure which store FAT partition information
* DWORD offest_sector - starting sector of FAT partition table
* Output : none
*******************************************************************/
void fnFAT32_init(FS_t *fs,DWORD offset_sector)
{
fnIDE_BufferSector(&buffers,offset_sector,1); // read DBR
// Load Parameters of FAT32
fs->bpb.byte_per_sector = fnIDE_SectorWord(BYTE_PER_SECTOR);
fs->bpb.sector_per_cluster = fnIDE_SectorByte(SECTOR_PER_CLUSTER);
fs->bpb.reserve_sector = fnIDE_SectorWord(RESERVE_SECTOR);
fs->bpb.FATnum = fnIDE_SectorByte(FAT_NUM);
fs->bpb.root_entrice = fnIDE_SectorWord(ROOT_ENTRICE);
fs->bpb.media_descriptor = fnIDE_SectorByte(MEDIA_DESCRIPTOR);
fs->bpb.sector_per_track = fnIDE_SectorWord(SECTOR_PER_TRACK);
fs->bpb.head_num= fnIDE_SectorWord(HEAD_NUM);
fs->bpb.hide_sector= fnIDE_SectorDWORD(HIDE_SECTOR);
fs->bpb.sector_num= fnIDE_SectorDWORD(LARGE_SECTOR);
fs->bpb.sector_per_FAT= fnIDE_SectorDWORD(SECTOR_PER_FAT_4);
fs->bpb.flag= fnIDE_SectorWord(EXT_FLAG);
fs->bpb.root_cluster= fnIDE_SectorDWORD(ROOT_CLUSTER);
fs->bpb.FSinfo_sector= fnIDE_SectorDWORD(FSINFO_SECTOR);
fs->bpb.backup_sector= fnIDE_SectorWord(BACKUP_SECTOR);
fs->byte_per_cluster= fs->bpb.byte_per_sector*fs->bpb.sector_per_cluster;
fs->fat_begin_lba = offset_sector + fs->bpb.reserve_sector;
fs->cluster_begin_lba = fs->fat_begin_lba + (fs->bpb.FATnum * fs->bpb.sector_per_FAT);
fs->fs_type= FS_TYPE_FAT32;
fs->total_cluster=fs->bpb.sector_num/fs->bpb.sector_per_cluster;
fnFATChainInit();
if (fnIDE_SectorWord(0x1FE)!=0xAA55) //check ending - 0xAA55 in DBR
{
printf("\r\nError: Incorrect Volume Signature");
while(1);
}
}
/******************************************************************
* Function : fnFAT32_FindNextCluster
* Description : find next cluster (according to current cluster in cluster chain). Finding steps:
* 1, find next cluster in FAT buffer in SDRAM (128K)
* 2, read another 128K FAT data from HD and write to FAT buffer to SDRAM if find nothing in step1
* 3, repeat step 1
* Input :
* DWORD current_cluster - current cluster number
* Output : next cluster number
*******************************************************************/
DWORD fnFAT32_FindNextCluster(DWORD current_cluster)
{
BYTE i;
DWORD FAT_group_offset, UI32position;
DWORD nextcluster;
DWORD *cluster_buffer;
DWORD sector_offset;
if(current_cluster>current_fs->total_cluster)
return 0xFFFFFFFF;
// find image of current cluster in FAT table
FAT_group_offset = current_cluster>>FAT_GROUP_DWORD_SIZE_M;
UI32position = (current_cluster - (FAT_group_offset <<FAT_GROUP_DWORD_SIZE_M)) ;
//step 1 - begin searching next cluster in SDRAM
for(i=0;i<FAT_GROUP_NUM;i++)
{
if(FAT_group_offset==fat_group_index[i])
{
cluster_buffer=(DWORD *)(fat_chain[i]);
nextcluster = cluster_buffer[UI32position];
if((nextcluster&0x0FFFFFFF)==0x0FFFFFFF)
{
return 0xFFFFFFFF;
}
else
{
return nextcluster;
}
}
}
//step 2 - read 128kB FAT table data(including current cluster) from HD and write to SDRAM
sector_offset = (FAT_group_offset<<FAT_GROUP_SIZE_M)/current_fs->bpb.byte_per_sector;
cluster_buffer = (DWORD*)(fat_chain[next_fat_group]);
fnIDE_BufferSector(cluster_buffer,current_fs->fat_begin_lba+sector_offset,FAT_GROUP_SECTOR_NUM);
fat_group_index[next_fat_group]=FAT_group_offset;
next_fat_group= next_fat_group +1 ;
if(next_fat_group==FAT_GROUP_NUM)
{
next_fat_group=1;
}
nextcluster = cluster_buffer[UI32position];
if((nextcluster&0x0FFFFFFF)==0x0FFFFFFF)
{
return 0xFFFFFFFF;
}
else
{
return nextcluster;
}
}
/******************************************************************
* Function : fnFAT32_SectorReader
* Description : read target sector( according to offset of target sector in cluster)
* case 1 (normally)-target sector is in current cluster
* case 2 - target sector is not in current cluster, find next cluster (according to offset)
* Input :
* currentcluster_t cluster - current cluster number ( do not contain the sector in case 2)
* DWORD offset - offset of target sector in the cluster
* Output : cluster - current cluster number
*******************************************************************/
currentcluster_t fnFAT32_SectorReader(currentcluster_t cluster, DWORD offset)
{
DWORD SectortoRead = 0;
DWORD ClustertoRead = 0;
DWORD ClusterChain = 0;
WORD sector_per_cluster=current_fs->bpb.sector_per_cluster;
int i;
if(cluster.value==0xFFFFFFFF)
return cluster;
ClusterChain = cluster.value;
ClustertoRead = offset / sector_per_cluster;
SectortoRead = offset - (ClustertoRead*sector_per_cluster);
// cast 2 -call finFAT32_FindNextCluster() to find cluster that contain target sector
for (i=cluster.offset; i<ClustertoRead; i++)
{
ClusterChain = fnFAT32_FindNextCluster(ClusterChain);
}
//register current cluster
cluster.value=ClusterChain;
cluster.offset=ClustertoRead;
if (ClusterChain==0xFFFFFFFF)
return cluster;
//read target sector
fnIDE_BufferSector(&buffers,fnFAT32_LBAofCluster(ClusterChain)+SectortoRead,1);
return cluster;
}
/******************************************************************
* Function : fnFAT32_WriteSector
* Description : write target sector( according to offset of target sector in cluster)
* case 1 (normally)-target sector is in current cluster
* case 2 - target sector is not in current cluster, find next cluster (according to offset)
* Input :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -