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

📄 fat.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	short sFcbNameLen;
	u8    ucSum;

	ucSum = 0;
	for (sFcbNameLen=11; sFcbNameLen!=0; sFcbNameLen--)     // NOTE: The operation is an unsigned char rotate right
	{

		ucSum = ((ucSum & 1) ? 0x80 : 0) + (ucSum >> 1) + *pFcbName++;
	}
	*uSum = ucSum;
}

// The Basis-Name Generation Algorithm

// void BasisNameGeneration(void)
//  {
//  1.  The UNICODE name passed to the file system is converted to upper case.
//  2.	The upper cased UNICODE name is converted to OEM.
//      if   (the uppercased UNICODE glyph does not exist as an OEM glyph in the OEM code page)
//        or (the OEM glyph is invalid in an 8.3 name)
//      {
//	     Replace the glyph to an OEM '_' (underscore) character.
//	     Set a "lossy conversion" flag.
//      }
//  3.	Strip all leading and embedded spaces from the long name.
//  4.	Strip all leading periods from the long name.
//  5.	While	(not at end of the long name)
//  	  and	(char is not a period)
//	  and	(total chars copied < 8)
//      {
//	  Copy characters into primary portion of the basis name
//      }
//  6.  Insert a dot at the end of the primary components of the basis-name
//      iff the basis name has an extension after the last period in the name.
//  7.	Scan for the last embedded period in the long name.
//      If	(the last embedded period was found)
//      {
//	   While     (not at end of the long name)
//	     and     (total chars copied < 3)
//	   {
//		Copy characters into extension portion of the basis name
//	   }
//      }
//   }


/**********************************************************/
/* Generate a short name with a long file name            */
/**********************************************************/
void FAT_GenerateSNameFromLName(short *s, char *p, int* nFlag, SDHC* sCh)  // implementation of BasisNameGeneration()
{
	char c[2][9];
	int i, n, j[2]={0, 0}, nExt=0, nLossyFlag=0;

	while (*s)
	{
		short k = *s++;
		if (k>=0x61&&k<=0x7a)
			k -= 0x20;   // UNICODE name convert to Upper case. (k>=a && k<=z)
		if ((k&0x7f)!=k)                   //if k is minus
		{
			k = '_'; nLossyFlag = 1;
		} // if not ascii, replace it with '_' and lossy flag is set.
		if (k=='+' || k==',' || k==':' || k=='=' || k=='[' || k==']')
		{  // if invalid, do as the above.
			k = '_'; nLossyFlag = 1;
		}
		if (k==' ')
		{
			nLossyFlag = 1;
			continue;
		} // Strip all the spaces.
		if (k=='.'&&j[0]==0)
		{
			nLossyFlag = 1;
			continue;
		}  // Strip all the periods in the name.
		if (k!='.'&&nExt>1)
		{
			for (n=0; (n<j[1])&&(j[0]+n<8); n++)
				c[0][j[0]+n] = c[1][n];           // copy char into primary portion of the basis name
			j[0]+= n;  //j[o]=8
			j[1] = 0;
			nExt = 1;
		}
		if (k!='.'&&j[nExt]<8)
		{
			c[nExt][j[nExt]++] = (char)k;
			continue;
		}
		else if (k=='.')
		{
			if (nExt) nLossyFlag = 1;
				nExt++;
			continue;
		}
		else
			nLossyFlag = 1;
	}
	for (i=j[0]; i<8; i++)
		c[0][i] = ' ';
	c[0][8] = 0;  // Primary portion
	strcpy(p, c[0]);
	for (i=j[1]; i<3; i++)
		c[1][i] = ' ';
	c[1][3] = 0;  // Extension portion
	strcat(p, c[1]);
	*nFlag = nLossyFlag;
}

// The Numeric-Tail Generation Algorithm (p.31)

// void NumericTailGeneration(void)
// {
//	if	(a "lossy conversion" was not flagged)
//	   and	(the long name fits within the 8.3 naming conventions)
//	   and	(the basis-name does not collide with any existing short name)
//	{
//	   The short name is only the basis-name without the numeric tail.
//	}
//	else
//	{
//	   Insert a numeric-tail "~n" to the end of the primary name
//	   such that the value of the "~n" is chosen so that the name
//	   thus formed does not collide with any existing short name
//	   and that the primary name does not exceed eight characters in nLength.
//	}

// Validating the contents of a directory
//  	if  (((m_ucLDirAttr & ATTR_LONG_NAME_MASK) == (ATTR_LONG_NAME)) && (m_ucLDirOrd != 0xE5))
//	{
		//  Found an active long name sub-component.  //
//	}
//	if  (((m_ucLDirAttr & ATTR_LONG_NAME_MASK) != (ATTR_LONG_NAME)) && (m_ucLDirOrd != 0xE5))
//	{
//		if ((DIR_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) == 0x00) {
			//  Found a file.  //
//		} else if ((DIR_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) == ATTR_DIRECTORY) {
			//  Found a directory.  //
//		} else if ((DIR_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) == ATTR_VOLUME_ID) {
			//  Found a volume label.  //
//		} else {
			//  Found an invalid directory entry.  //
//		}
//	}
// }  End of NumericTailGeneration()

/**********************************************************/
/* Append a numeric tail for short file name              */
/**********************************************************/
void FAT_GenerateNumericTail(char *p, int n, SDHC* sCh)  //Implementation of NumericTailGeneration()
{
	char c[8];
	int i, k, m=n, nDigitNum=1;

	// invalid numeric tail //
	if (n<1 || n>999999 || p ==NULL)
		return;
	// get nDigitNum //
	while (m>=10)
	{
		m /= 10; nDigitNum++;
	}
	// get tail in char //
	k = nDigitNum;
	c[k+1]=0;
	do
	{
		m=n%10; n/=10; c[k--]=m+'0';
	}
	while (n>=10);
	c[0] = '~';
	// insert //
	for (k=0; k<8; k++)
		if (p[k]==' ')
			break;
	if (k+nDigitNum<8)
	{
		for (i=0; i<nDigitNum; i++)
		p[k+i] = c[i];
	}
	else
	{
		for (i=0; i<nDigitNum; i++)
		p[8-nDigitNum+i] = c[i];
	}
}

void FAT_ReadSector(u8 *dest, int lba, int nblocks, SDHC* sCh)
{
	Assert(dest);
	Assert(nblocks);

	SDHC_ReadBlocks(lba, nblocks, (u32)dest, sCh);
}


void FAT_WriteSector(u8 *src, int lba, int nblocks, SDHC* sCh)
{
	Assert(src);
	Assert(nblocks);

	SDHC_WriteBlocks(lba, nblocks, (u32)src, sCh);
}

/******************************************************************/
/* From cluster to physical sector number.                        */
/******************************************************************/

void FAT_FromClusterToLba(int cluster, int* nLba, SDHC* sCh)
{
	if (cluster < 2)
	{
		*nLba = oFat.m_nPosRoot;
		return; /// 7.20 need
	}
	*nLba = oFat.m_nFirstDataSector + (cluster-2)*oFat.m_ucBpbSecPerClus + SDCARD_OFFSET_SECTOR;
}


/*******************************************************************/
/* collect a long file name in unicode format from directory entry */
/*******************************************************************/

void FAT_CollectLFileName(short *s, u8 *p, int* nLfname, SDHC* sCh)
{
	static int nLength;
	int i, j, nPosi, nHead, nOrder, ucNerror=0;
L:
	if (ucNerror)
	{
		Assert(0);
		if (nHead) oFat.m_nOrphanCount++;
		oFat.m_nNthEntry = 0;
		*nLfname =  -1;
	}

	nHead = ((p[0]&0x40)==0x40);
	if (nHead && oFat.m_nNthEntry>1)
	{
		ucNerror = 1; goto L;
	}
	else if (!nHead && oFat.m_nNthEntry<=1)
	{
		ucNerror = 2; goto L;
	}
	nOrder = p[0]&(~0x40);
	if (nOrder==0||nOrder==0xe5)
	{
		ucNerror = 3; goto L;
	}
	if (nHead && oFat.m_nNthEntry<=1)
		oFat.m_nNthEntry = nOrder;
	else if (oFat.m_nNthEntry == nOrder+1)
		oFat.m_nNthEntry = nOrder;
	else
	{
		ucNerror = 4; goto L;
	}
	Assert(oFat.m_nNthEntry>0);
	nPosi = 13*(oFat.m_nNthEntry-1);
	for (i = 0; i < 5; i++)  // 1-5
		s[nPosi+i] = LSB_GET_2BYTES(p+1+i*2);
	for (i = 0; i < 6; i++)  // 6-11
		s[nPosi+5+i] = LSB_GET_2BYTES(p+14+i*2);
	for (i = 0; i < 2; i++)  // 12-13
		s[nPosi+11+i] = LSB_GET_2BYTES(p+28+i*2);
	if (nHead)
	{
		nLength = nPosi+13;
		for (i=0; i<13; i++)
			if (s[nPosi+i]==0)
			{
				nLength = nPosi+i;
				break;
			}
		for (j=i+1; j<13; j++)
			if (s[nPosi+j]!=-1)
			{
				ucNerror = 5; goto L;
			}
	}
	if (oFat.m_nNthEntry==1)
	{
		if (!nLength)
		{
			ucNerror = 6; goto L;
		}
		*nLfname = nLength;
	}
	else
		*nLfname =  0;
}


/**********************************************************/
/* Pass out to directory entry from a long file name     */
/**********************************************************/
void FAT_PassoutLFileName(short *s, u8* cFname, int nOrder, int* nDirecEntry, SDHC* sCh)
{
//	char cSfname[SF_NAME_LENGTH+1];
	short *nPosi = s+13*(nOrder-1), sTmp[13];
	int i, k=0, nHead=nOrder, nMaxOrder;
	int nUniChr;
	int nLen;

	FAT_GetUnicodeStrLen(s, &nUniChr, sCh);
	nLen = nUniChr;
	nMaxOrder = (nLen+12)/13;
	if (nLen<=0 || nOrder<=0 || nOrder>nMaxOrder)
		*nDirecEntry = 0;
	if (nOrder == nMaxOrder)
	{
		nHead |= 0x40; k = nLen%13;
	}
	if (nHead==0xe5) nHead++;

	oFat.m_ucFileEntryHead[0] = nHead;
	oFat.m_ucFileEntryHead[11] = ATTR_LONG_NAME;
	oFat.m_ucFileEntryHead[12] = 0;
	FAT_ComputeChkSum(cFname, &oFat.m_ucFileEntryHead[13], sCh);
	LSB_SET_2BYTES(oFat.m_ucFileEntryHead+26, 0);
	if (k)
		for (i=0; i<13; i++)
		sTmp[i] = ((i<k)?(*(nPosi+i)):((i==k)?0:0xffff));
	else
		for (i=0; i<13; i++)
			sTmp[i] = *(nPosi+i);
	for (i = 0; i < 5; i++)  // 1-5 */
		LSB_SET_2BYTES(oFat.m_ucFileEntryHead+1+i*2, *(sTmp+i));
	for (i = 0; i < 6; i++)  // 6-11 */
		LSB_SET_2BYTES(oFat.m_ucFileEntryHead+14+i*2, *(sTmp+5+i));
	for (i = 0; i < 2; i++)  // 12-13 */
		LSB_SET_2BYTES(oFat.m_ucFileEntryHead+28+i*2, *(sTmp+11+i));
	*nDirecEntry = 1;
}

//***********************************************************************/
/* Check if p is a short name entry to know previous entry is a orphan  */
/************************************************************************/

void FAT_CheckOrphan(u8 *p, int* nOrphan, SDHC* sCh)
{
	if (p[0]==FREE_ENTRY_TAG0)
		*nOrphan = 1;
	if (p[0]==TERM_ENTRY_TAG0)
		*nOrphan = 1;
	if ((p[11]&ATTR_LONG_NAME)==ATTR_LONG_NAME)
		*nOrphan =  1;
	if ((p[11]&ATTR_VOLUME_ID)==ATTR_VOLUME_ID)
		*nOrphan = 1;
	*nOrphan = 0;
}

/***********************************************************/
/* Fat32 short file name conversion from outside to inside */
/***********************************************************/
void FAT_FormatSFileName(u8 *fname, char *name, int* nSfnameconv, SDHC* sCh)
{
	char *p=name;
	int j=0, nFoundSeparator=0, nFoundSpace=0;

	if (p==NULL || *p==0)
		*nSfnameconv = -1;
	else if (*p == PATH_NAME_CHAR_SEPARATOR)
	{
		fname[j++] = *p++;
		if (*p == PATH_NAME_CHAR_SEPARATOR)
		{
			fname[j++] = *p++;
		}
		if ((*p != PATH_NAME_CHAR_DELIMITER) && (*p != PATH_NAME_CHAR_END))
		{
			*nSfnameconv = -2;
		}
		fname[j] = PATH_NAME_CHAR_END;
		*nSfnameconv = 0;
	}
	while (*p)
	{
		if (!PATH_NAME_CHAR_VALID(*p))     // invalid char
		{
			*nSfnameconv = -3;
		}
		else if (*p==' ')
		{
			nFoundSpace = 1;
			fname[j++]=*p++;
		}
		else if (*p==PATH_NAME_CHAR_SEPARATOR)
		{
			if (nFoundSeparator)         // 2 or more
				*nSfnameconv = -4;
			else if (!j)                 // no base name
				*nSfnameconv =   -5;
			nFoundSeparator = 1;
			while (j<SF_BASE_LENGTH)
				fname[j++]=' ';          // 8 character max
			p++;
		}
		else if ((*p==PATH_NAME_CHAR_DELIMITER)||(*p==PATH_NAME_CHAR_END))
		{
			if (!j)
				*nSfnameconv = -5;        // no base name
			else
				while (j<SF_NAME_LENGTH)
					fname[j++]=' ';      // 8+3
		}
		else
		{
			if (j==SF_BASE_LENGTH)
				nFoundSpace = 0;
			else if (nFoundSpace)
				*nSfnameconv = -6;
			fname[j++] = *p++;

⌨️ 快捷键说明

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