📄 fat.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 + -