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

📄 fat16avr2004.c

📁 移植到mega32上面的fat16代码实现了
💻 C
📖 第 1 页 / 共 4 页
字号:
//*****************************************************************************
//
// Title		: FAT16/32 file system driver for ATMEL AVR
// Authors		: Project A3670
// File Name	: 'fat.c'
// Date			: April 26, 2004
// Version		: 1.00
// Target MCU	: Atmel AVR Series
// Editor Tabs	: 4
//
// NOTE: The authors in no way will be responsible for damages that you coul'd be using this code.
//       Use this code at your own risk.
//
//       This code is distributed under the GNU Public License
//       which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <string.h>


#include "ata.h"
#include "fat.h"
#include "fatconf.h"
#include "fattime.h"

// globals
unsigned char *SectorBuffer  =		(unsigned char *) SECTOR_BUFFER_ADDR;	// Sector Buffer
unsigned char *FatCache =			(unsigned char *) FAT_CACHE_ADDR;		// Fat Buffer
char VolLabel[12];							// Volume Label

struct partrecord PartInfo;					// Partition Information
TFILE File;									// File Information
unsigned long FSInfo;						// File System Information
unsigned char Fat32Enabled;					// Indicates if is FAT32 or FAT16
unsigned long FirstDataSector;				// First Data Sector Address
unsigned int  SectorsPerCluster;			// Number of Sectors per Cluster
unsigned long FirstFATSector;				// First FAT Sector Address
unsigned long FirstFAT2Sector;				// First FAT2 Sector Address
unsigned long FirstDirCluster;				// First Directory (Data) Cluster Address
unsigned long FatInCache = 0xFFFFFFFF;		// Address of the FAT Cluster in FatCache
unsigned long FatSectors;					// Number of FAT Sectors
unsigned long currentDirCluster;			// Actual Dir Cluster Number
unsigned long NumClusters;					// ATA Dispositive Cluster Numbers
unsigned long SectorInCache = 0xFFFFFFFF;	// Address of the Sector Cluster in SectorBuffer



//*****************************************************************************
// Function: fatClustToSect
// Parameters: cluster
// Returns: sector
//
// Description: Converts Sectors in Clusters
//*****************************************************************************
unsigned long fatClustToSect(unsigned long clust)
{
	if (clust == 0)
		clust=2;
	return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}


//*****************************************************************************
// Function: fatSectToClust
// Parameters: sector
// Returns: cluster
//
// Description: Converts Clusters in Sectors
//*****************************************************************************
unsigned long fatSectToClust(unsigned long sect)
{
	return (((sect - FirstDataSector) / SectorsPerCluster) + 2);
}


//*****************************************************************************
// Function: fatInit
// Parameters: none
// Returns: TRUE if a FAT drive was found, FALSE otherwise
//
// Description: Get FAT info from ATA dispositive and initialize internal variables
//*****************************************************************************
unsigned char fatInit(void)
{
	struct bpb710 *bpb;

	// read partition table
	ataReadSectors(DRIVE0, 0, SectorBuffer, &SectorInCache);

	// map first partition record
	// save partition information to global PartInfo
	PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart);

	// Read the Partition BootSector
	// **first sector of partition in PartInfo.prStartLBA
	ataReadSectors( DRIVE0, PartInfo.prStartLBA, SectorBuffer, &SectorInCache );

	bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;

	// setup global disk constants
	FirstDataSector	= PartInfo.prStartLBA;
	if(bpb->bpbFATsecs)
	{
		// bpbFATsecs is non-zero and is therefore valid
		FirstDataSector	+= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
	}
	else
	{
		// bpbFATsecs is zero, real value is in bpbBigFATsecs
		FirstDataSector	+= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
	}
	SectorsPerCluster	= bpb->bpbSecPerClust;
	FirstFATSector		= bpb->bpbResSectors + PartInfo.prStartLBA;
	FatSectors			= bpb->bpbBigFATsecs;
	NumClusters			= ataGetSizeInSectors()/(bpb->bpbSecPerClust);

	// initialize Volume Label
	memcpy(&VolLabel, bpb->bpbVolLabel, 11);
	VolLabel[11]='\0';

	switch (PartInfo.prPartType)
	{
		case PART_TYPE_DOSFAT16:
		case PART_TYPE_FAT16:
		case PART_TYPE_FAT16LBA:
			// first directory cluster is 2 by default (clusters range 2->big)
			FirstDirCluster	= CLUST_FIRST;
			// push data sector pointer to end of root directory area
			//FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
			Fat32Enabled = FALSE;
			break;
		case PART_TYPE_FAT32LBA:
		case PART_TYPE_FAT32:
			// bpbRootClust field exists in FAT32 bpb710, but not in lesser bpb's
			FirstDirCluster = bpb->bpbRootClust;
			// push data sector pointer to end of root directory area
			// need this? FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
			Fat32Enabled = TRUE;
			break;
		default:
			//Found: No Partition!
			return FALSE;
			break;
	}

	if (Fat32Enabled)
		FirstFAT2Sector=FirstFATSector+bpb->bpbBigFATsecs;
	else
		FirstFAT2Sector=FirstFATSector+bpb->bpbFATsecs;
	FSInfo=bpb->bpbFSInfo+PartInfo.prStartLBA;

	currentDirCluster= FirstDirCluster;

	return TRUE;
}


//*****************************************************************************
// Function: fatNextCluster
// Parameters: cluster
// Returns: the next cluster
//
// Description: Find next cluster in the FAT chain
//*****************************************************************************
unsigned long fatNextCluster(unsigned long cluster)
{
	unsigned long nextCluster;
	unsigned long fatMask;
	unsigned long fatOffset;
	unsigned long sector;
	unsigned int offset;

	// get fat offset in bytes
	if(Fat32Enabled)
	{
		// four FAT bytes (32 bits) for every cluster
		fatOffset = cluster << 2;
		// set the FAT bit mask
		fatMask = FAT32_MASK;
	}
	else
	{
		// two FAT bytes (16 bits) for every cluster
		fatOffset = cluster << 1;
		// set the FAT bit mask
		fatMask = FAT16_MASK;
	}

	// calculate the FAT sector that we're interested in
	sector = FirstFATSector + (fatOffset / BYTES_PER_SECTOR);
	// calculate offset of the our entry within that FAT sector
	offset = fatOffset % BYTES_PER_SECTOR;

	// if we don't already have this FAT chunk loaded, go get it
	ataReadSectors( DRIVE0, sector, (unsigned char*)FAT_CACHE_ADDR, &FatInCache);


	// read the nextCluster value
	nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;

	// check to see if we're at the end of the chain
	if (nextCluster == (CLUST_EOFE & fatMask))
		nextCluster = 0;

	return nextCluster;
}



//*****************************************************************************
// Function: fatClusterSize
// Parameters: none
// Returns: the size of a cluster in sectors
//
// Description: return the number of sectors in a disk cluster
//*****************************************************************************
unsigned int fatClusterSize(void)
{
	return SectorsPerCluster;
}


//*****************************************************************************
// Function: fatGetFirstDirCluster
// Parameters: none
// Returns: the cluster number of the first dir entry in FAT
//
// Description: return the first dir entry cluster in FAT
//*****************************************************************************
unsigned long fatGetFirstDirCluster(void)
{
	return(FirstDirCluster);
}


//*****************************************************************************
// Function: fatGetPartInfo
// Parameters: none
// Returns: FAT partition information
//
// Description: return the partition information read in fatInit routine
//*****************************************************************************
struct partrecord *fatGetPartInfo(void)
{
	return (&PartInfo);
}



//*****************************************************************************
// Function: fatGetSecPerClust
// Parameters: none
// Returns: the number of Sectors per Cluster
//
// Description: return the number of Sectors per Cluster read in fatInit
//*****************************************************************************
unsigned int fatGetSecPerClust(void)
{
	return SectorsPerCluster;
}


//*****************************************************************************
// Function: fatGetFirstFATSector
// Parameters: none
// Returns: the address of the first FAT Sector
//
// Description: return the sector address of the first FAT
//*****************************************************************************
unsigned long fatGetFirstFATSector(void)
{
	return(FirstFATSector);
}


//*****************************************************************************
// Function: fatGetFirstFAT2Sector
// Parameters: none
// Returns: the address of the first second FAT Sector
//
// Description: return the sector address of the second FAT
//*****************************************************************************
unsigned long fatGetFirstFAT2Sector(void)
{
	return(FirstFAT2Sector);
}


//*****************************************************************************
// Function: fatGetFirstDataSector
// Parameters: none
// Returns: the address of the first data Sector
//
// Description: return the sector address of the data in FAT
//*****************************************************************************
unsigned long fatGetFirstDataSector(void)
{
	return(FirstDataSector);
}


//*****************************************************************************
// Function: fatGetNumClusters
// Parameters: none
// Returns: the total number of clusters
//
// Description: return the total number of clusters in the ata dispositive
//*****************************************************************************
unsigned long fatGetNumClusters(void)
{
	return(NumClusters);
}



//*****************************************************************************
// Function: fatDir
// Parameters: initial cluster, offset
// Returns: On SUSCEFULL returns the sector with direntries info, otherwise
//          returns NULL
//
// Description: return the sector with direntries info starting in the cluster,
//              and with offset sectors from the begining cluster sector
//*****************************************************************************
unsigned char *fatDir(unsigned long cluster, unsigned long offset)
{
	unsigned long index;

	for (index=0; index < offset/SectorsPerCluster; index++)
		cluster=fatNextCluster(cluster);

	if (cluster == 0)
		return NULL;

	ataReadSectors(DRIVE0, fatClustToSect(cluster)+ offset%SectorsPerCluster, SectorBuffer, &SectorInCache);
	return SectorBuffer;
}



//*****************************************************************************
// Function: fatGetFileInfo
// Parameters: address of direntry struct, short name of the file
// Returns: On SUSCEFULL, return the direntry struct filled out with the file info,
//          otherwise returns NULL;
//
// Description: return the direntry struct of a short name file given
//              this function will search for a filename only in the current
//              directory, given by currentDirCluster
//*****************************************************************************
struct direntry *fatGetFileInfo(struct direntry *rde, char *shortName)
{
	unsigned long sector=0, cluster;
	struct direntry *de;

⌨️ 快捷键说明

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