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

📄 bf531am29driver.c

📁 开发平台是ADSP++,用于ADI的BF531驱动AM29160FLASH的源程序。自己编写
💻 C
📖 第 1 页 / 共 2 页
字号:
	WriteFlash( ulFlashStartAddr + 0x0AAA, 0x10 );

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


	// erase should be complete
	return ErrorCode;
}


//----------- E r a s e B l o c k ( ) ----------//
//
//  PURPOSE
//  	Sends an "erase block" command to the flash.
//
//	INPUTS
//		int nBlock - block to erase
//		unsigned long ulStartAddr - flash start address
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE EraseBlock( int nBlock, unsigned long ulAddr )  //段擦除
{

	ERROR_CODE 	  ErrorCode   = NO_ERR;		//tells us if there was an error erasing flash
 	unsigned long ulSectStart = 0x0;		//stores the sector start offset
 	unsigned 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( (ulFlashStartAddr + 0x0AAA), 0xaa );
	WriteFlash( (ulFlashStartAddr + 0x0554), 0x55 );
	WriteFlash( (ulFlashStartAddr + 0x0AAA), 0x80 );
	WriteFlash( (ulFlashStartAddr + 0x0AAA), 0xaa );
	WriteFlash( (ulFlashStartAddr + 0x0554), 0x55 );

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

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

 	// block erase should be complete
	return ErrorCode;
}


//----------- 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 ulAddr) //轮番查询,是否嵌入式算法运行完成
{
	ERROR_CODE ErrorCode = NO_ERR;	// flag to indicate error
	unsigned short sVal1;
	unsigned short sVal2;

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

	while( ErrorCode == NO_ERR )
	{
		// read the value 2 times
		ReadFlash( ulAddr, &sVal1 );
		ReadFlash( ulAddr, &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( ulAddr, &sVal1 );
			ReadFlash( ulAddr, &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(ulAddr);
			}
		}
	}

	// we can return
	return ErrorCode;
}


//----------- G e t C o d e s ( ) ----------//
//
//  PURPOSE
//  	Sends an "auto select" command to the flash which will allow
//		us to get the manufacturer and device codes.
//
//  INPUTS
//  	int *pnManCode - pointer to manufacture code
//		int *pnDevCode - pointer to device code
//		unsigned long ulStartAddr - flash start address
//
//	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise

ERROR_CODE GetCodes(int *pnManCode, int *pnDevCode, unsigned long ulAddr)
{
    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( ulFlashStartAddr + 0x0aaa, 0xaa );
	WriteFlash( ulFlashStartAddr + 0x0554, 0x55 );
	WriteFlash( ulFlashStartAddr + 0x0aaa, 0x90 );

	// now we can read the codes
	ReadFlash( ulFlashStartAddr + 0x0000,(unsigned short *)pnManCode );  //读产品型号
	*pnManCode &= 0x00FF;

	ReadFlash( ulFlashStartAddr + 0x0002, (unsigned short *)pnDevCode ); //读器件型号
	*pnDevCode &= 0x00FF;

	if( *pnDevCode == 0x49 )     //49 DB ----是否是49?
	{
	    gNumSectors = 35;     //35g段
	  	pFlashDesc = "AM29LV160DB(2M x 8)";
	}
	else
	{
	    gNumSectors = 35;
		pFlashDesc = "S29AL004D(256 x 16)";
	}

	// 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(ulAddr);

	// 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 ulAddr, int *pnSector )
{
	int nSector = 0;
	int i;
	int error_code = 1;
	unsigned long ulMask;					//offset mask
	unsigned long ulOffset;					//offset
	unsigned long ulStartOff;
	unsigned long ulEndOff;

	ulMask      	  = 0x3fffff;
	ulOffset		  = ulAddr & ulMask;

	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( unsigned long *ulStartOff, unsigned long *ulEndOff, int nSector )
{
	long lSectorSize = 0;
	long lChipNo;
	int nSectorOffsetInChip;
	long lChipSize;

	lChipNo = nSector/gNumSectors;    //第几段 gNumSectors全局变量
	nSectorOffsetInChip = nSector%gNumSectors;  //除以取余数,以此判断段的起止地址 
	lChipSize = 1024 * 1024;    //1M  ---没用上!!


	if( nSectorOffsetInChip == 0 )
	{
	    *ulStartOff = 0x0;
	    *ulEndOff = (*ulStartOff + 0x4000) - 1;     //第0段16k
	}
	else if( nSectorOffsetInChip == 1 )
	{
	    *ulStartOff = 0x4000;
	    *ulEndOff = (*ulStartOff + 0x2000) - 1;     //第1段8K
	}
	else if( nSectorOffsetInChip == 2 )
	{
   		*ulStartOff = 0x6000;
	    *ulEndOff = (*ulStartOff + 0x2000) - 1;     //第2段8K
	}
	else if( nSectorOffsetInChip == 3 )
	{
   		*ulStartOff = 0x8000;
	    *ulEndOff = (*ulStartOff + 0x8000) - 1;     //第4段32K
	}
	else if( (nSectorOffsetInChip >= 4) && (nSectorOffsetInChip <= 18) )
	{
	    *ulStartOff = (nSectorOffsetInChip - 3) * 0x10000;
	    *ulEndOff = (*ulStartOff + 0x10000) - 1;      //以后均为64K
	}
	else
		return INVALID_SECTOR;


	// ok
	return NO_ERR;
}


//----------- G e t F l a s h S t a r t A d d r e s s ( ) ----------//
//
//  PURPOSE
//  	Gets flash start address from an absolute address.
//
//  INPUTS
//  	unsigned long ulAddr - absolute address
//
//	RETURN VALUE
//		unsigned long - Flash start address

unsigned long GetFlashStartAddress( unsigned long ulAddr)
{

	ERROR_CODE 	  ErrorCode = NO_ERR;		//tells us if there was an error erasing flash
	unsigned long ulFlashStartAddr;			//flash start address
	unsigned long ulSectStartAddr;			//sector start address
	unsigned long ulSectEndAddr;			//sector end address
	unsigned long ulMask;					//offset mask

	// get flash start address from absolute address
	GetSectorStartEnd( &ulSectStartAddr, &ulSectEndAddr, (gNumSectors-1));
	ulMask      	  = ~(ulSectEndAddr);
	ulFlashStartAddr  =  ulAddr & ulMask;   //从绝对地址读取FLASH起始地址?

	return(ulFlashStartAddr);
}


//----------- 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 ulAddr, unsigned short *pusValue )
{

	// 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 *)(ulAddr);

	// read the value
	*pusValue = (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 ulAddr, unsigned short usValue )
{

	// 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 *)(ulAddr);

	*pFlashAddr = usValue;

	// Enable Interrupts
    sti(uiSaveInts);

	// ok
	return NO_ERR;
}

⌨️ 快捷键说明

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