⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 mp3播放器
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef __FAT_C__
#define __FAT_C__
//***********************************************
#include "dp8051.h"
#include "config.h"
#include "absacc.h"
#include "constant.h"
#include "variable.h"
#include "function.h"
#include "sdhost.h"
#include "sssmp3_regs.h"
#include "fat.h"
#include "mp3_appl.h"
//***********************************************
//***********************************************
xdata U8 sbuf1[512] _at_(0xE000);
xdata U8 sbuf2[512] _at_(0xF000);
//***********************************************
/************************************************
函 数 名: InitFat()
功    能:初始化Fat
说    明:
调    用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
U8 InitFat(void)
{
	//setting LBA = 0 to read MBR info. or BPB
	DMA_load_sector(0, 0x05);

	//Assume it is MBR, now load Boot Sector
	if((((((MBR *)sbuf1)->P1).x86Boot == 0x00)
		||((((MBR *)sbuf1)->P1).x86Boot == 0x80))
		&&((((((MBR *)sbuf1)->P1).PartitionType)& 0xF0)== 0x00))
	{
		if(((MBR *)sbuf1)->Signature != 0x55AA )
		{	//NOTE: must be 0x55AA in MBR      
	  		return FATERR_NO_DOSFORMAT;
    	}

		ENDIAN_ASSIGN_4( &CFatData.dwFatTabStartlba, &((MBR *)sbuf1)->P1.LogStartSector );	//not done yet! See below.
		//CFatData.dwFatTabStartlba = LE32(((MBR *)sbuf1)->P1.LogStartSector);

		//setting BPB LBA, load Boot Sector
		DMA_load_sector(CFatData.dwFatTabStartlba, 0x05);
//*********************************************
#if TX_DEBUG
    	//TXSend((Uint8 xdata *)0xE000);
#endif
//*********************************************
	}
  	else if((((BS16 *)sbuf1)->JmpCode[0] == 0xEB)
			&&(((BS16 *)sbuf1)->JmpCode[2] == 0x90)
			&&(((BS16 *)sbuf1)->Signature == 0x55AA))
	{
    	CFatData.dwFatTabStartlba = 0; //not done yet! See below.
	}
	else
  	{
		return FATERR_NO_DOSFORMAT;
	}
   
	if(((BS16 *)sbuf1)->FATSz16)
		CFatData.fFAT32 = 0;//FAT16 mode
	else
		CFatData.fFAT32 = 1; // FAT32 mode	
		
	// HERE: sbuf should be containing Boot sector ////
  if(CFatData.fFAT32)
  {//FAT32
 	ENDIAN_ASSIGN_2(&CFatData.wBytesPerSec, &((BS32 *)sbuf1)->BytesPerSector);
	//CFatData.wBytesPerSec = LE16(((BS32 *)sbuf1)->BytesPerSector);

	CFatData.bSectorsPerClu = ((BS32 *)sbuf1)->SectorsPerCluster;
 	CFatData.dwFatTabStartlba += ((U8 *)&((BS32 *)sbuf1)->ReservedSectors)[0]; 
 	ENDIAN_ASSIGN_4( &CFatData.dwSecNumInFat, &((BS32 *)sbuf1)->FATSz32);
	//CFatData.dwSecNumInFat = LE32(((BS32 *)sbuf1)->FATSz32);

    CFatData.dwClu2Startlba = CFatData.dwFatTabStartlba + CFatData.dwSecNumInFat *((U32)(((BS32 *)sbuf1)->NumFATs)); 
    ENDIAN_ASSIGN_4( &CFatData.dwRootStartCluNo, &((BS32 *)sbuf1)->RootClus);
	//CFatData.dwRootStartCluNo = LE32(((BS32 *)sbuf1)->RootClus);

    CFatData.dwRootStartlba = (CFatData.dwRootStartCluNo - 2)* CFatData.bSectorsPerClu + CFatData.dwClu2Startlba;
                
    CFatData.wSecNumInRoot = CFatData.bSectorsPerClu;
    FATTab.bShiftBits = 2;//Fat32 records each cluster by four bytes
	CFatData.dwMask = 0x0FFFFFFF;//fat32 using bit28~bit0

	//FAT32根目录簇链
    ReadRootCluster();
  }
  else
  {//FAT16
	ENDIAN_ASSIGN_2( &CFatData.wBytesPerSec, &((BS16 *)sbuf1)->BytesPerSector);
	//CFatData.wBytesPerSec = LE16(((BS16 *)sbuf1)->BytesPerSector);

    CFatData.bSectorsPerClu = ((BS16 *)sbuf1)->SectorsPerCluster;
    CFatData.dwFatTabStartlba += ((U8 *)&((BS16 *)sbuf1)->ReservedSectors)[0];
    //ENDIAN_ASSIGN_2( &varAl.TmpShort, &((BS16 *)sbuf1)->FATSz16); 
    //CFatData.dwSecNumInFat = (0x0000FFFF)&((ULONG)varAl.TmpShort);
	CFatData.dwSecNumInFat = ((U32)LE16(((BS16 *)sbuf1)->FATSz16))& 0x0000FFFF;

    ENDIAN_ASSIGN_2(&CFatData.wSecNumInRoot, &((BS16 *)sbuf1)->RootDirEntries);
	//CFatData.wSecNumInRoot = LE16(((BS16 *)sbuf1)->RootDirEntries);

    FileData.RootDirNum = (U32)CFatData.wSecNumInRoot;
    CFatData.wSecNumInRoot <<= 5;//Each FDB = 32bytes
    CFatData.wSecNumInRoot /= CFatData.wBytesPerSec;
    CFatData.dwRootStartlba = CFatData.dwFatTabStartlba + CFatData.dwSecNumInFat *((U32)(((BS16 *)sbuf1)->NumFATs)); 
    CFatData.dwRootStartCluNo = 0;//Assigning "0" to the start cluster# of root for fat16 mode.
    CFatData.dwClu2Startlba = CFatData.dwRootStartlba +(U32)CFatData.wSecNumInRoot; 
    FATTab.bShiftBits = 1;//Fat16 records each cluster by two bytes.  
    CFatData.dwMask = 0x0000FFFF; 
  }
        
  CFatData.bFDBNumInSec = (U8)(CFatData.wBytesPerSec / DIREntrySize);//Coutning the number of FDB in one sector.
  return FATERR_NO_ERROR;
}
/************************************************
函 数 名: Forward()
功    能:
说    明:
调    用:
全局变量:
入口参数:无
出口参数:无
返 回 值:
************************************************/
bit Forward(void)
{
  bit flag = 0;
  U8 index;
  U32 position;
  if(CFatData.fFAT32)
  {
    //FAT32
    for(;FileData.dwCurCluNo < FileData.RootDirNum;)
	{
      position = FileData.dwCurCluNo;
	  for(index = 0; index  < MAX_FILE_FRAGMENT_NUMBER; index++)
	  {
	    if(position < rootclusters[index].number)
	    {
	      position = rootclusters[index].cluster + position;
	      break;
		}
		else
		{
		  position -= rootclusters[index].number;
		}
	  }
	  position = CFatData.dwClu2Startlba + (position - 2)* (U32)CFatData.bSectorsPerClu;
      
	  for(;FileData.wCurFDBNo < (U16)CFatData.bSectorsPerClu * CFatData.wBytesPerSec / DIREntrySize;)
	  {
	    //position += FileData.wCurFDBNo / DIREntrySize / CFatData.wBytesPerSec;
		if(!flag)
		{
		  DMA_load_sector(position + FileData.wCurFDBNo * DIREntrySize / CFatData.wBytesPerSec, 0x05);
          flag = 1;
		}
        if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute != 0x0F)
          &&((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute & ARCHIVE_DIR) != ARCHIVE_DIR))
	    {
		  if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[0] == (S8)'M')
		    &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[1] == (S8)'P')
		    &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[2] == (S8)'3')
		    &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Unused)
		    &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Deleted))
		  {
		    ENDIAN_ASSIGN_4(&FileData.dwFileDataSize,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
			FileData.dwFileStartCluNo = CFatData.dwMask &((U32)LE16(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO));
            FileData.dwFileStartCluNo += CFatData.dwMask &(((U32)LE16(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusHI)) << 16);
            ReadFileFAT();
            return OK;
		  }
		  else
		  {
		    FileData.wCurFDBNo++;
		    if(!(FileData.wCurFDBNo & 0x0F))
		      flag = 0;
		  }
	    }
		else
		{
		  FileData.wCurFDBNo++;
		  if(!(FileData.wCurFDBNo & 0x0F))
		    flag = 0;
		}
	  }
      FileData.wCurFDBNo = 0;
      FileData.dwCurCluNo++;
	}
    return KO;
  }
  else
  {
    //FAT16
	for(;FileData.wCurFDBNo < (U16)FileData.RootDirNum;)
	{
	  if(!flag)
	  {
	    DMA_load_sector(CFatData.dwRootStartlba + (FileData.wCurFDBNo / CFatData.bFDBNumInSec),0x05);
		flag = 1;
	  }
	  if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute != 0x0F)
        &&((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute & ARCHIVE_DIR) != ARCHIVE_DIR))
	  {
		if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[0] == (S8)'M')
		  &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[1] == (S8)'P')
		  &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[2] == (S8)'3')
		  &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Unused)
		  &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Deleted))
		{
		  ENDIAN_ASSIGN_4(&FileData.dwFileDataSize,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
		  //FileData.dwFileDataSize = LE32(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);

		  //ENDIAN_ASSIGN_2(&varAl.TmpShort,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO); 
          //FileData.dwFileStartCluNo = (0x0000FFFF)&((Uint32)varAl.TmpShort);
		  FileData.dwFileStartCluNo = CFatData.dwMask &((U32)LE16(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO));

		  //CFatData.fRet = FATERR_NO_ERROR;
		  //将该文件FAT表读出并放到SRAM中
		  ReadFileFAT();

		  //varAl.WAVE_Flg = 0;
		  return OK;
	    }
		/*else if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[0] == 'W')
		       &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[1] == 'A')
		       &&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[2] == 'V'))
		{
		  ENDIAN_ASSIGN_4(&FileData.dwFileDataSize,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
		  ENDIAN_ASSIGN_2(&varAl.TmpShort,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO); 
          FileData.dwFileStartCluNo = (0x0000FFFF)&((Uint32)varAl.TmpShort);

		  //CFatData.fRet = FATERR_NO_ERROR;
		  FileData.wCurFDBNo++;
		  
		  //将该文件FAT表读出并放到SRAM中,起始地址为0xD000
		  ReadFileFAT();
		  varAl.WAVE_Flg = 1;
		  return(1);
		}*/
		else
		{
		  FileData.wCurFDBNo++;
		  if(!(FileData.wCurFDBNo & 0x0F))
		    flag = 0;
		}
	  }
	  else
	  {
	    FileData.wCurFDBNo++;
		if(!(FileData.wCurFDBNo & 0x0F))
		  flag = 0;
	  }
    }
	//CFatData.fRet = FATERR_NO_FILE;
#if TX_DEBUG
    //SendChar(0xC1);
#endif
	return KO;
  }
}
/************************************************
函 数 名: Backward()
功    能:
说    明:
调    用:
全局变量:
入口参数:无
出口参数:无
返 回 值:
************************************************/
bit Backward(void)
{
  bit flag = 0;
  U8 index;
  U32 position;
  if(CFatData.fFAT32)
  {
    //FAT32
	varAl.TmpShort = FileData.wCurFDBNo;
	varAl.TmpLong = FileData.dwCurCluNo;
	if(FileData.wCurFDBNo)
	  FileData.wCurFDBNo--;
	else
	{
	  FileData.wCurFDBNo = (U16)CFatData.bSectorsPerClu * CFatData.wBytesPerSec / DIREntrySize - 1;
	  if(FileData.dwCurCluNo)
	    FileData.dwCurCluNo--;
	  else
	    FileData.dwCurCluNo = FileData.RootDirNum - 1;
	}
    for(;;)
	{
	  position = FileData.dwCurCluNo;
	  for(index = 0; index  < MAX_FILE_FRAGMENT_NUMBER; index++)
	  {
	    if(position < rootclusters[index].number)
	    {
	      position = rootclusters[index].cluster + position;
	      break;
		}
		else
		{
		  position -= rootclusters[index].number;
		}
	  }
	  position = CFatData.dwClu2Startlba + (position - 2)* (U32)CFatData.bSectorsPerClu;
      for(;FileData.wCurFDBNo < (U16)CFatData.bSectorsPerClu * CFatData.wBytesPerSec / DIREntrySize;)
      {
	    if(!flag)
	  	{
	      DMA_load_sector(position + FileData.wCurFDBNo * DIREntrySize / CFatData.wBytesPerSec, 0x05);
		  flag = 1;
	    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -