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

📄 secam29lvbf531.c

📁 开发平台是ADSP++,用于ADI的BF531驱动AM29160FLASH的源程序。自己编写
💻 C
📖 第 1 页 / 共 2 页
字号:
	{
		// fill the value
		for (i = 0; ( ( i < lCount ) && ( ErrorCode == NO_ERR ) ); i++, ulOffset += (lStride * 2) )
		{


			// check to see that the address is within a valid sector
			ErrorCode = GetSectorNumber( ulOffset, &nSector );
			if( NO_ERR == ErrorCode )
			{
					//ResetFlash();
				// unlock the flash, do the write, and wait for completion
				UnlockFlash(ulOffset);
				WriteFlash( ulOffset, pnData[0] );
				ErrorCode = PollToggleBit(ulOffset);
			}
			else
			{
				return ErrorCode;
			}
		}
	}

	// return the appropriate error code
	return ErrorCode;
}


//////////////////////////////////////////////////////////////
// ERROR_CODE ReadData()
//
// Read a buffer from flash.
//
// Inputs:	unsigned long ulStart - offset in flash to start the reads at
//			int nCount - number of elements to read, in this case bytes
//			int nStride - number of locations to skip between reads
//			int *pnData - pointer to data buffer to fill
//
//////////////////////////////////////////////////////////////

ERROR_CODE ReadData( unsigned long ulStart, long lCount, long lStride, int *pnData )
{

	long i = 0;						// loop counter
	int j = 0;						// inner loop counter
	unsigned long ulOffset = ulStart;			// current offset to write
	int iShift = 0;					// shift value by iShift bits
	int iNumWords = 2;				// number of words in a long
	int nLeftover = lCount % 4;		// how much if any do we have leftover to write
	int nHi,nLow;
	int nSector = 0;
	ERROR_CODE ErrorCode = NO_ERR;		// tells whether we had an error while filling

	// write the buffer up to BUFFER_SIZE items
	for (i = 0; (i < lCount/4) && (i < BUFFER_SIZE); i++)
	{
		for ( iShift = 0, j = 0; j < iNumWords ; j+=2 )
		{


			// check to see that the address is within a valid sector
			ErrorCode = GetSectorNumber( ulOffset, &nSector );
			if( NO_ERR == ErrorCode )
			{
				// Read flash
				ReadFlash( ulOffset, &nLow );
				ulOffset += (lStride * 2);
				ReadFlash( ulOffset, &nHi );
				ulOffset += (lStride * 2);
				pnData[i] = (nHi << 16) | nLow;
			}
			else
			{
				return ErrorCode;
			}
		}
	}

	// because of the way our ldr file is built, we will always have
	// 2 bytes leftover if there is leftover, because the flash is 16 bit
	// that will mean that there is only one write left to do.
	if( nLeftover > 0 )
	{

		// check to see that the address is within a valid sector
		ErrorCode = GetSectorNumber( ulOffset, &nSector );
		if( NO_ERR == ErrorCode )
		{
			ReadFlash( ulOffset, &pnData[i] );
		}
		else
		{
			return ErrorCode;
		}
	}

	// return the appropriate error code
	return ErrorCode;
}




//----------- R e a d F l a s h ( ) ----------//
//
//  PURPOSE
//  	Reads a value from an address in flash.
//
//  INPUTS
// 		unsigned long ulAddr - the address to read from
// 		int pnValue - pointer to store value read from flash
//
//	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE ReadFlash( unsigned long ulOffset, int *pnValue )
{

	// disable interrupts before performing the load or store operation
	// [refer warning: page 6-71 BF533 HRM]
	//unsigned int uiSaveInts = cli();

	// set our flash address to where we want to read
	unsigned short *pFlashAddr = (unsigned short *)(ulFlashStartAddr+ulOffset);

	// read the value
	*pnValue = (unsigned short)*pFlashAddr;   //没看明白??是因为将该地址中写数了!

	// Enable Interrupts
    //sti(uiSaveInts);

	// ok
	return NO_ERR;
}


//----------- W r i t e F l a s h ( ) ----------//
//
//  PURPOSE
//  	Write a value to an address in flash.
//
//  INPUTS
//	 	unsigned long  ulAddr - address to write to
//		unsigned short nValue - value to write
//
//	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE WriteFlash( unsigned long ulOffset, int nValue )
{

	// disable interrupts before performing the load or store operation
	// [refer warning: page 6-71 BF533 HRM]
	//unsigned int uiSaveInts = cli();

	// set the address
	unsigned short *pFlashAddr = (unsigned short *)(ulFlashStartAddr+ulOffset);

	*pFlashAddr = nValue;

	// Enable Interrupts
    //sti(uiSaveInts);

	// ok
	return NO_ERR;
}





//----------- P o l l T o g g l e B i t ( ) ----------//
//
//  PURPOSE
//  	Polls the toggle bit in the flash to see when the operation
//		is complete.
//
//	INPUTS
//	unsigned long ulAddr - address in flash
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise


ERROR_CODE PollToggleBit(unsigned long ulOffset) //轮番查询,是否嵌入式算法运行完成
{
	ERROR_CODE ErrorCode = NO_ERR;	// flag to indicate error
	int sVal1;
	int sVal2;

	// read flash 1 time
	ReadFlash( ulOffset, &sVal1 );

	while( ErrorCode == NO_ERR )
	{
		// read the value 2 times
		ReadFlash( ulOffset, &sVal1 );
		ReadFlash( ulOffset, &sVal2 );

		// XOR to see if any bits are different
		sVal1 ^= sVal2;

		// see if we are toggling
		if( !(sVal1 & 0x40) )
			break;

		// check error bit
		if( !(sVal2 & 0x20) )
			continue;
		else
		{
			// read the value 2 times
			ReadFlash( ulOffset, &sVal1 );
			ReadFlash( ulOffset, &sVal2 );

			// XOR to see if any bits are different
			sVal1 ^= sVal2;

			// see if we are toggling
			if( !(sVal1 & 0x40) )
				break;
			else
			{
				ErrorCode = POLL_TIMEOUT;
				ResetFlash();
			}
		}
	}

	// we can return
	return ErrorCode;
}



//////////////////////////////////////////////////////////////
// ERROR_CODE ResetFlash()
//
// Sends a "reset" command to the flash.
//
//////////////////////////////////////////////////////////////

ERROR_CODE ResetFlash(void)
{
	// send the reset command to the flash
	WriteFlash(0x0AAA, 0xf0 );

	// reset should be complete
	return NO_ERR;
}




//----------- E r a s e F l a s h  ( ) ----------//
//
//  PURPOSE
//  	Sends an "erase all" command to the flash.
//
//	INPUTS
//		unsigned long ulStartAddr - flash start address
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE EraseFlash(void)
{
	ERROR_CODE ErrorCode = NO_ERR;	// tells us if there was an error erasing flash
	int nBlock = 0;					// index for each block to erase
	//unsigned long ulFlashStartAddr;	// flash start address

	// get flash start address from absolute address
	// The ulAddr should ideally be pointing to the flash start
	// address. However we just verify it here again.
	//ulFlashStartAddr = GetFlashStartAddress(ulAddr);

	// erase contents of Flash
	WriteFlash(0x0555, 0xaa );
	WriteFlash(0x02aa, 0x55 );
	WriteFlash(0x0555, 0x80 );
	WriteFlash(0x0555, 0xaa );
	WriteFlash(0x02aa, 0x55 );
	WriteFlash(0x0555, 0x10 );

	// poll until the command has completed
	ErrorCode = PollToggleBit(ulFlashStartAddr + 0x0000);


	// erase should be complete
	return ErrorCode;
}


//////////////////////////////////////////////////////////////
// ERROR_CODE EraseBlock()
//
// Sends an "erase block" command to the flash.
//
//////////////////////////////////////////////////////////////



ERROR_CODE EraseBlock( int nBlock)  //段擦除
{

	ERROR_CODE 	  ErrorCode   = NO_ERR;		//tells us if there was an error erasing flash
 	 long ulSectStart = 0x0;		//stores the sector start offset
 	 long ulSectEnd   = 0x0;		//stores the sector end offset(however we do not use it here)
	//unsigned long ulFlashStartAddr;			//flash start address

	// get flash start address from absolute address
	// The ulAddr should ideally be pointing to the flash start
	// address. However we just verify it here again.
	//ulFlashStartAddr = GetFlashStartAddress(ulAddr);

	// Get the sector start offset
	// we get the end offset too however we do not actually use it for Erase sector
	GetSectorStartEnd( &ulSectStart, &ulSectEnd, nBlock );

	// send the erase block command to the flash
	WriteFlash( 0x0555, 0xaa );
	WriteFlash( 0x02aa, 0x55 );
	WriteFlash( 0x0555, 0x80 );
	WriteFlash( 0x0555, 0xaa );
	WriteFlash( 0x02aa, 0x55 );

	// the last write has to be at an address in the block
	WriteFlash(ulSectStart, 0x30 );

	// poll until the command has completed
	ErrorCode = PollToggleBit(ulSectStart);

 	// block erase should be complete
	return ErrorCode;
}



//////////////////////////////////////////////////////////////
// ERROR_CODE UnlockFlash()
//
// Sends an "unlock" command to the flash to allow the flash
// to be programmed.
//
//////////////////////////////////////////////////////////////

ERROR_CODE UnlockFlash(unsigned long ulOffset)
{
	unsigned long ulOffsetAddr = ulOffset;
	ulOffsetAddr &= 0xFFFF0000;

	// send the unlock command to the flash
	// ORed with lOffsetAddr so we know what block we are in
	WriteFlash( 0x0555, 0xaa );
	WriteFlash( 0x02aa, 0x55 );
	WriteFlash( 0x0555, 0xa0 );

	// ok
	return NO_ERR;
}


//////////////////////////////////////////////////////////////
// ERROR_CODE GetCodes()
//
// Sends an "auto select" command to the flash which will allow
// us to get the manufacturer and device codes.
//
//////////////////////////////////////////////////////////////



ERROR_CODE GetCodes(void)
{
    //unsigned long ulFlashStartAddr;		//flash start address

	// get flash start address from absolute address
	// The ulAddr should ideally be pointing to the flash start
	// address. However we just verify it here again.
	//ulFlashStartAddr = GetFlashStartAddress(ulAddr);

	// send the auto select command to the flash
	WriteFlash( 0x0555, 0xaa );
	WriteFlash( 0x02aa, 0x55 );
	WriteFlash( 0x0555, 0x90 );

	// now we can read the codes
	ReadFlash(0x0000,&AFP_ManCode);  //读产品型号
	AFP_ManCode &= 0x00FF;

	ReadFlash(0x0001,&AFP_DevCode ); //读器件型号
	AFP_DevCode &= 0x00FF;

	// we need to issue another command to get the part out
	// of auto select mode so issue a reset which just puts
	// the device back in read mode
	ResetFlash();  

	// ok
	return NO_ERR;
}

//----------- G e t S e c t o r N u m b e r ( ) ----------//
//
//  PURPOSE
//  	Gets a sector number based on the offset.
//
//  INPUTS
//  	unsigned long ulAddr - absolute address
//		int 	 *pnSector     - pointer to sector number
//
//	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE GetSectorNumber( unsigned long ulOffset, int *pnSector)
{




	for(i = 0; i < gNumSectors; i++)
	{
	    GetSectorStartEnd(&ulStartOff, &ulEndOff, i);
		if ( (ulOffset >= ulStartOff)
			&& (ulOffset <= ulEndOff) )
		{
			error_code = 0;
			nSector = i;
			break;
		}
	}

	// if it is a valid sector, set it
	if (error_code == 0)
		*pnSector = nSector;
	// else it is an invalid sector
	else
		return INVALID_SECTOR;

	// ok
	return NO_ERR;
}


//----------- G e t S e c t o r S t a r t E n d ( ) ----------//
//
//  PURPOSE
//  	Gets a sector start and end address based on the sector number.
//
//  INPUTS
//  	unsigned long *ulStartOff - pointer to the start offset
//		unsigned long *ulEndOff - pointer to the end offset
//		int nSector - sector number
//
//	RETURN VALUE
//		ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE GetSectorStartEnd(  long *lStartOff, long *lEndOff, int nSector )
{

	if( nSector == 0 )
	{
	    *lStartOff = 0x0;
	    *lEndOff = (*lStartOff + 0x2000) - 1;     //第0段16k
	}
	else if( nSector == 1 )
	{
	    *lStartOff = 0x2000;
	    *lEndOff = (*lStartOff + 0x1000) - 1;     //第1段8K
	}
	else if( nSector == 2 )
	{
   		*lStartOff = 0x3000;
	    *lEndOff = (*lStartOff + 0x1000) - 1;     //第2段8K
	}
	else if( nSector == 3 )
	{
   		*lStartOff = 0x4000;
	    *lEndOff = (*lStartOff + 0x4000) - 1;     //第4段32K
	}
	else if( (nSector >= 4) && (nSector <= 34) )
	{
	    *lStartOff = (nSector - 3) * 0x8000;
	    *lEndOff = (*lStartOff + 0x8000) - 1;      //以后均为64K
	}
	else
		return INVALID_SECTOR;


	// ok
	return NO_ERR;
}

⌨️ 快捷键说明

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