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

📄 parallel_flash_test.c

📁 ADI Blackfin BF51X 範例程式
💻 C
字号:
/*******************************************************************
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.

Project Name:  	Power_On_Self_Test

Hardware:		ADSP-BF518 EZ-Board

Description:	This file tests the parallel flash on the EZ-Board.
*******************************************************************/


/*******************************************************************
*  include files
*******************************************************************/
#include <cdefBF518.h>
#include <ccblkfn.h>
#include <stdlib.h>
#include <drivers\flash\util.h>     /* library struct includes */
#include <drivers\flash\Errors.h>   /* error type includes */
#include "m29w320.h"		    	/* flash includes */


#define FLASH_START_ADDR 		0x20000000	/* start address on EZ-Board */


/*******************************************************************
*  function prototypes
*******************************************************************/
int CheckForCFISupport(void);


/*******************************************************************
*   Function:    Init_ParallelMemorySelects
*   Description: This function configures memory selects for parallel flash.
*******************************************************************/
void Init_ParallelMemorySelects(void)
{
	/* PG11 - AMS2, PG15 - AMS3 */
	
	/* setup mux bits */
	short portg_mux = *pPORTG_MUX;	/* bits [15:14] = 10 for AMS3
									   bits [13:12] = 01 for AMS2 */
	portg_mux |= 0x9000;			/* set bits 15, 12 */
	portg_mux &= 0x9fff;			/* clear bits 14, 13 */
	*pPORTG_MUX = portg_mux;		/* write it back */
	*pPORTG_FER |= (PG15 | PG11);	/* enable peripheral function */
}


/*******************************************************************
*   Function:    TEST_PARALLEL_FLASH(void)
*   Description: performs a test on the parallel flash
*******************************************************************/
int TEST_PARALLEL_FLASH(void)
{
	int i, j;							/* indexes */
	unsigned int iPassed = 1;			/* result from test */
	ERROR_CODE Result = NO_ERR;			/* result */
	COMMAND_STRUCT pCmdBuffer;			/* command buffer union */
	unsigned short usRd = 0, usWr = 0;	/* storage for data */
	int nManCode = 0, nDevCode = 0;		/* man and device ids */


	/* sectors to be tested: we chose one sector from a few different banks, making
	   sure we don't overwrite any sector of flash where the boot image lives */
	int pnTestSectors[] = { 31,		/* 0x */
							47,		/* 0x */
							55,		/* 0x */
							70,		/* 0x : locked-down sector shouldn't work */
							-1};	/* must end with -1 */

	/* init memory selects which are muxed on BF518 */
	Init_ParallelMemorySelects();
	
	/* open the parallel flash */
	Result = m29w320_Open();

	if (Result != NO_ERR)
	{
		return 0;
	}

	/* setup the external bus control */
	*pEBIU_AMGCTL = 0xFF;

	/* get the codes */
	pCmdBuffer.SGetCodes.pManCode = (unsigned long *)&nManCode;
	pCmdBuffer.SGetCodes.pDevCode = (unsigned long *)&nDevCode;
	pCmdBuffer.SGetCodes.ulFlashStartAddr = FLASH_START_ADDR;
	Result = m29w320_Control( CNTRL_GET_CODES, &pCmdBuffer );

	/* if codes don't match what we expect then we should fail */
	if( (FLASH_MANUFACTURER_ST != nManCode) || (FLASH_DEVCODE_ST_M29W320EB != nDevCode) )
	{
		return 0;
	}

	/* we also show how to determine if this part supports the Common Flash Interface (CFI) and
		if so, we will attempt to get the CFI data */
	if (!CheckForCFISupport())
	{
		/* this means there was a failure not that the device does not support CFI, so
			therefore we return failure */
		return 0;
	}

	/* for each test sector */
	for ( usWr = 0x1234, j = 0; (pnTestSectors[j] != -1) && (iPassed); j++ )
	{
		/* erase the sector */
		pCmdBuffer.SEraseSect.ulFlashStartAddr = FLASH_START_ADDR;
		pCmdBuffer.SEraseSect.nSectorNum = pnTestSectors[j];
		Result = m29w320_Control( CNTRL_ERASE_SECT, &pCmdBuffer );

		/* if the erase passed, continue */
		if(NO_ERR == Result)
		{
			/* write some data */
			for( i = 0; i < 0x8; i+=2, usWr+= 0x1111 )
			{
				unsigned long ulOffset;

				/* calculate offset based on sector */
				if ( pnTestSectors[j] < 8 )
				{
					ulOffset = pnTestSectors[j]*8*1024 + i + FLASH_START_ADDR;
				}
				else
				{
					ulOffset = 0x10000 + + i + FLASH_START_ADDR + ( (64*1024)*(pnTestSectors[j] - 8) );
				}

				/* write a word to the flash */
				Result = m29w320_Write( &usWr, ulOffset, 0x1 );

				if(NO_ERR == Result)
				{
					iPassed = 1;

					/* now do a read */
					Result = m29w320_Read( &usWr, ulOffset, 0x1 );

					if(NO_ERR == Result)
					{
						/* compare the data, writes should not work here */
						if ( 70 == pnTestSectors[j])	
						{
							if( usRd == usWr )
							{
								iPassed = 0;
								break;
							}
						}
						
						/* compare the data, writes should work here */
						else
						{
							if( usRd != usWr )
							{
								iPassed = 0;
								break;
							}
						}
					}
				}
			}
		}

		/* if erase failed, break out */
		else
			break;

		/* at this point the sector test passed, erase it again */
		Result = m29w320_Control( CNTRL_ERASE_SECT, &pCmdBuffer );
	}

	/* close driver and return result */
	m29w320_Close();

	return iPassed;
}


/*******************************************************************
*   Function:    CheckForCFISupport
*   Description: Checks if the devices supports the Common Flash Interface
*	             (CFI) and if so gets the CFI data.
*******************************************************************/
int CheckForCFISupport(void)
{
	ERROR_CODE Result = NO_ERR;			/* result from driver */
	COMMAND_STRUCT pCmdBuffer;			/* command buffer union */
	bool bSupportsCFI = false;			/* see if this device supports CFI */
	int nFlashWidth = 0x0;				/* flash width */
	char pCFIData[128*2];				/* provide enough for 16-bit wide flashes */
	char *pQRY = NULL;					/* ptr to QRY string within CFI data */
	unsigned short usPrimary = 0x0;		/* primary pointer within CFI data */
	unsigned short usDeviceSize = 0x0;	/* device size (2^n) within CFI data */
	unsigned short usMajVerASCII = 0x0;	/* major version in ASCII within CFI data */
	unsigned short usMinVerASCII = 0x0;	/* minor version in ASCII within CFI data */

	/* see if this device support CFI */
	pCmdBuffer.SSupportsCFI.pbSupportsCFI = &bSupportsCFI;
	Result = m29w320_Control( CNTRL_SUPPORTS_CFI, &pCmdBuffer );
	if (Result == UNKNOWN_COMMAND)
	{
		return 1;	/* not a failure, but the driver doesn't even support this command */
	}
	else if (Result != NO_ERR)
    {
        return 0;
    }

    /* if it supports CFI we can read the CFI data */
	if ( bSupportsCFI )
	{
		/* first check on the device width so we know how large the CFI data will be and
			how to interpret it */
		pCmdBuffer.SGetFlashWidth.pnFlashWidth = &nFlashWidth;
		Result = m29w320_Control( CNTRL_GET_FLASH_WIDTH, &pCmdBuffer );
		if (Result == UNKNOWN_COMMAND)
		{
			return 1;	/* not a failure, but the driver doesn't even support this command */
		}
		else if (Result != NO_ERR)
	    {
	        return 0;
	    }

	    /* now get the CFI data, make sure enough memory is allocated for the flash width
	    	which is 128 bytes per 8-bit width */
	    pCmdBuffer.SGetCFIData.pCFIData = pCFIData;
	    pCmdBuffer.SGetCFIData.ulFlashStartAddr = 0x0;
		Result = m29w320_Control( CNTRL_GET_CFI_DATA, &pCmdBuffer );
		if (Result == UNKNOWN_COMMAND)
		{
			return 1;	/* not a failure, but the driver doesn't even support this command */
		}
		else if (Result != NO_ERR)
	    {
	        return 0;
	    }

	    /* take a look at some of the CFI data, for example according to the CFI spec, the
	    	string "QRY" should be at offset 0x10, note the byte offset always gets multiplied
	    	by nFlashWidth, so for x16 devices the offset 0x10 becomes byte offset 0x20 */

	    /* if not x8 or x16 we won't check the data, we only allocated enough for up to x16 */
	    if ( (_FLASH_WIDTH_8 == nFlashWidth) || (_FLASH_WIDTH_16 == nFlashWidth) )
	    {
	    	/* check QRY string, note x16 devices will have a NULL after each character, check the
	    		CFI spec for details on other architectures */
	    	pQRY = &pCFIData[0x10 * nFlashWidth];

	    	/* check the primary (P) offset, this is used to offset into the extended area */
	    	usPrimary = pCFIData[0x15 * nFlashWidth];

	    	/* versions are some of the things stored in the extended area */
	    	usMajVerASCII = pCFIData[(usPrimary+0x3) * nFlashWidth];
	    	usMinVerASCII = pCFIData[(usPrimary+0x4) * nFlashWidth];
	    }
	}

	return 1;
}

⌨️ 快捷键说明

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