am29lv081b_test.c

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

C
398
字号
///////////////////////////////////////////////////////////////
//
// am29lv081b_test.c
//
// Analog Devices, Inc. - 2006
//
// Rev - 1.00.0
//
// Fixes in this Release
//
//
// Change Log
//
//		1.00.0
//			- initial release
//
// Test ADSP-21262 EZ-KIT Lite AMD AM29LV081B flash that is connected
// by parallel port. The test programe does write/read to last sector 
// of flash and compare the data is the same. The test pass if the 
// data is same. Otherwise failed.
//
//
///////////////////////////////////////////////////////////////


#include <cdef21262.h>
#include <def21262.h>
#include <string.h>
#include "adi_am29lv081b.h"		// flash-AM29LV081B includes
#include "Services_Sharc.h"			// system services buffers
#include "util.h" 				// library struct includes
#include "Errors.h"				// error type includes


/* AMD AM29LV081B flash Memory Location */

#define FLASH_START_ADDR	0x1000000
#define BUFFER_SIZE		0x600

ERROR_CODE GetFlashInfo(void);
ERROR_CODE GetSectorMap(void);
ERROR_CODE EraseFlashSector(unsigned short usSector);
ERROR_CODE ReadData( unsigned long ulStart, long lCount, long lStride, int *pnData );
ERROR_CODE WriteData( unsigned long ulStart, long lCount, long lStride, int *pnData );

int 			*AFP_SectorInfo;
int 			AFP_ManCode 		= -1;			// 0x01 	= Atmel
int 			AFP_DevCode 		= -1;			// 0x38 	= AT49BV040

typedef struct _SECTORLOCATION
{
 	unsigned long ulStartOff;
	unsigned long ulEndOff;
}SECTORLOCATION;

SECTORLOCATION SectorInfo[NUM_SECTORS];



// test parallel port flash memory
int TEST_AM29LV081B_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;

	//turn off PPFLGS, or AM29LV081B_FLASH stop working
	*pSYSCTL &= (~PPFLGS);

	// open the device
	ErrorCode = (ERROR_CODE)ADIAM29LV081BEntryPoint.adi_pdd_Open(	NULL,		// DevMgr handle
							0,				// 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
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}		
	if (GetFlashInfo() != NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
	if( (0x01 != AFP_ManCode) || (0x38 != AFP_DevCode) )
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}						
	ErrorCode = GetSectorMap();
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
	//test last sector only	
	ErrorCode = EraseFlashSector(NUM_SECTORS-1);
	if(ErrorCode!=NO_ERR)
	{
	    *pSYSCTL |= PPFLGS;
		return false;
	}
							
	AFP_Offset = SectorInfo[NUM_SECTORS-1].ulStartOff;
	AFP_Stride = 1;
	TestSize =  SectorInfo[NUM_SECTORS-1].ulEndOff - SectorInfo[NUM_SECTORS-1].ulStartOff;

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

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

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

//----------- 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 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 *)&AFP_ManCode;
	CmdStruct.SGetCodes.pDevCode = (unsigned long *)&AFP_DevCode;
	CmdStruct.SGetCodes.ulFlashStartAddr = FLASH_START_ADDR;

	ADIAM29LV081BEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_CODES, &CmdStruct );


	ADIAM29LV081BEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_DESC, &CmdStruct );

	return(ErrorCode);

}


//----------- GetSectorMap  ( ) ----------//
//
//  PURPOSE
//  	Get flash sector map.
//
// 	INPUTS
// 		None
//
//  RETURN VALUE
//  	ERROR_CODE - value if any error occurs during writing
//  	NO_ERR     - otherwise
//
//  CHANGES
//  	9-28-2005 Created
ERROR_CODE GetSectorMap()
{

	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<NUM_SECTORS; i++)
	{
		SSectStartEnd.nSectorNum = i;
		SSectStartEnd.pStartOffset = &SectorInfo[i].ulStartOff;
		SSectStartEnd.pEndOffset = &SectorInfo[i].ulEndOff;

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

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

	return(ErrorCode);
}


//----------- EraseFlashSector  (unsigned short usSector ) ----------//
//
//  PURPOSE
//  	Erase the nth sector on flash.
//
// 	INPUTS
// 		unsigned short usSector - The sector that need be erased
//
//  RETURN VALUE
//  	ERROR_CODE - value if any error occurs during writing
//  	NO_ERR     - otherwise
//
//  CHANGES
//  	9-28-2005 Created

ERROR_CODE 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) ADIAM29LV081BEntryPoint.adi_pdd_Control(NULL, CNTRL_ERASE_SECT, &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 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) ADIAM29LV081BEntryPoint.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) ADIAM29LV081BEntryPoint.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 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) ADIAM29LV081BEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_SECTNUM, &CmdStruct  );

		if( NO_ERR == ErrorCode )
		{
			ReadBuff.Data 				= (void *)&pnData[i];
			ReadBuff.pAdditionalInfo 	= (void *)&ulAbsoluteAddr ;
			ErrorCode = (ERROR_CODE) ADIAM29LV081BEntryPoint.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_AM29LV081B_FLASH();
		if( 0 == iStatus )
		{
			asm("emuexcpt;");
		}
	}

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




⌨️ 快捷键说明

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