at25f2048_test.c

来自「ADI 公司的DSP ADSP21262 EZ-KIT LITE开发板的全部源代」· C语言 代码 · 共 538 行

C
538
字号
/*****************************************************************************
**																			**
**	 Name: 	AT25F2048_test.c													**	
**																			**
******************************************************************************

(C) Copyright 2006 - Analog Devices, Inc.  All rights reserved.

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.  

Purpose:	Perform a POST flash memory AT25F2048 test on the 21364 EZ-Kit Lite	

                                                                               

******************************************************************************/  
// AT25F2048_test.c


#include <cdef21262.h>
#include <def21262.h>
#include <sysreg.h>
#include <string.h>
#include <drivers\flash\util.h>
#include <drivers\flash\adi_m25p20.h>
#include <drivers\flash\adi_at25f2048.h>
#include <drivers\flash\Errors.h>
#define	MAX_DEV				3

// start address of SPI flash
#define FLASH_START_ADDR	0x000000
#define BUFFER_SIZE			0x400
#define MAX_NUM_SECTORS 	4
#define BAUD_RATE_DIVISOR 	100

static volatile int  SPI_ManCode 	= -1;			// 0x1F 	= Atmel
static volatile int  SPI_DevCode 	= -1;			// 0x63 = AT25F2048, 0x60 = AT25F2048

//----- f u n c t i o n   p r o t o t y p e s -----//

ERROR_CODE OpenFlashDevice(void);
ERROR_CODE GetNumSectors(void);
ERROR_CODE AT25F2048_SetupForFlash(void);
ERROR_CODE AT25F2048_GetSectorMap(void);
ERROR_CODE AT25F2048_EraseFlashSector(unsigned short usSector);
ERROR_CODE AT25F2048_ReadData( unsigned long ulStart, long lCount, long lStride, int *pnData );
ERROR_CODE AT25F2048_WriteData( unsigned long ulStart, long lCount, long lStride, int *pnData );
ERROR_CODE AT25F2048_EraseFlashAll(void);
ERROR_CODE AT25F2048_GetFlashInfo(void);

//----- c o n s t a n t   d e f i n i t i o n s -----//

int 	 *AFP_SectorInfo;
int		 AFP_NumSectors=-1;		// number of sectors in the flash device

ADI_DEV_PDD_ENTRY_POINT *pADISPIFlashEntryPoint;
ADI_DEV_PDD_ENTRY_POINT *g_ADISPIFlashEntryPoint_PTR[MAX_DEV] = 
{
	&ADIM25P20EntryPoint,
	&ADIAT25F2048EntryPoint,
	&ADIAT25F2048EntryPoint
};
const unsigned int g_FlashDevCode[MAX_DEV] = 
{
	0x12,
	0x60,
	0x63 
};	
typedef struct _SECTORLOCATION
{
 	unsigned long ulStartOff;
	unsigned long ulEndOff;
}SECTORLOCATION;

SECTORLOCATION SectorInfo[MAX_NUM_SECTORS];

// test serial flash memory
int TEST_AT25F2048_FLASH(void)
{
    
	int i = 0;
	COMMAND_STRUCT CmdStruct;
	ERROR_CODE ErrorCode = NO_ERR;			//return error code
	int write_data=0;
	int read_data=0;
	int AFP_Offset;
	int AFP_Stride;
	int TestSize;
	
	*pSPIDMAC = 0;
	*pSPIBAUD = 0;
	*pSPIFLG = 0xF80;
	*pSPICTL = 0x400;
	
	//turn off PPFLGS, or flash memory stop working
	*pSYSCTL &= (~PPFLGS);

	ErrorCode = AT25F2048_SetupForFlash();
	
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
					
	// The 21262 SPI Flash can support 2 devices M25P20 / AT25F2048
	// Since the system services does not support Sharc, we temporaily make a call
	// to device#1, get codes to determine if the device is correct. If the device
	// does not match then we open device #2 and proceed.
	// NOTE: Once the ssl is in place the DevMgr shall handle this.
	ErrorCode = OpenFlashDevice();
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}

	// get the number of sectors for this device
	if( ErrorCode == NO_ERR )
	{
		ErrorCode = GetNumSectors();
	}
			
	ErrorCode = AT25F2048_GetSectorMap();
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
	
	//--- TEST BEGINS (Testing Last Sector only)	
	// Erase last sector 	
	ErrorCode = AT25F2048_EraseFlashSector(AFP_NumSectors-1);
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
	
	//Fill Last sector						
	AFP_Offset = SectorInfo[AFP_NumSectors-1].ulStartOff;
	AFP_Stride = 1;
	TestSize =  SectorInfo[AFP_NumSectors-1].ulEndOff - SectorInfo[AFP_NumSectors-1].ulStartOff;

	// the size of last sector
	for( i=0; i<TestSize; i++)
	{
		if(write_data>0xff)
			write_data = 0;

		ErrorCode = AT25F2048_WriteData( AFP_Offset, 1, AFP_Stride, (int *)&write_data );
		if(ErrorCode!=NO_ERR)
		{
		    *pSYSCTL |= PPFLGS;
			return false;
		}
		ErrorCode = AT25F2048_ReadData( AFP_Offset, 1, AFP_Stride, (int *)&read_data );
		if(ErrorCode!=NO_ERR)
		{
		    *pSYSCTL |= PPFLGS;
			return false;
		}
		read_data &= 0xff; //mask the first 3 bytes
		if(write_data != read_data)
		{
		    //error
		    *pSYSCTL |= PPFLGS;
		     return false;
		}
		AFP_Offset++;
		write_data++;
		read_data = 0;

	}
	// Close the Device
	ErrorCode = (ERROR_CODE)(*pADISPIFlashEntryPoint).adi_pdd_Close(NULL);
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
	
	*pSYSCTL |= PPFLGS;		
	return true;	
}    


//----------- S e t u p F o r F l a s h ( ) ----------//
//
//  PURPOSE
// 		Perform necessary setup for the processor to talk to the
//		flash such as external memory interface registers, etc.
//
//  RETURN VALUE
//  	ERROR_CODE - value if any error occurs during Opcode scan
//  	NO_ERR     - otherwise

ERROR_CODE AT25F2048_SetupForFlash(void)
{
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
	SRU(SPI_CLK_O,DPI_PB03_I);
	SRU(HIGH,DPI_PBEN03_I);
	
	// for the flag pins to act as chip select
	SRU(FLAG4_O, DPI_PB05_I);
	SRU(HIGH, DPI_PBEN05_I);
	

	//First set flag 4 as an output
	sysreg_bit_set( sysreg_FLAGS, FLG4O ); //asm("bit set flags FLG4O;");
	sysreg_bit_set( sysreg_FLAGS, FLG4 ); //asm("bit set flags FLG4;"); //Logic high
	
#elif (__ADSP21364__) || (__ADSP21262__)

	//First set flag 0 as an output
	sysreg_bit_set( sysreg_FLAGS, FLG0O ); 
	sysreg_bit_set( sysreg_FLAGS, FLG0 );  //Logic high

#endif
	return NO_ERR;

	
}
	
//----------- O p e n F l a s h D e v i c e ( ) ----------//
//
//  PURPOSE
//  	Opens the appropriate flash device.
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs during Opcode scan
//  	NO_ERR     - otherwise
//
// 	CHANGES
//  	9-28-2005 Created

ERROR_CODE OpenFlashDevice(void)
{
	ERROR_CODE ErrorCode = 	NO_ERR; 		//return error code
	int n;
	
	for( n=0; n<MAX_DEV; n++)
	{

		pADISPIFlashEntryPoint = g_ADISPIFlashEntryPoint_PTR[n];
		
		// open the device	
	   	ErrorCode = (ERROR_CODE) (*g_ADISPIFlashEntryPoint_PTR[n]).adi_pdd_Open(	NULL,		// DevMgr handle
								n,										// pdd entry point
								NULL,									// device instance
								NULL,									// client handle callback identifier
					  			ADI_DEV_DIRECTION_BIDIRECTIONAL,		// data direction for this device
								NULL,			// DevMgr handle for this device
								NULL,			// handle to DmaMgr for this device
								NULL,			// handle to deferred callback service
								NULL );			// client's callback function
								
		// get flash manufacturer & device codes, title & desc
		if( ErrorCode == NO_ERR )
		{
			ErrorCode = AT25F2048_GetFlashInfo();
		}				

		if( SPI_DevCode == g_FlashDevCode[n] )	
		{
	  	   // reset the flash to a known state	
			COMMAND_STRUCT SCmdStruct;
			SCmdStruct.SReset.ulFlashStartAddr = FLASH_START_ADDR;
			ErrorCode = (ERROR_CODE)(*g_ADISPIFlashEntryPoint_PTR[n]).adi_pdd_Control(NULL, CNTRL_RESET, &SCmdStruct );
	
			return ErrorCode;
  
		}
	}	
	
	return(ErrorCode);
}

//----------- G e t N u m S e c t o r s  ( ) ----------//
//
//  PURPOSE
//  	Get the number of sectors for this device.
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise
//
// 	CHANGES
//  	9-28-2005 Created

ERROR_CODE GetNumSectors(void)
{

	ERROR_CODE ErrorCode = NO_ERR;			//return error code

	GET_NUM_SECTORS_STRUCT	SGetNumSectors;	//structure for GetNumSectors
	SGetNumSectors.pnNumSectors = &AFP_NumSectors;

	ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_GETNUM_SECTORS, (COMMAND_STRUCT *)&SGetNumSectors  );

	return(ErrorCode);
}

//----------- G e t S e c t o r M a p  ( ) ----------//
//
//  PURPOSE
//  	Get the start and end offset for each sector in the flash.
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise
//
// 	CHANGES
//  	9-28-2005 Created

ERROR_CODE AT25F2048_GetSectorMap(void)
{

	ERROR_CODE ErrorCode = NO_ERR;			//return error code
	GET_SECTSTARTEND_STRUCT	SSectStartEnd;	//structure for GetSectStartEnd
	int i;									//index

	//initiate sector information structures
	for( i=0;i<AFP_NumSectors; i++)
	{
		SSectStartEnd.nSectorNum = i;
		SSectStartEnd.pStartOffset = &SectorInfo[i].ulStartOff;
		SSectStartEnd.pEndOffset = &SectorInfo[i].ulEndOff;

		ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_GET_SECSTARTEND, (COMMAND_STRUCT *)&SSectStartEnd  );
	}

	AFP_SectorInfo = (int*)&SectorInfo[0];

	return(ErrorCode);
}


//----------- G e t F l a s h I n f o  ( ) ----------//
//
//  PURPOSE
//  	Get the manufacturer code and device code
//
// 	RETURN VALUE
//  	ERROR_CODE - value if any error occurs
//  	NO_ERR     - otherwise
//
// 	CHANGES
//  	9-28-2005 Created

ERROR_CODE AT25F2048_GetFlashInfo(void)
{
	ERROR_CODE ErrorCode = NO_ERR;		//return error code
	static GET_CODES_STRUCT  SGetCodes;	//structure for GetCodes
	COMMAND_STRUCT CmdStruct;

	//setup code so that flash programmer can just read memory instead of call GetCodes().
	CmdStruct.SGetCodes.pManCode = (unsigned long *)&SPI_ManCode;
	CmdStruct.SGetCodes.pDevCode = (unsigned long *)&SPI_DevCode;
	CmdStruct.SGetCodes.ulFlashStartAddr = FLASH_START_ADDR;

	ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_GET_CODES, &CmdStruct );

	if(!ErrorCode)
	{
		ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_GET_DESC, &CmdStruct );
	}
	return(ErrorCode);
}


ERROR_CODE AT25F2048_EraseFlashSector(unsigned short usSector)
{
	ERROR_CODE ErrorCode = NO_ERR;			//return error code
    COMMAND_STRUCT CmdStruct;
    
	CmdStruct.SEraseSect.nSectorNum  		= usSector;		// Sector Number to erase
	CmdStruct.SEraseSect.ulFlashStartAddr 	= FLASH_START_ADDR;	// FlashStartAddress
	ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_ERASE_SECT, &CmdStruct);

	return(ErrorCode);
    
}
ERROR_CODE AT25F2048_EraseFlashAll(void)
{
	ERROR_CODE ErrorCode = NO_ERR;			//return error code
    COMMAND_STRUCT CmdStruct;
	CmdStruct.SEraseAll.ulFlashStartAddr 	= FLASH_START_ADDR;	//FlashStartAddress
	ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_ERASE_ALL, &CmdStruct );

	return 	ErrorCode;
}


//----------- W r i t e D a t a  ( ) ----------//
//
//  PURPOSE
//  	Write a buffer to flash device.
//
// 	INPUTS
// 		unsigned long ulStart - address in flash to start the writes at
//		long lCount - number of elements to write, in this case bytes
//		long lStride - number of locations to skip between writes
//		int *pnData - pointer to data buffer
//
//  RETURN VALUE
//  	ERROR_CODE - value if any error occurs during writing
//  	NO_ERR     - otherwise
//
//  CHANGES
//  	9-28-2005 Created

ERROR_CODE AT25F2048_WriteData( unsigned long ulStart, long lCount, long lStride, int *pnData )
{
	long i = 0;						// loop counter
	ERROR_CODE ErrorCode = NO_ERR;	// tells whether there was an error trying to write
	int nCompare = 0;				// value that we use to verify flash
	bool bVerifyError = FALSE;		// lets us know if there was a verify error
	unsigned long ulAbsoluteAddr;   // current address to write
	unsigned long ulSector = 0;		// sector number to verify address

	ADI_DEV_1D_BUFFER		WriteBuff;	// buffer pointer
	ADI_DEV_1D_BUFFER		ReadBuff;	// buffer pointer

	ulAbsoluteAddr = FLASH_START_ADDR + ulStart;

	COMMAND_STRUCT	CmdStruct;	//structure for GetSectStartEnd

	// write the buffer up to BUFFER_SIZE items
	for (i = 0; ( i < lCount ) && ( ErrorCode == NO_ERR ); i++, ulAbsoluteAddr += lStride)
	{

		// check to see that the address is within a valid sector
		CmdStruct.SGetSectNum.ulOffset = ulAbsoluteAddr;
		CmdStruct.SGetSectNum.pSectorNum = &ulSector;
		ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_GET_SECTNUM, &CmdStruct  );

		if( NO_ERR == ErrorCode )
		{
			// unlock the flash, do the write, increase shift, and wait for completion
			WriteBuff.Data 				= (void *)&pnData[i] ;
			WriteBuff.pAdditionalInfo 	= (void *)&ulAbsoluteAddr ;
				ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Write(NULL, ADI_DEV_1D, (ADI_DEV_BUFFER *)&WriteBuff);
		}
		else
		{
			return ErrorCode;
		}
	}

	// return the appropriate error code
	return ErrorCode;
}


//----------- R e a d D a t a  ( ) ----------//
//
//  PURPOSE
//  	Read a buffer from flash device.
//
// 	INPUTS
//		unsigned long ulStart - address in flash to start the reads at
//		long lCount - number of elements to read, in this case bytes
//		long lStride - number of locations to skip between reads
//		int *pnData - pointer to data buffer to fill
//
//	RETURN VALUE
//  	ERROR_CODE - value if any error occurs during reading
//  	NO_ERR     - otherwise
//
//  CHANGES
//  	9-28-2005 Created

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

	long i = 0;						// loop counter
	ERROR_CODE ErrorCode = NO_ERR;	// tells whether there was an error trying to read
	unsigned long ulAbsoluteAddr;   // current address to read
	unsigned long ulSector = 0;		// sector number to verify address
	unsigned long ulMask =0xffff;

	ADI_DEV_1D_BUFFER		ReadBuff;	// buffer pointer

	COMMAND_STRUCT	CmdStruct;	//structure for GetSectStartEnd

	ulAbsoluteAddr = FLASH_START_ADDR + ulStart;

	// read the buffer up to BUFFER_SIZE items 
	for (i = 0; (i < lCount) && (i < BUFFER_SIZE); i++, ulAbsoluteAddr += lStride)
	{
		// check to see that the address is within a valid sector
		CmdStruct.SGetSectNum.ulOffset = ulAbsoluteAddr;
		CmdStruct.SGetSectNum.pSectorNum = &ulSector;
		ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Control(NULL, CNTRL_GET_SECTNUM, &CmdStruct  );

		if( NO_ERR == ErrorCode )
		{
			ReadBuff.Data 				= (void *)&pnData[i];
			ReadBuff.pAdditionalInfo 	= (void *)&ulAbsoluteAddr ;
		ErrorCode = (ERROR_CODE) (*pADISPIFlashEntryPoint).adi_pdd_Read(NULL, ADI_DEV_1D, (ADI_DEV_BUFFER *)&ReadBuff);
		}
		else
		{
			return ErrorCode;
		}
	}

	// return the appropriate error code
	return ErrorCode;
}

/*********************************************************************
*
*	Function:	main
*
*********************************************************************/
#ifdef _STANDALONE_ // use this to run standalone tests
int main(void)
{
	int iStatus;

	asm("nop;");

	while(1)
	{
		iStatus = TEST_AT25F2048_FLASH();
		if( 0 == iStatus )
		{
			asm("emuexcpt;");
		}
	}

}
#endif //#ifdef _STANDALONE_ // use this to run standalone tests


⌨️ 快捷键说明

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