网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> DSP >> 代码示例 >> ADI DSP代码示例 >> Blackfin >> 文章正文
  ADSP-BF533 FAT32 Base(C)源代码         ★★★ 【字体:
ADSP-BF533 FAT32 Base(C)源代码
作者:61IC    文章来源:本站原创    点击数:    更新时间:2007-1-22    

/************************************************************************
* 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     :
*             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_WriteSector(currentcluster_t cluster, DWORD offset)
{
    DWORD SectortoRead = 0;
   DWORD ClustertoRead = 0;
   DWORD ClusterChain = 0;
   int i;
  
   if(cluster.value==0xFFFFFFFF)
    return cluster;

   ClusterChain = cluster.value;

 
   ClustertoRead = offset / current_fs->bpb.sector_per_cluster;  
   SectortoRead = offset - (ClustertoRead*current_fs->bpb.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;
   }
  
   //write target sector
   fnIDE_WriteBufferSector(&(buffers.currentsector),fnFAT32_LBAofCluster(ClusterChain)+SectortoRead,1);
  
   return cluster;
}

/******************************************************************
* Function     : fnFAT32_UpdateFAT
* Description : Update FAT data table in HD with fat buffer data in SDRAM
* write target sector( according to offset of target sector in cluster)
* Input     :
*             DWORD - Current_Cluster - cluster in buffer
* Output   : 1-done/ 0-fail
*******************************************************************/
YTE fnFAT32_UpdateFAT(DWORD Current_Cluster)
{
 DWORD FAT_group_num;
 DWORD *buffer;
 BYTE i;
 
 if (Current_Cluster<2||Current_Cluster>=(current_fs->bpb.sector_per_FAT*current_fs->bpb.byte_per_sector/4))
  return 0;

 FAT_group_num = Current_Cluster>>FAT_GROUP_DWORD_SIZE_M;
 
 // write FAT data in SDRAM to HD FAT data table( according to Current_Cluster)
 for(i=0;i<FAT_GROUP_NUM;i++)
 {
  if(FAT_group_num==fat_group_index[i])
  {
   buffer=(DWORD *)(fat_chain[i]);
   
   fnIDE_WriteBufferSector(buffer,current_fs->fat_begin_lba+FAT_group_num*FAT_GROUP_SECTOR_NUM,0);
 
   fnIDE_WriteBufferSector(buffer,current_fs->fat_begin_lba+FAT_group_num*FAT_GROUP_SECTOR_NUM+current_fs->bpb.sector_per_FAT,0);
   return 1;
  }
 }
 return 0;
}

/******************************************************************
* Function     : fnFAT32_NextEmptyCluster
* Description : search next empty cluster in FAT buffer in SDRAM and fetch another 128KB data from HD FAT data table if not.
* Input     :
*             DWORD cluster - start cluster ( not used, routine search from cluster 2)
* Output   : Empty cluster number
*******************************************************************/
DWORD fnFAT32_NextEmptyCluster(DWORD cluster)
{
 DWORD i,j,k;
 DWORD FAT_group_num=0,FAT_group_offset;
 DWORD sector_offset,cluster_base;
 DWORD FAT_group_size=FAT_GROUP_SIZE>>2;
 DWORD total_group=current_fs->bpb.sector_per_FAT*current_fs->bpb.byte_per_sector/FAT_GROUP_SIZE+1;
 DWORD * data;
 DWORD buffer[128];
 WORD  u32_per_sector = current_fs->bpb.byte_per_sector>>2;

      //start searching from cluster 2
 for(i=0;i<total_group;i++)
 {
  // search in FAT buffer in SDRAM 
  for(j=0;j<FAT_GROUP_NUM;j++)
  {
   if(i==fat_group_index[j])
   {
    data = (DWORD *)(fat_chain[i]);
    break;
   }
  }
  //update FAT buffer if find nothing
  if(j==FAT_GROUP_NUM)
  {
   sector_offset = (i<<FAT_GROUP_SIZE_M)/current_fs->bpb.byte_per_sector;
   data = (DWORD*)(fat_chain[next_fat_group]);
   fnFAT32_UpdateFAT(cluster);
   fnIDE_BufferSector(data,current_fs->fat_begin_lba+sector_offset,FAT_GROUP_SECTOR_NUM);
   fat_group_index[next_fat_group] = FAT_group_num;
   next_fat_group= next_fat_group+1;
   if(next_fat_group==FAT_GROUP_NUM)
   {
    next_fat_group=1;
   }
  }
  
  cluster_base=i*FAT_group_size; //DWORD
  for(k=0;k<FAT_group_size;k++)
  {
  
   if(data[k]==0x00000000)
   {
    return cluster_base+k;
   }
  }
 }
 
 return 0xFFFFFFFF;
}

/******************************************************************
* Function     : fnFAT32_EditFat
* Description : Edit FAT table
* Input     :
*             DWORD Current_Cluster-target cluster number            
*             DWORD value-edit value
* Output   : 1-done/ 0-fail
*******************************************************************/
BYTE fnFAT32_EditFat(DWORD Current_Cluster,DWORD value)
{
 DWORD FAT_sector_offset, UI32position;
 DWORD FAT_group_num,FAT_group_offset,sector_offset;
 BUFFER *buffer;
 DWORD *cluster;
 BYTE i;
 
 if (Current_Cluster<2||Current_Cluster>=(current_fs->bpb.sector_per_FAT*current_fs->bpb.byte_per_sector/4))
  return 0;

 //get offset of target cluster in FAT buffer in SDRAM
 FAT_group_num = Current_Cluster>>FAT_GROUP_DWORD_SIZE_M;
 FAT_group_offset= Current_Cluster-(FAT_group_num<<FAT_GROUP_DWORD_SIZE_M);
 FAT_sector_offset = FAT_group_offset / 128;
 
 UI32position = (FAT_group_offset - (FAT_sector_offset * 128)) ;

 //edit target cluster in FAT buffer, update FAT table
 for(i=0;i<FAT_GROUP_NUM;i++)
 {
  if(FAT_group_num==fat_group_index[i])
  {
   buffer=(BUFFER *)(fat_chain[i]+FAT_sector_offset*512);
   buffer->u32data[UI32position]=value;
   fnIDE_WriteBufferSector(buffer,current_fs->fat_begin_lba+FAT_group_num*FAT_GROUP_SECTOR_NUM+FAT_sector_offset,1);
   fnIDE_WriteBufferSector(buffer,current_fs->fat_begin_lba+FAT_group_num*FAT_GROUP_SECTOR_NUM+current_fs->bpb.sector_per_FAT+FAT_sector_offset,1);
   return 1;
  }
 }

 // read new data from FAT table in HD to SDRAM and edit it if there is no target cluster in SDRAM
 sector_offset = (FAT_group_num<<FAT_GROUP_SIZE_M)/current_fs->bpb.byte_per_sector;
 cluster = (DWORD*)(fat_chain[next_fat_group]);
 fnIDE_BufferSector(cluster,current_fs->fat_begin_lba+sector_offset,FAT_GROUP_SECTOR_NUM);
 fat_group_index[next_fat_group] = FAT_group_num;
 
 buffer=(BUFFER *)(fat_chain[next_fat_group]+FAT_sector_offset*512);
 buffer->u32data[UI32position]=value;
 
 fnIDE_WriteBufferSector(buffer,current_fs->fat_begin_lba+FAT_group_num*FAT_GROUP_SECTOR_NUM+FAT_sector_offset,1);
 
 fnIDE_WriteBufferSector(buffer,current_fs->fat_begin_lba+FAT_group_num*FAT_GROUP_SECTOR_NUM+current_fs->bpb.sector_per_FAT+FAT_sector_offset,1);
 next_fat_group= next_fat_group +1;
 if(next_fat_group==FAT_GROUP_NUM)
 {
  next_fat_group=1;
 }
 
 
 return 1;
}

/******************************************************************
* Function     : fnFAT32_EditFatChain
* Description : Edit FAT table - only edit FAT buffer in SDRAM
* Input     :
*             DWORD Current_Cluster-target cluster number            
*             DWORD value-edit value
* Output   : 1-done/ 0-fail
*******************************************************************/
BYTE fnFAT32_EditFatChain(DWORD Current_Cluster,DWORD value)
{
 DWORD FAT_group_num,FAT_group_offset,sector_offset;
 DWORD *buffer;
 BYTE i;
 
 if (Current_Cluster<2||Current_Cluster>=(current_fs->bpb.sector_per_FAT*current_fs->bpb.byte_per_sector/4))
  return 0;


 FAT_group_num = Current_Cluster>>FAT_GROUP_DWORD_SIZE_M;
 FAT_group_offset= Current_Cluster-(FAT_group_num<<FAT_GROUP_DWORD_SIZE_M);
 

 for(i=0;i<FAT_GROUP_NUM;i++)
 {
  if(FAT_group_num==fat_group_index[i])
  {
   buffer=(DWORD *)(fat_chain[i]);
   buffer[FAT_group_offset]=value;
   return 1;
  }
 }
 
 return 0;
}

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    基于ADSP-BF533的最小系统设…
    基于ADSP-BF533处理器的去方…
    ADSP-BF533 IDE_Base(C)源代…
    ADSP-BF533 IDE Access(C)源…
    ADSP-BF533 文件系统(C)源代…
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号