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

📄 adi_am29lv081b.c

📁 Analog Device ADSP21346平台下对AMD Flash操作的例程
💻 C
📖 第 1 页 / 共 2 页
字号:
	WriteFlash( ulFlashStartAddr + 1, 0xaa );
	WriteFlash( ulFlashStartAddr + 2, 0x55 );
	WriteFlash( ulFlashStartAddr + 3, 0x10 );
#else
	WriteFlash( ulFlashStartAddr + 0, 0x55aa0000 );
	WriteFlash( ulFlashStartAddr + 1, 0x1055aa80 );
#endif
	
		
		// poll until the command has completed
	ErrorCode = PollToggleBit(ulFlashStartAddr, 0xFF);

	// 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
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
	WriteFlash( (ulFlashStartAddr + ulSectStart + 0), 0x00 );
	WriteFlash( (ulFlashStartAddr + ulSectStart + 1), 0x00 );
	WriteFlash( (ulFlashStartAddr + ulSectStart + 2), 0xaa );
	WriteFlash( (ulFlashStartAddr + ulSectStart + 3), 0x55 );

	WriteFlash( (ulFlashStartAddr + ulSectStart + 0), 0x80 );
	WriteFlash( (ulFlashStartAddr + ulSectStart + 1), 0xaa );
	WriteFlash( (ulFlashStartAddr + ulSectStart + 2), 0x55 );
	WriteFlash( (ulFlashStartAddr + ulSectStart + 3), 0x30 );
#else
	WriteFlash( (ulFlashStartAddr + ulSectStart ), 0x55aa0000 );
	WriteFlash( (ulFlashStartAddr + ulSectStart ), 0x3055aa80 );
#endif
	
	// poll until the command has completed
	ErrorCode = PollToggleBit(ulFlashStartAddr + ulSectStart, 0xFF);

 	// 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( const unsigned long ulOffset, const unsigned short usValue )
{
	bool bError = TRUE;				// flag to indicate error
	bool bPass = FALSE;				// flag indicating passing
	int nTimeOut = 0x1FFFFF;		// timeout after a while
	ERROR_CODE ErrorCode = NO_ERR;	// flag to indicate error
	unsigned short nReadVal = 0;

	while( bError && !bPass )
	{
		// read the data
		ReadFlash( ulOffset, &nReadVal );

		// see if the data read == data written
		if( (nReadVal & 0xFF) != usValue )
		{
			// check DQ5 bit for error
			if( (nReadVal & 0x20) == 0x20 )
				bError = FALSE;
		}
		else
			bPass = TRUE;
	}

	// if we didn't pass yet then make sure DQ7 was
	// not changing simultaneously with DQ5
	if( !bPass )
	{
		ReadFlash( ulOffset, &nReadVal );

		// see if the data read == data written
		if( (nReadVal & 0xFF) == usValue )
			bPass = TRUE;
	}

	if( !bPass )
		ErrorCode = POLL_TIMEOUT;

	// 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
	// return to standard operation mode
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
	WriteFlash( ulFlashStartAddr + 0, 0x00 );
	WriteFlash( ulFlashStartAddr + 1, 0xAA );
	WriteFlash( ulFlashStartAddr + 2, 0x55 );
	WriteFlash( ulFlashStartAddr + 3, 0x90 );
#else
	WriteFlash( ulFlashStartAddr, 0x9055aa00 );
#endif
 	
 	// read the manufacturer code
	ReadFlash( ulFlashStartAddr , (unsigned short *)pnManCode );
	*pnManCode &= 0x00FF;

	ReadFlash( ulFlashStartAddr + 1, (unsigned short *)pnDevCode );
	*pnDevCode &= 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(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;
	
	// get offset from absolute address
	unsigned long ulMask  = 0x3fffff;		 //offset mask
	unsigned long ulOffset= ulAddr & ulMask; //offset
	
	// determine the sector
	nSector = ulOffset & 0xffff0000;
	nSector = ulOffset >> 16;
	nSector = nSector & 0x000f;

	// if it is a valid sector, set it
	if ( (nSector >= 0) && (nSector < NUM_SECTORS) )
		*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 )
{
	// The blocks in the flash memory are asymmetrically arranged
	// Thus we use block sizes to determine the block addresses
	unsigned long  ulBlkSize 	= 0x10000;	// Block size 0

	// block is in main flash
	if( ( nSector < NUM_SECTORS ))
	{
		*ulStartOff =(nSector * ulBlkSize );
		*ulEndOff = ( (*ulStartOff) + ulBlkSize ) - 1;
	}
	// no such sector
	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, (NUM_SECTORS-1));
	ulMask      	  = ~(ulSectEndAddr);
	ulFlashStartAddr  =  ulAddr & ulMask;

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

#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
	// set our flash address to where we want to read
	volatile unsigned short *pFlashAddr = (volatile unsigned short *)(ulAddr);

	// read the value
	*pusValue = (unsigned short)*pFlashAddr;

#else //if __ADSP21364__ & __ADSP21262__
	
	//--- Core-Driven Transfer to read from Parallel Port ---//
	unsigned short val = 0;

	unsigned short ReadEnable = PPDUR32 | PPEN;  // enables PP read
	
	// Initiate parallel port registers ---/
	*pEMPP = 0;		// setup DMA modify
	*pEIPP = ulAddr ;// setup DMA destination
	*pICPP = 1;
	*pECPP = 1;
			
	// Initialize PPCTL register with appropriate settings
	*pPPCTL = ReadEnable;  // enables PP read	

	// Wait two core-clock cycles after PPEN is set for the parallel 
	// port to fetch two 32-bit data words
	asm("nop;");
	asm("nop;");

	val = (*pRXPP) & 0xFF;
			
    // poll to ensure parallel port has completed the transfer
	do{
	;}
	while( (*pPPCTL & (PPBS|PPDS)) != 0);

	// Fetch data from RXPP
 	*pPPCTL = 0; // clear dma control register

	*pusValue = val; // put the value at the location passed in
#endif

	// 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( const unsigned long ulAddr, const unsigned short usValue )
{

#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
	// set the address
	volatile unsigned short *pFlashAddr = (volatile unsigned short *)(ulAddr);

	*pFlashAddr = usValue;
	
#else // if __ADSP21364__ or __ADSP21262__

	//--- Core-Driven Transfer to write to Parallel Port ---//
	unsigned short WriteEnable = PPDUR32 | PPTRAN  | PPEN;  // enables PP write

	//--- Initiate parallel port registers ---/
	*pEMPP = 0;
	*pEIPP = ulAddr;
	*pICPP = 1;
	*pECPP = 4;
	
	// Initialize PPCTL register with appropriate settings
	*pPPCTL = WriteEnable;
	*pTXPP = usValue;
	*pPPCTL |= PPDEN|PPEN;
	
	//poll to ensure parallel port has completed the transfer
	do{
	;}
	while( (*pPPCTL & (PPBS|PPDS)) != 0);

	// clear dma control register
	*pPPCTL = 0;
	
#endif
	// ok
	return NO_ERR;
}


⌨️ 快捷键说明

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