📄 fat.c
字号:
}
if (j==SF_NAME_LENGTH)
break; // 8+3
}
while (j<SF_NAME_LENGTH)
fname[j++]=' ';
fname[j]=PATH_NAME_CHAR_END; // NULL
*nSfnameconv = 1;
}
/*************************************************************/
/* Check if two long file name is match or not */
/*************************************************************/
void FAT_Compare2LFileName(u32 slength, short *s, char *p, int* nChkmatch, SDHC* sCh)
{
u32 i;
if (slength!=strlen(p))
*nChkmatch = 0;
for (i=0; i<slength; i++) {
if (s[i]==p[i] || ((s[i]-0x20)==p[i]&&s[i]>=0x61&&s[i]<=0x71))
continue;
else
*nChkmatch = 0;
}
*nChkmatch = 1;
}
/************************************************************/
/* Get the unicode character string nLength */
/************************************************************/
void FAT_GetUnicodeStrLen(short *s, int* nUniChr, SDHC* sCh)
{
int i;
if (s==NULL)
*nUniChr = 0;
for (i=0; i<260; i++)
{
if (*s==0)
break;
else
s++;
}
*nUniChr = i;
}
/************************************************************/
/* Convert unicode to char (direct=0) or reverse (direct=1) */
/************************************************************/
void FAT_ConvertUnicode(short *s, char *p, int direct, int* nConvUni, SDHC* sCh)
{
int i, nLen=0;
if (direct==UNICODE2CHAR)
{
FAT_GetUnicodeStrLen(s, &nLen, sCh);
for (i=0; i<=nLen; i++)
*p++ = (char)*s++;
}
else if (direct==CHAR2UNICODE)
{
nLen = strlen(p);
for (i=0; i<=nLen; i++)
*s++ = *p++;
s = s-nLen-1;
p = p-nLen-1;
}
*nConvUni = nLen;
}
/*****************************************************************/
/* check if two long file name in unicode format is match or not */
/*****************************************************************/
void FAT_Compare2UnicodeLFileName(short *s1, short *s2, int* nComLFName, SDHC* sCh)
{
while (*s1)
{
if (*s1++!=*s2++)
*nComLFName = 0;
}
if (*s2)
*nComLFName = 0;
else
*nComLFName = 1;
}
void FAT_CopyUnicodeLFileName(short *s1, short *s2, int* nCoLname, SDHC* sCh)
{
int i=0;
while (*s2)
{
i++;
*s1++=*s2++;
}
*s1 = *s2;
*nCoLname = i;
}
/************************************************/
/* Get nHead cluster from a file entry */
/************************************************/
void FAT_GetEntryCluster(u8 *p, u32* nEntCluster, SDHC* sCh) // p: FAT32 Byte Directory Entry Structure
{
int sTmp, tmp1;
sTmp = LSB_GET_2BYTES(p+20); // high word of this entry's 1st cluster number
tmp1 = LSB_GET_2BYTES(p+26); // low word
sTmp = (sTmp << 16) + tmp1;
if (sTmp==0) sTmp=2; // for root directory
*nEntCluster = sTmp;
}
/**********************************************/
/* Set nHead cluster in a file entry */
/**********************************************/
void FAT_SetEntryCluster(u8 *p, u32 cluster, SDHC* sCh) // p: FAT32 Byte Directory Entry Structure
{
int sTmp = (cluster>>16)&0xffff; // high word
cluster &= 0xffff; // low word
LSB_SET_2BYTES(p+20, sTmp); // left: LSB address, right: value
LSB_SET_2BYTES(p+26, cluster);
}
/************************************************/
/* set date and time in a file entry */
/************************************************/
void FAT_SetDateAndTime(u8 *p, SDHC* sCh) // p: FAT32 Byte Directory Entry Structure (oFat.m_ucFileEntryHead)
{
#if 1
LSB_SET_2BYTES(p+14, 0xAE37); // DIR_CrtTime
LSB_SET_2BYTES(p+16, 0x309E); // DIR_CrtDate
LSB_SET_2BYTES(p+22, 0x612A); // DIR_WrtTime
LSB_SET_2BYTES(p+24, 0x2f5c); // DIR_WrtDate
LSB_SET_2BYTES(p+18, 0x309e); // DIR_LstAccDate
#else
LSB_SET_2BYTES(p+14, oFat.m_nFat32FileTime); // DIR_CrtTime
LSB_SET_2BYTES(p+16, oFat.m_nFat32FileDate); // DIR_CrtDate
LSB_SET_2BYTES(p+22, oFat.m_nFat32FileTime); // DIR_WrtTime
LSB_SET_2BYTES(p+24, oFat.m_nFat32FileDate); // DIR_WrtDate
LSB_SET_2BYTES(p+18, oFat.m_nFat32FileDate); // DIR_LstAccDate
#endif
}
/************************************************/
/* Generate a special directory entry */
/* ucSpecEnt : must be 2-level Pointer.. by song. */
/************************************************/
void FAT_GenerateDirEntry(int tag, int cluster, u8** ucSpecEnt, SDHC* sCh)
{
int i;
for (i=0; i<DIR_ENTRY_SIZE; i++) // Initialize oFat.m_ucFileEntryHead.
{
oFat.m_ucFileEntryHead[i] = 0;
}
LSB_SET_2BYTES(oFat.m_ucFileEntryHead, tag);
if (tag==DOT_ENTRY_TAG||tag==DOTDOT_ENTRY_TAG) // 0x202e or 0x2e2e, ". " or ".."
{
for (i=2; i<SF_NAME_LENGTH; i++) // Insert space in DIR_Name[2] ~ DIR_Name[10]
{
oFat.m_ucFileEntryHead[i] = 0x20;
}
oFat.m_ucFileEntryHead[11] = ATTR_DIRECTORY;
FAT_SetDateAndTime(oFat.m_ucFileEntryHead, sCh);
FAT_SetEntryCluster(oFat.m_ucFileEntryHead, cluster, sCh);
}
LSB_SET_4BYTES(oFat.m_ucFileEntryHead+28, 0); // 32-bit DWORD holding this file's size in bytes
// youngbo.song - set pointer value..
*ucSpecEnt = oFat.m_ucFileEntryHead; // FAT32 Byte Directory Entry Structure
}
void FAT_CopyEntry(u8* p, u32 x, SDHC* sCh)
{
u8* pTargetPointer;
FAT_GenerateDirEntry(x, 0, &pTargetPointer, sCh);
FAT_CopyAblockOfMem(p, pTargetPointer, DIR_ENTRY_SIZE, sCh);
}
/***********************************/
/* A block of memory copy */
/***********************************/
void FAT_CopyAblockOfMem(u8 *target, u8 *source, int bytes, SDHC* sCh)
{
int i;
for (i=0; i<bytes; i++)
*target++ = *source++;
}
/********************************************************/
/* Conversion: sector and offset unifying */
/********************************************************/
// only used in DIR_search_file_entry()
void FAT_UnifySector(int *sector, int *offset, int sector1, int offset1, SDHC* sCh)
{
*sector = sector1 + offset1/oFat.m_usBpbBytsPerSec;
*offset = offset1%oFat.m_usBpbBytsPerSec;
}
/*****************************************************************/
/* Get next cluster with current_cluster in a FAT table */
/*****************************************************************/
void FAT_GetNextCluster(int cluster, int* nNextClu, SDHC* sCh)
{
int nSector, nOffset, nNextcluster;
int nFatEnt;
FAT_ClusterFatAddr(cluster, &nSector, &nOffset, sCh);
FAT_GetFat(nSector, nOffset, &nNextcluster, &nFatEnt, sCh);
if (nFatEnt <= 0 )
{
Assert(0);
*nNextClu = -2;
}
if (nNextcluster >= oFat.m_nEOC)
{
*nNextClu = -1;
}
else if (FATType==IS_FAT32)
*nNextClu = (nNextcluster & oFat.m_nMaskCluster);
else
*nNextClu = nNextcluster;
}
/*****************************************************************************/
/* Write a fat entry for that cluster number into oFat.m_ucBuffer in a FAT table */
/*****************************************************************************/
void FAT_SetFat(int offset, u32 fat_entry, u8*p, SDHC* sCh)
{
//u8 *p = oFat.m_pFatBuffStart;
u32 uOriginal;
#if 0
if(LastFatSector == -1)
{
LastFatSector = 0;
}
ReadSector(FatBuffStart, LastFatSector+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1);
#endif
// in FAT32
uOriginal = LSB_GET_4BYTES(p+offset);
fat_entry = (fat_entry&oFat.m_nMaskCluster)+(uOriginal&(~oFat.m_nMaskCluster));
///printf("fat_entry content: 0x%x, offset = 0x%x, uOriginal: 0x%x in SetFat()\n", fat_entry, offset, uOriginal); // LYS 040429 test
LSB_SET_4BYTES(p+offset, fat_entry);
///CopyArray(see, FatBuffStart, SECBUFFSIZE);
oFat.m_nLastFatChanged = 1;
}
/*********************************************************************/
/* Write the fat content from oFat.m_ucBuffer to fat area of HD if needed */
/*********************************************************************/
void FAT_WriteFatContent(int* nFatContent, SDHC* sCh) //WriteFatContent
{
u8 *p = oFat.m_pFatBuffStart;
if (oFat.m_nLastFatChanged)
{
///printf("flush_fat(): oFat.m_nLastFatSector - %d\n", oFat.m_nLastFatSector);
//WriteSector(p, oFat.m_nLastFatSector+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1);
FAT_WriteSector(p, oFat.m_nLastFatSector+oFat.m_uBpbHiddSec+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1, sCh);// sunny modify
oFat.m_nLastFatChanged = 0;
}
*nFatContent = 1;
}
/************************************************************************/
/* conversion: cluster to its fat's sector and offset in a FAT table */
/************************************************************************/
void FAT_ClusterFatAddr(int cluster, int *sector, int *offset, SDHC* sCh)
{
int nFatOffSet = (cluster * FATType)/2;
*sector = nFatOffSet / oFat.m_usBpbBytsPerSec;
*offset = nFatOffSet - (*sector) * oFat.m_usBpbBytsPerSec;
}
/*****************************************************************/
/* read a fat entry from oFat.m_ucBuffer with specified sector and offset */
/*****************************************************************/
void FAT_GetFat(int sector, int offset, int *fat_entry, int* nFatEnt, SDHC *sCh)
{
u8 *p = oFat.m_pFatBuffStart;
if ((sector<0)||(sector>=oFat.m_nFatSz))
{
*nFatEnt = -1;
return;
}
if (sector != oFat.m_nLastFatSector)
{
int i=1; // in fat16, 32
if (oFat.m_nLastFatChanged)
{
//printf("why fat change.. in GetFat()\n");
FAT_WriteSector(p, oFat.m_nLastFatSector+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, i, sCh);
oFat.m_nLastFatChanged = 0;
Delay(10000); /// need delay between write and read op. why??
}
FAT_ReadSector(p, sector+oFat.m_nPosFat+oFat.m_uBpbHiddSec+SDCARD_OFFSET_SECTOR, i, sCh); // sunny 060818
oFat.m_nLastFatSector = sector;
}
// in FAT32
*fat_entry = (LSB_GET_4BYTES(p+offset))&oFat.m_nMaskCluster;
///printf("fat_entry: 0x%x in GetFat()\n", *fat_entry); // LYS 040429 test
*nFatEnt = 1;
}
/*****************************************************************/
/* append cluster chain to another chain */
/*****************************************************************/
void FAT_AppendCluster(int cluster, int nextcluster, int* nAnoChain, SDHC* sCh)
{
int sector, offset, sTmp;
int nFatEnt;
FAT_ClusterFatAddr(cluster, §or, &offset, sCh);
FAT_GetFat(sector, offset, &sTmp, &nFatEnt, sCh);
if (nFatEnt<=0) {
Assert(0);
printf("append cluster fat ERROR\n");
// ucNerror Display
*nAnoChain = -1;
}
FAT_SetFat(offset, nextcluster, oFat.m_pFatBuffStart, sCh);
FAT_WriteFatContent(nAnoChain, sCh);
}
/********************************************************************/
/* write a file entry in directory with file nLength and headcluster */
/********************************************************************/
void FAT_WriteFileHead(const char *name, u8 ucAttr, u32 nLength, u32 cluster, int* nFileEnt, SDHC* sCh)
{
int i;
if (cluster<2)
{
*nFileEnt = -2;
return;
}
ucAttr &= 0x3f;
if ((ucAttr&ATTR_DIRECTORY) == ATTR_DIRECTORY)
nLength = 0;
printf("name: %s\n", name);
FAT_ConvertToDiscEntryFormat(name, oFat.m_cpEntryName, sCh);
printf("oFat.m_cpEntryName: %s\n", oFat.m_cpEntryName);
FAT_CopyArray(oFat.m_ucFileEntryHead, (u8*)oFat.m_cpEntryName, SF_NAME_LENGTH, sCh);
printf("oFat.m_ucFileEntryHead: ");
for(i=0; i<SF_NAME_LENGTH; i++) {
printf("%c ", oFat.m_ucFileEntryHead[i]);
}
printf("\n");
oFat.m_ucFileEntryHead[11] = ucAttr;
oFat.m_ucFileEntryHead[12] = 0x18; //NTRes // LYS 040427
oFat.m_ucFileEntryHead[13] = 0x3D; //CrtTimeTenth // LYS 040427 //LYS 040430
FAT_SetDateAndTime(oFat.m_ucFileEntryHead, sCh);
FAT_SetEntryCluster(oFat.m_ucFileEntryHead, cluster, sCh);
LSB_SET_4BYTES(oFat.m_ucFileEntryHead+28, nLength);
*nFileEnt = 0;
}
void FAT_WriteSFFileHead(const char *name, u8 ucAttr, u32 nLength, u32 cluster, int* nFileEnt, SDHC* sCh)
{
int i;
//int flength;
//if ((flength=FormatSFileName(oFat.m_ucFsfname, (char*)name))<0) return -1;
if (cluster<2)
{
*nFileEnt = -2;
return;
}
//name = oFat.m_ucFsfname;
ucAttr &= 0x3f;
if ((ucAttr&ATTR_DIRECTORY) == ATTR_DIRECTORY)
nLength = 0;
//strncpy(oFat.m_ucFileEntryHead, name, strlen(name)); //LYS 040102 (char*) type casting
printf("name: %s\n", name);
FAT_CopyArray(oFat.m_ucFileEntryHead, (u8*)name, SF_NAME_LENGTH, sCh);
printf("oFat.m_ucFileEntryHead: ");
for(i=0; i<SF_NAME_LENGTH; i++) {
printf("%c ", oFat.m_ucFileEntryHead[i]);
}
printf("\n");
oFat.m_ucFileEntryHead[11] = ucAttr;
oFat.m_ucFileEntryHead[12] = 0x18; //NTRes // LYS 040427
oFat.m_ucFileEntryHead[13] = 0x3D; //CrtTimeTenth // LYS 040427 //LYS 040430
FAT_SetDateAndTime(oFat.m_ucFileEntryHead, sCh);
FAT_SetEntryCluster(oFat.m_ucFileEntryHead, cluster, sCh);
LSB_SET_4BYTES(oFat.m_ucFileEntryHead+28, nLength);
*nFileEnt = 0;
}
/*******************************************************/
/* release a cluster chain with specified headcluster */
/*******************************************************/
// headcluster: cluster to be deleted in FAT table
// nLength: short file or dir name: 1
// long file or dir name: the number of entries to be used
void FAT_ReleaseClusterChain(int headcluster, int nLength, int* nRelCluster, SDHC* sCh)
{
int sector, offset, sTmp, count=0;
int nFatContent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -