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

📄 fat.c

📁 Mp3 Player using ATmega128, VS1003B, Character LCD. Test OK.Good Sound.
💻 C
字号:
/*
-------------------------------------------------------------------------------
* 力格			: FAT32 Interface Code
* 颇老疙		: fat.c
* 父电 荤恩		: kkamcneko@naver.com
* 父电 朝楼		: 2005-11-11
* 荐沥茄 朝楼	: 2005-12-29
* Version		: 0.1
* Target MCU	: AVR ATMega128
* 徘 荤捞令		: 4
* 眠玫 俊叼磐	: EditPlus (http://www.editplus.com)
-------------------------------------------------------------------------------
*/

// Standard Header files
#include <string.h>
#include "../global.h"
#include "fat.h"
#include "filelist.h"
#include "../sd/sd.h"
#include "../usart.h"

// global variables
U8 SecPerClus;					// 茄 Cluster寸 sector 荐(Sector per Cluster)
U32 FirstDataSector;			// 霉锅掳 单捞磐 冀磐(焊烹 风飘叼泛配府 浚飘府狼 困摹烙)
U32 StartFATSector;				// FAT 矫累 冀磐
U32 RootCluster;				// Root Directory狼 努矾胶磐 锅龋(老馆利栏肺 2)

struct tagFATBuffer FATBuffer;	// FAT Buffer(1冀磐甫 佬绢坷扁 困茄 滚欺)
struct tagDirEntryBuffer DirEntryBuffer;	// 叼泛磐府 浚飘府 Buffer

int fatInit(void)
{
	struct tagPartTable* partTable_ptr;
	struct tagBootSector* bootSector_ptr;
	struct tagBPB32* bpb32_ptr;

	U8 buffer[SECTOR_SIZE];	// 512 bytes

// 鞘夸 绝绢 林籍贸府
//	U32 RootDirSectors;

	U32 StartLBASector;			// 霉锅掳 颇萍记狼 矫累冀磐(何飘冀磐)
	U32 FATSz = 0;

	SD_Read_Sector(MBR_ADDR, buffer);	// MBR_ADDR : 0

	partTable_ptr = (struct partTable_ptr *) (buffer + 446);	// First Partition Table Offset: 446

	// 茄俺狼 颇萍记父 荤侩茄促绊 啊沥窍绊, 2,3,4锅掳 颇萍记 沥焊绰 佬瘤 臼澜
	
	StartLBASector = partTable_ptr->StartLBA;


	// 霉锅掳 颇萍记狼 矫累冀磐(何飘冀磐)甫 佬绰促.
	SD_Read_Sector(StartLBASector, buffer);		

	bootSector_ptr = (struct tagBootSector *) buffer;
	bpb32_ptr = (struct tagBPB32 *) (buffer + 36);	// BPB Offset: 36

	// FAT狼 矫累冀磐甫 备窃
	StartFATSector = StartLBASector + bootSector_ptr->BPB_RsvdSecCnt;

	// 风飘叼泛磐府 冀磐甫 备窃
	// 鞘夸 绝绢 林籍贸府
//	RootDirSectors = ((bootSector_ptr->BPB_RootEntCnt * 32) + 
//		(bootSector_ptr->BPB_BytesPerSec - 1)) / bootSector_ptr->BPB_BytesPerSec;


	FATSz = bpb32_ptr->BPB_FATSz32;			// 1俺狼 FAT抛捞喉捞 瞒瘤窍绰 冀磐荐

	// 霉锅掳 单捞磐 冀磐甫 备窃
	// 鞘夸 绝绢 林籍贸府(RootDirSectors 何盒 昏力)
//	FirstDataSector = StartLBASector + bootSector_ptr->BPB_RsvdSecCnt + 
//		(bootSector_ptr->BPB_NumFATs * FATSz) + RootDirSectors;
	FirstDataSector = StartLBASector + bootSector_ptr->BPB_RsvdSecCnt + 
		(bootSector_ptr->BPB_NumFATs * FATSz);

	// 1扁啊 SD狼 版快 努矾胶磐寸 冀磐荐啊 8
	SecPerClus = bootSector_ptr->BPB_SecPerClus;	// 努矾胶磐寸 冀磐荐甫 傈开函荐俊 历厘秦 狄
	RootCluster = bpb32_ptr->BPB_RootClus;			// 风飘叼泛磐府狼 努矾胶磐 锅龋甫 傈开函荐俊 历厘秦 狄(焊烹2)

	return 0;
}

// 泅犁叼泛磐府郴狼 阿 颇老狼 努矾胶磐 林家客 浚飘府 困摹蔼阑 备窃(100俺鳖瘤)
U32 fatGetDirEntry(U32 cluster)
{
	struct tagDirEntry *dirEntry_ptr = 0;
	
	U32 sector;
	U8 nextSector;
	U32 curCluster, nextCluster;
	U8 buffer[SECTOR_SIZE];			// 512 bytes
	U8 index = (SECTOR_SIZE / 32);		// 茄冀磐寸 叼泛配府 浚飘府啊 16俺 粮犁(1冀磐 512byte / 32byte = 16俺)
	U8 entryCount = 0;
	U8 hasNext = 1;

	nextSector = SecPerClus;			// 8 (1GB SD墨靛绰 努矾胶磐寸 8冀磐)
	curCluster = cluster;
	sector = fatClusToSec(curCluster);	// 浚飘府啊 困摹茄 冀磐甫 备窃
	fatDirEntryBufferInit();			// Directory Entry Buffer 檬扁拳

	do
	{
		if(index == 16)		// 茄冀磐狼 葛电 叼泛磐府 浚飘府甫 佬菌栏搁, 促澜 冀磐肺...
		{
			if(nextSector == 0)	// 泅犁 努矾胶磐甫 葛滴 佬菌栏搁, 促澜 努矾胶磐肺 捞悼
			{
				if((nextCluster = fatGetNextCluster(curCluster)) == 0xFFFFFFFF)	// 努矾胶磐狼 场捞搁
					break;

				curCluster = nextCluster;
				sector = fatClusToSec(curCluster);	// 努矾胶磐 林家甫 角力 冀磐 林家肺 函券
				nextSector = SecPerClus;
				entryCount = 0;
			}

			if(SD_Read_Sector(sector++, buffer) != 0)
			{
				return -1;
			}

			dirEntry_ptr = (struct tagDirEntry *) buffer;
			index = 0;
			nextSector--;
		}

		// 厚绢乐绰 浚飘府啊 酒聪搁
		if( (dirEntry_ptr->DIR_Name[0] != DIR_ENTRY_IS_FREE) | (dirEntry_ptr->DIR_Name[0] != SPACE) )
		{
			if(hasNext)	// 促澜浚飘府肺 逞绢 艾栏搁,
				fatDirEntryBufferInsert(curCluster, entryCount);

			// 变 捞抚 颇老捞搁 0
			hasNext = dirEntry_ptr->DIR_Attr == ATTR_LONG_NAME ? 0 : 1;
		}

		index++;
		entryCount++;
		dirEntry_ptr++;	// move to next entry(32官捞飘究 器牢磐 刘啊)
	}
	while(dirEntry_ptr->DIR_Name[0] && !fatDirEntryBufferIsFull());	// DIR_Name[0] = 0 : no more entries

	return 0;
}

// cluster:entry 林家甫 涝仿窍搁 秦寸 颇老狼 沥焊甫 府畔
struct tagFileInfo fatGetFileInfo(U32 cluster, U8 entry)
{
	struct tagDirEntry *dirEntry_ptr = 0;
	struct tagLongDirEntry *longDirEntry_ptr = 0;
	struct tagFileInfo fileInfo;
	
	U16 i, j;
	U32 sector;
	U8 nextSector;
	U32 curCluster, nextCluster;
	U8 buffer[SECTOR_SIZE];	// 512 bytes
	U8 index = entry % 16;
	U8 seqNumOffset;
	U8 longName[256+1] = {0,};	// 变 捞抚篮 弥措 256巩磊(檬扁拳 救窍搁 颇老疙 第俊 静饭扁蔼 嘿澜)
	U16 wchar, result;
	U8 hasLongName = 0;	// 变 捞抚 浚飘府烙阑 钎矫

	nextSector = (SecPerClus - 1) - (entry / 16);		// 1GB SD墨靛绰 努矾胶磐寸 8冀磐
	curCluster = cluster;
	sector = fatClusToSec(curCluster) + (entry / 16);	// 浚飘府啊 困摹茄 冀磐甫 备窃

	SD_Read_Sector(sector++, buffer);	// 冀磐甫 佬澜

	dirEntry_ptr = (struct tagDirEntry *) buffer;
	dirEntry_ptr += (entry % 16);	// 浚飘府 困摹肺 器牢磐 捞悼

	do
	{
		if(index == 16)	// 泅犁 冀磐狼 付瘤阜 浚飘府搁
		{
			// 叼泛磐府 浚飘府啊 促澜冀磐唱 努矾胶磐肺 拌加 捞绢瘤绰 版快
			if(nextSector == 0)	// 促澜 努矾胶磐肺 捞悼
			{
				if((nextCluster = fatGetNextCluster(curCluster)) == 0xFFFFFFFF)	// 努矾胶磐狼 场捞搁
					break;

				curCluster = nextCluster;
				sector = fatClusToSec(curCluster);	// 努矾胶磐 林家甫 角力 冀磐 林家肺 函券
				nextSector = SecPerClus;
			}
		
			if(SD_Read_Sector(sector++, buffer) != 0)
			{
			}

			dirEntry_ptr = (struct tagDirEntry *) buffer;
			index = 0;
			nextSector--;
		}

		if(dirEntry_ptr->DIR_Name[0] != DIR_ENTRY_IS_FREE)	// 厚绢乐绰 浚飘府啊 酒聪搁
		{
			if(dirEntry_ptr->DIR_Attr == ATTR_LONG_NAME)	// 变 捞抚 颇老捞搁
			{
				hasLongName = 1;	// 变 捞抚 浚飘府烙阑 钎矫
				longDirEntry_ptr = (struct tagLongDirEntry_ptr *) dirEntry_ptr;

				// 变捞抚 浚飘府绰 开鉴栏肺 历厘登绢 乐栏骨肺,
				// 2俺搁 26锅何磐 捞抚阑 盲况持绊, 促澜 浚飘府俊绰 0锅何磐 盲况持绰促.
				// 1俺搁 官肺 0锅何磐 盲况 持绰促.
				seqNumOffset = ((longDirEntry_ptr->LDIR_Ord & ~0x40) - 1) * 26;	// additional entry = 40 | N

				for(i=0; i<10; i++)
					longName[seqNumOffset++] = longDirEntry_ptr->LDIR_Name1[i];	// copy first part				
				for(i=0; i<12; i++)
					longName[seqNumOffset++] = longDirEntry_ptr->LDIR_Name2[i];	// second part
				for(i=0; i<4; i++)
					longName[seqNumOffset++] = longDirEntry_ptr->LDIR_Name3[i];	// and third part
			}
			else
			{	
				if(hasLongName)	// 变 捞抚 浚飘府搁
				{
					for(i=0,j=0; longName[i] != 0xFF; i+=2)
					{
						wchar = longName[i+1];	// high byte
						wchar <<= 8;
						wchar |= longName[i];	// low byte

						if(wchar == 0x0000)
							break;

						if(wchar >= 0xAC00 && wchar <= 0xD7AF)	// 茄臂捞搁
						{
							result = uniToKssm(wchar);	// 蜡聪内靛甫 炼钦屈栏肺 函券
							fileInfo.fileName[j++] = result >> 8;		// high byte
							fileInfo.fileName[j++] = result & 0x00FF;	// low byte
						}
						else if(wchar >= 0x0000 && wchar <= 0x007F)	// 康巩捞搁
							fileInfo.fileName[j++] = wchar;	// 窍困官捞飘父 荤侩(惑困 官捞飘绰 肋覆)
					}
					fileInfo.fileName[j] = 0;
				}
				else	// 陋篮 捞抚 浚飘府搁
				{
					strcpy(fileInfo.fileName, dirEntry_ptr->DIR_Name);
					fatFormalizeFileName(fileInfo.fileName);	// 8.3 痹拜俊 嘎档废 捞抚 函版
				}
	
				fileInfo.attr = dirEntry_ptr->DIR_Attr;		// 颇老 加己阑 备窃
				fileInfo.size = dirEntry_ptr->DIR_FileSize;	// 颇老 农扁甫 备窃

				// 颇老狼 矫累 努矾胶磐甫 备窃
				fileInfo.startCluster = dirEntry_ptr->DIR_FstClusHI;
				fileInfo.startCluster <<= 16;
				fileInfo.startCluster |= dirEntry_ptr->DIR_FstClusLO;

				break;		// 颇老狼 沥焊甫 葛滴 掘菌栏搁 风橇巩 呕免
			}
		}
		
		index++;
		dirEntry_ptr++;	// move to next entry
	}
	while(dirEntry_ptr->DIR_Name[0]);

	return fileInfo;
}


U32 fatGetNextCluster(U32 cluster)
{
	U32 entryPerSec;	// 冀磐寸 FAT 浚飘府狼 俺荐
	U32 nextCluster;	// 促澜 努矾胶磐
	U32 FATsec;			// FAT 浚飘府啊 乐绰 冀磐
	U32 FATSecOffset;	// FAT 矫累冀磐何磐 茫绊 乐绰 FAT浚飘府啊 乐绰 冀磐狼 惑措困摹蔼
	U32 temp;
	U32 index;			// 冀磐郴俊辑 茫绊 乐绰 FAT 浚飘府狼 惑措困摹蔼

	entryPerSec = SECTOR_SIZE / 4;	// FAT 浚飘府 茄俺寸 4Bytes 
	FATSecOffset = cluster / entryPerSec;
	FATsec = StartFATSector + FATSecOffset;

	if(FATsec != FATBuffer.lastSector)	// 滚欺俊 乐绰瘤 犬牢
		fatBufferInit(cluster);	// 绝栏搁 滚欺甫 檬扁拳

	index = (cluster - (FATSecOffset * entryPerSec)) * 4;

	// FAT 浚飘府 4byte蔼阑 历厘
	nextCluster = FATBuffer.buffer[index];

	temp = FATBuffer.buffer[index+1];
	nextCluster |= temp << 8;

	temp = FATBuffer.buffer[index+2];
	nextCluster |= temp << 16;

	temp = FATBuffer.buffer[index+3];
	nextCluster |= temp << 24;

	// mask for FAT32 cluster numbers
	nextCluster = nextCluster & 0x0FFFFFFF;

	if(nextCluster == 0x0FFFFFFF)	// 颇老狼 场捞搁
		return 0xFFFFFFFF;
	else 
		return nextCluster;
}

/*
U32 fatGetPrevCluster(U32 startCluster, U32 curCluster)
{
	U32 nextCluster, cluster = startCluster;

	if(startCluster == curCluster)
		return startCluster;

	do
	{
		if((nextCluster = fatGetNextCluster(cluster)) == curCluster)
			return cluster;
		cluster = nextCluster;
	}
	while(cluster != 0xFFFFFFFF);
}
*/

// 努矾胶磐 林家甫 冀磐 林家肺 函券秦淋
U32 fatClusToSec(U32 cluster)
{
	return ((cluster - 2) * SecPerClus) + FirstDataSector;
}

void fatBufferInit(U32 cluster)
{
	U32 entryPerSec;	// 冀磐寸 FAT 浚飘府狼 俺荐
	U32 FATsec;			// FAT 浚飘府啊 乐绰 冀磐
	U32 FATSecOffset;	// FAT 矫累冀磐何磐 茫绊 乐绰 FAT浚飘府啊 乐绰 冀磐狼 惑措困摹蔼

	entryPerSec = SECTOR_SIZE / 4;	// FAT 浚飘府 茄俺寸 4Bytes 
	FATSecOffset = cluster / entryPerSec;
	FATsec = StartFATSector + FATSecOffset;

	FATBuffer.lastSector = FATsec;		// FAT 冀磐林家甫 历厘
	SD_Read_Sector(FATsec, FATBuffer.buffer);	// FAT 冀磐甫 历厘

}

void fatDirEntryBufferInit()
{
	DirEntryBuffer.index = 0;
}

int fatDirEntryBufferInsert(U32 cluster, U8 entry)
{
	if(fatDirEntryBufferIsFull())
		return -1;
	
	DirEntryBuffer.cluster[DirEntryBuffer.index] = cluster;
	DirEntryBuffer.entry[DirEntryBuffer.index] = entry;
	DirEntryBuffer.index++;

	return 0;
}

U8 fatDirEntryBufferIsFull(void)
{
	if(DirEntryBuffer.index == ENTRY_BUF_SIZE)
		return 1;
	else
		return 0;
}

// 颇老疙阑 8.3 器杆俊 嘎苗 函券秦 淋
void fatFormalizeFileName(U8 *fileName)
{
	U8 i, j;
	U8 str[8+1+3+1];	// Name[8], Dot[1], Ext[1], NULL[1]

	// 捞抚阑 眠免
	for(i=0,j=0; i<8; i++,j++)
	{
		if(fileName[i] == 0x20)
			break;
		str[j] = fileName[i];
	}	

	if(fileName[8] != 0x20)	// 犬厘磊啊 粮犁窍搁
	{
		str[j++] = '.';
		for(i=8; i<11; i++,j++)	// 犬厘磊 眠免
		{
			if(fileName[i] == 0x20)
				break;
			str[j] = fileName[i];
		}
	}

	str[j] = 0;

	strcpy(fileName, str);
}


// 蜡聪内靛 茄臂阑 炼钦屈栏肺 函券
unsigned int uniToKssm(U16 wchar)
{
	U16 cho, joong, jong;
	U16 result = 0x8000;

	// 檬己阑 眠免
	cho = 2 + (wchar - 0xAC00) / (21*28);

	// 吝己阑 眠免
	joong = (wchar - 0xAC00) % (21*28) / 28;
	if(joong < 5)
		joong += 3;
	else if(joong < 11)
		joong += 5;
	else if(joong < 17)
		joong += 7;
	else
		joong += 9;

	// 辆己阑 眠免
	jong  = (wchar - 0xAC00) % 28;
	if(jong < 17)
		jong++;
	else
		jong += 2;

	// 檬己 + 吝己 + 辆己 = 炼钦屈 茄臂
	result |= cho << 10;
	result |= joong << 5;
	result |= jong;

	return result;
}

⌨️ 快捷键说明

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