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 + -
显示快捷键?