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

📄 smt_fat.c

📁 The combined demo is dedicated for S1C33L05, so DMT33L05 should be used to load and run the demo. F
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(bArea != SMT_AREA_2)					// ECC value is taken out from
	  {										// - "ECC Area-1" or "ECC Area-2".
		ulEccVal  = (unsigned long)(pChkBuff->stDatBuff.bEcc1[0]);
		ulEccVal |= (unsigned long)(pChkBuff->stDatBuff.bEcc1[1] << 8);
		ulEccVal |= (unsigned long)(pChkBuff->stDatBuff.bEcc1[2] << 16);
	  }
	else
	  {
		ulEccVal  = (unsigned long)(pChkBuff->stDatBuff.bEcc2[0]);
		ulEccVal |= (unsigned long)(pChkBuff->stDatBuff.bEcc2[1] << 8);
		ulEccVal |= (unsigned long)(pChkBuff->stDatBuff.bEcc2[2] << 16);
	  }

	return(ulEccVal);
  }


/************************************************************************
 *  smtRdSect
 *      Type     : int
 *      Ret val  : Error Code
 *      Argument : unsigned long ulLogSct ... Logic sector address
 *                 unsigned long ulDatSiz ... Read data size
 *                 char *pBuffer          ... Read data buffer
 *      Function : This function reads data for the size from specified
 *                 sector.
 ************************************************************************/
int	smtRdSect(
	unsigned char bDrvNum,					// Drive number(dummy)
	unsigned long ulLogSct,					// Logic sector address
	unsigned long ulDatSiz,					// Read data size
	unsigned char *pBuffer					// Read data buffer
	)
  {
	unsigned long	ulLogBlk;				// Logic block address
	unsigned long	ulPhyBlk;				// Physics block address
	unsigned long	ulPhySct;				// Physics sector address
	unsigned long	ulPage;					// Page address

	ulDatSiz /= smt_pDevInf->pSizeInf->uwDatSize;		// Data are read in sector unit.
	while(ulDatSiz > 0)						// When an error occurs, it evacuate
	  {										// - in another block in the block unit.
		ulLogBlk = ulLogSct / smt_pDevInf->pSizeInf->uwBlkSize;
		ulPhyBlk = smtChgPhyNum(ulLogBlk);
		ulPhySct = ulLogSct % smt_pDevInf->pSizeInf->uwBlkSize;
		ulPage = smtChgPgNum(ulLogBlk / SMT_LZN_MAX, ulPhyBlk, ulPhySct);
		if(smtPageReadWrap(SMT_C_DREAD_1, 0x00, ulPage, pBuffer) != SMT_E_SUCCESS)
		  {
			smtErrInf.iSmtErr = SMT_E_PAGREAD;
			return(SMT_E_FAILURE);
		  }
		pBuffer += smt_pDevInf->pSizeInf->uwDatSize;
		ulLogSct++;
		ulDatSiz--;
	  }

	return(SMT_E_SUCCESS);
  }

/************************************************************************
 *  smtWtSect
 *      Type     : int
 *      Ret val  : Error code
 *      Argument : unsigned long ulLogSct ... Logic sector address
 *                 unsigned long ulDatSiz ... Write data size
 *                 char *pBuffer          ... Write data buffer
 *      Function : This function writes data for the size in specified
 *                 sector.
 ************************************************************************/
int	 smtWtSect(
	unsigned char	bDrvNum,				// Drive number(dummy)
	unsigned long	ulLogSct,				// Logic sector address
	unsigned long	ulDatSiz,				// Write data size
	unsigned char   *pBuffer,				// Wrire data buffer
	unsigned char   bVerify					// Verify option flag
	)
  {
	int		iLoop, iLoopLmt;				// Loop counter
	unsigned char	bIndex;					// Zone index
	unsigned char	bOvrWrtFlg;				// Over write flag
	unsigned char	bBlkGetFlg;				// New block get flag
	unsigned long	ulZone;					// Zone address
	unsigned long	ulLogBlk;				// Logic block address
	unsigned long	ulPhySct;				// Physics sector address
	unsigned long	ulEndSct;				// End physics sector address
	unsigned long	ulOldPhyBlk;			// Old physics block address
	unsigned long	ulNewPhyBlk;			// New physics block address
	unsigned long	ulErsPhyBlk;			// Erase physics block address
	unsigned long	ulPage;					// Page address
	int		iRetVal;
	unsigned int	*pReadPnt;				// Data compare pointer
	struct SMT_BLKCOPY_PARAMS	stBCParams;	// Block copy function parameters

	////////////////
	// INITIALIZE //
	////////////////
	bOvrWrtFlg = SMT_FALSE;					// Each address is calculated.
	bBlkGetFlg = SMT_FALSE;					// Each address is calculated.
	ulErsPhyBlk = 0x00000000;				// Erase Block address clear
	ulLogBlk = ulLogSct / smt_pDevInf->pSizeInf->uwBlkSize;
	ulPhySct = ulLogSct % smt_pDevInf->pSizeInf->uwBlkSize;
	ulEndSct = ulPhySct + ulDatSiz / smt_pDevInf->pSizeInf->uwDatSize;
	ulZone = ulLogBlk / SMT_LZN_MAX;
	if(!ulZone)
	  {
		bIndex = 0;
	  }
	else
	  {
		bIndex = 1;
	  }

	/////////////////
	// SECTOR LOOP //							// Data are written in sector unit.
	/////////////////							// When an error occurs, it evacuate
	ulOldPhyBlk = smtChgPhyNum(ulLogBlk);		// - in another block in the block unit.
	while((ulPhySct < ulEndSct)&&(ulPhySct < smt_pDevInf->pSizeInf->uwBlkSize))
	  {
		if(!(smtBlkTbl[bIndex].bBlkChkInf[(ulLogBlk % SMT_LZN_MAX) / 8] & SMT_M_MASK(ulLogBlk % 8)))
		  {
			////////////////////
			// NEW DATA WRITE //
			////////////////////				// Data are written in the new block.
			for(iLoop = 0 ; iLoop <= SMT_BLKTRY_MAX ; iLoop++)
			  {
				if(smtGetFreeBlk(ulZone, &ulNewPhyBlk) != SMT_E_SUCCESS)
				  {
					return(SMT_E_FAILURE);
				  }
				bBlkGetFlg  = SMT_TRUE;			// Indicate Got new block
				ulOldPhyBlk = ulNewPhyBlk;
				smtSetProlDat(ulLogBlk, pBuffer);
				ulPage = smtChgPgNum(ulZone, ulNewPhyBlk, ulPhySct);
				if(pSmt_PageProgram(0x00, ulPage, pBuffer, bVerify) != SMT_E_SUCCESS)
				  {
					if(smtEntryBadBlk(ulZone, ulNewPhyBlk) != SMT_E_SUCCESS)
					  {
						return(SMT_E_FAILURE);
					  }
					continue;
				  }

				if(smtWtBlkAddr(ulZone, ulNewPhyBlk, ulLogBlk) != SMT_E_SUCCESS)
				  {
					if(smtEntryBadBlk(ulZone, ulNewPhyBlk) != SMT_E_SUCCESS)
					  {
						return(SMT_E_FAILURE);
					  }
					continue;
				  }
				smtBlkTbl[bIndex].bBlkCnvInf[ulLogBlk % SMT_LZN_MAX] = SMT_M_BYTE(ulNewPhyBlk, 0);
				smtBlkTbl[bIndex].bBlkChkInf[(ulLogBlk % SMT_LZN_MAX) / 8] |= SMT_M_MASK(ulLogBlk % 8);
				break;
			  }
			if(iLoop > SMT_BLKTRY_MAX)				// Retry over?
			  {
				smtErrInf.iSmtErr = SMT_E_SCTWRTE;	// Set Sector Write error
				return(SMT_E_FAILURE);
			  }
		  }
		else
		  {
			/////////////////////
			// DATA OVER WRITE //					// Appropriate sector is written after it is
			/////////////////////					// - copied on the new block when sector isn't being erased.
			if(bOvrWrtFlg != SMT_TRUE && bBlkGetFlg != SMT_TRUE)
			  {
				ulPage = smtChgPgNum(ulZone, ulOldPhyBlk, ulPhySct);
				if(smtPageReadWrap(SMT_C_DREAD_1, 0x00, ulPage, smtRead.bBuff) != SMT_E_SUCCESS)
				  {
					return(SMT_E_FAILURE);
				  }

				pReadPnt = (unsigned int *)smtRead.bBuff;	// The existence of the data is monitored.
				iLoopLmt = smt_pDevInf->pSizeInf->uwDatSize / sizeof(unsigned int);
				for(iLoop = 0 ; iLoop < iLoopLmt ; iLoop++)
				  {
					if(*pReadPnt++ != 0xffffffff)
					  {
						break;
					  }
				  }

				if(iLoop < iLoopLmt)
				  {										// The one except for appropriate sector
					bOvrWrtFlg = SMT_TRUE;				// is copied on another block.
					stBCParams.ulLogBlk	 = ulLogBlk;	// Set block Copy parameters
					stBCParams.ulFirstBlk	 = ulOldPhyBlk;
					stBCParams.ulExceptSct	 = ulPhySct;
					stBCParams.bValidBlkFlag = SMT_BLKMV_FIRST;
					stBCParams.bVerify	 = bVerify;
					iRetVal = smtBlockCopy(&stBCParams);
					if(iRetVal != SMT_E_SUCCESS)
					  {
						return(iRetVal);
					  }
					if(!ulErsPhyBlk)
					  {
						ulErsPhyBlk = ulOldPhyBlk;
					  }
					ulOldPhyBlk = stBCParams.ulDestBlk;
				  }
			  }

			smtSetProlDat(ulLogBlk, pBuffer);
			ulPage = smtChgPgNum(ulZone, ulOldPhyBlk, ulPhySct);
			if(pSmt_PageProgram(0x00, ulPage, pBuffer, bVerify) != SMT_E_SUCCESS)
			  {
				if(smtWtEvac(ulLogBlk, ulPhySct, pBuffer, bVerify) != SMT_E_SUCCESS)
				  {
					return(SMT_E_FAILURE);
				  }
				ulOldPhyBlk = smtChgPhyNum(ulLogBlk);
			  }
		  }
		ulPhySct++;
		pBuffer += smt_pDevInf->pSizeInf->uwDatSize;
	  }

	/////////////////////
	// OLD BLOCK ERASE //
	/////////////////////
	if(bOvrWrtFlg != SMT_TRUE)				// When data are replaced, an old block is erased.
	  {
		return(SMT_E_SUCCESS);
	  }

	if(ulPhySct < smt_pDevInf->pSizeInf->uwBlkSize)
	  {
		if(smtDupliSect(ulZone, ulOldPhyBlk, ulErsPhyBlk, ulPhySct,
		   smt_pDevInf->pSizeInf->uwBlkSize - 1, bVerify) != SMT_E_SUCCESS)
		  {
			stBCParams.ulLogBlk	 = ulLogBlk;	// Set block Copy parameters
			stBCParams.ulFirstBlk	 = ulOldPhyBlk;
			stBCParams.ulLatterBlk	 = ulErsPhyBlk;
			stBCParams.ulExceptSct	 = ulPhySct;
			stBCParams.bValidBlkFlag = SMT_BLKMV_BOTH | SMT_BLKMV_RECOVER;
			stBCParams.bVerify	 = bVerify;
			iRetVal = smtBlockCopy(&stBCParams);
			if(iRetVal != SMT_E_SUCCESS)
			  {
				return(iRetVal);
			  }
		  }
	  }

	ulPage = smtChgPgNum(ulZone, ulErsPhyBlk, 0x00);
	if(pSmt_BlockErase(ulPage) == SMT_E_SUCCESS)
	  {
		smtBlkTbl[bIndex].bBlkPhyInf[ulErsPhyBlk / 8] |= SMT_M_MASK(ulErsPhyBlk % 8);
	  }

	return(SMT_E_SUCCESS);

  }


/************************************************************************
 *  smtWtEvac
 *      Type     : int
 *      Ret val  : Error code
 *      Argument : unsigned long ulLogBlk ... Logic block address
 *                 unsigned long ulPhySct ... Physics sector address
 *               : unsigned char *pBuffer ... target data
 *               : unsigned char bVerify  ... Verify flag
 *      Function : This function copies normal data from the error block
 *                 on another block.
 ************************************************************************/
int	smtWtEvac(
	unsigned long	ulLogBlk,
	unsigned long	ulPhySct,
	unsigned char	*pBuffer,
	unsigned char	bVerify
	)
  {
	unsigned long	ulZone;						// Zone address
	unsigned long	ulPhyBlk;					// Physics block address
	unsigned long	ulNewPhyBlk;				// New physics block address
	unsigned long	ulPage;						// Page address
	int		iRetVal;							// Return code
	int		iLoop;								// Loop counter
	struct SMT_BLKCOPY_PARAMS	stBCParams;		// Block copy function parameters

	ulPhyBlk = smtChgPhyNum(ulLogBlk);			// The data which aren't unusual are copied
	ulZone = ulLogBlk / SMT_LZN_MAX;
	for(iLoop = 0 ; iLoop < SMT_BLKTRY_MAX ; iLoop++)	// - on another block.
	  {											// Information on "Bad Block" is written in the unusual block.
		stBCParams.ulLogBlk	 = ulLogBlk;
		stBCParams.ulFirstBlk	 = ulPhyBlk;
		stBCParams.ulExceptSct	 = ulPhySct;
		stBCParams.bValidBlkFlag = SMT_BLKMV_FIRST;
		stBCParams.bVerify	 = bVerify;
		iRetVal = smtBlockCopy(&stBCParams);
		if(iRetVal != SMT_E_SUCCESS)
		  {
			return(iRetVal);
		  }

		smtSetProlDat(ulLogBlk, pBuffer);
		ulPage = smtChgPgNum(ulZone, stBCParams.ulDestBlk, ulPhySct);
		if(pSmt_PageProgram(0x00, ulPage, pBuffer, bVerify) != SMT_E_SUCCESS)
		  {

			if(smtEntryBadBlk(ulZone, ulNewPhyBlk) != SMT_E_SUCCESS)
			  {
				return(SMT_E_FAILURE);
			  }
			continue;
		  }

		if(smtEntryBadBlk(ulZone, ulPhyBlk) != SMT_E_SUCCESS)
		  {
			return(SMT_E_FAILURE);
		  }
		break;
	  }

	if(iLoop <= SMT_BLKTRY_MAX)
	  {
		return(SMT_E_SUCCESS);
	  }
	else
	  {
		smtErrInf.iSmtErr = SMT_E_SCTWRTE;		// Set Sector Write error
		return(SMT_E_FAILURE);
	  }
  }


/************************************************************************
 *  smtChkRdDat
 *      Type     : int
 *      Ret val  : Error code
 *      Argument : unsigned char *pBuff ... Check data buffer
 *      Function : This function check the good reason of the reading data.
 ************************************************************************/
int	smtChkRdDat(
	unsigned char	*pBuff						// Check data buffer
	)
  {
	int	iRetVal;								// Return value
	int	iLoop;									// Loop counter
	int	iZero;									// Zero counter
	int	iEccVal;								// ECC value
	int	iResult1;								// Data area-1 check result
	int	iResult2;								// Data area-2 check result
	union SMT_PROLIX_BUFF	*pProlBuff;			// Data buffer pointer

	iRetVal = SMT_E_SUCCESS;					// Return value is initialized.

	//////////////////////////////
	/// DATA STATUS AREA CHECK ///
	//////////////////////////////
	iZero = 0;									// The validity of the data is checked
	iLoop = 0;									// - referring to "Data Status Area".
	while(iLoop < 8)
	  {
		if(!(smtProlBuff.stDatBuff.bDatSts & SMT_M_MASK(iLoop)))
		  {
			if(++iZero >= 4)
			  {
				smtErrInf.iSmtErr = SMT_E_PHYSFMT;
				return(SMT_E_FAILURE);
			  }
		  }
		iLoop++;
	  }

	//////////////////////
	/// ECC AREA CHECK ///						// The ECC check of the data is done.
	//////////////////////						// When there is a bit error, a bit is modified,
#ifdef L05DMT
	iEccVal= SMT_M_ECCVALA1;
#else
	iEccVal = smtGetEccVal(smtProlBuff.bFlatBuff, SMT_AREA_1);	// - and an error is returned.
#endif
	iResult1 = smtChkEccVal(pBuff, SMT_AREA_1, iEccVal);
	if(iResult1 != SMT_E_SUCCESS)
	  {
		iResult1 = smtErrInf.iSmtErr;
	  }

#ifdef L05DMT
	iEccVal= SMT_M_ECCVALA2;
#else
	iEccVal = smtGetEccVal(smtProlBuff.bFlatBuff, SMT_AREA_2);	// - and an error is returned.
#endif
	iResult2 = smtChkEccVal(pBuff, SMT_AREA_2, iEccVal);
	if(iResult2 != SMT_E_SUCCESS)
	  {
		iResult2 = smtErrInf.iSmtErr;
	  }

	if((iResult1 == SMT_E_ECCFAIL)||(iResult2 == SMT_E_ECCFAIL))
	  {
		smtErrInf.iSmtErr = SMT_E_ECCFAIL;
		iRetVal = SMT_E_FAILURE;

⌨️ 快捷键说明

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