📄 main.c
字号:
/*******************************************************************************/
/* */
/* (C) Copyright 2004 - Analog Devices, Inc. All rights reserved. */
/* */
/* FILE: M a i n ( ) */
/* */
/* CHANGES: 1.00.0 - initial release */
/* */
/* PURPOSE: VisualDSP++ "Flash Programmer" flash driver for use with the */
/* ADSP-BF538F processor containing the AMD S29AL004D/8D */
/* flash device. */
/* */
/*******************************************************************************/
#include <services/services.h> // system services includes
#include <drivers/adi_dev.h> // device manager includes
#include <stdlib.h> // malloc includes
#include <drivers\flash\adi_S29AL004D_8D.h> // flash-S29AL004D/8D includes
#include <drivers\flash\util.h> // library struct includes
#include <drivers\flash\Errors.h> // error type includes
#include <cdefBF538.h>
#define FLASH_START_ADDR 0x20000000
#define BUFFER_SIZE 0x600
//Flash Programmer commands
typedef enum
{
NO_COMMAND, // 0
GET_CODES, // 1
RESET, // 2
WRITE, // 3
FILL, // 4
ERASE_ALL, // 5
ERASE_SECT, // 6
READ, // 7
GET_SECTNUM, // 8
GET_SECSTARTEND,// 9
}enProgCmds;
//----- g l o b a l s -----//
char *AFP_Title = "ADSP-BF538F EZ-KIT Lite"; // EzKit info: ADSP-BF538 eval board
char *AFP_Description; // Flash Description: AMD. am29lv008bDB
char *AFP_DeviceCompany; // Flash Company
char *AFP_DrvVersion = "1.00.0"; // Driver Version
char *AFP_BuildDate = __DATE__; // Driver Build Date
enProgCmds AFP_Command = NO_COMMAND; // command sent down from the GUI
int AFP_ManCode = -1; // 0x20 = STMicroelectronics
int AFP_DevCode = -1; // 0x22CB = am29lv008bDB
unsigned long AFP_Offset = 0x0; // offset into flash
int *AFP_Buffer; // buffer used to read and write flash
long AFP_Size = BUFFER_SIZE; // buffer size
long AFP_Count = -1; // count of locations to be read or written
long AFP_Stride = -1; // stride used when reading or writing
int AFP_NumSectors = -1; // number of sectors in the flash device
int AFP_Sector = -1; // sector number
int AFP_Error = 0; // contains last error encountered
bool AFP_Verify = FALSE; // verify writes or not
unsigned long AFP_StartOff = 0x0; // sector start offset
unsigned long AFP_EndOff = 0x0; // sector end offset
int AFP_FlashWidth = 0x10; // width of the flash device
int *AFP_SectorInfo;
bool bExit = FALSE; //exit flag
//----- c o n s t a n t d e f i n i t i o n s -----//
// structure for flash sector information
typedef struct _SECTORLOCATION
{
unsigned long ulStartOff;
unsigned long ulEndOff;
}SECTORLOCATION;
//----- f u n c t i o n p r o t o t y p e s -----//
ERROR_CODE GetNumSectors(void);
ERROR_CODE AllocateAFPBuffer(void);
ERROR_CODE GetSectorMap(SECTORLOCATION *pSectInfo);
ERROR_CODE GetFlashInfo(void);
ERROR_CODE ProcessCommand(void);
ERROR_CODE SetupForFlash(void);
ERROR_CODE FillData( unsigned long ulStart, long lCount, long lStride, int *pnData );
ERROR_CODE ReadData( unsigned long ulStart, long lCount, long lStride, int *pnData );
ERROR_CODE WriteData( unsigned long ulStart, long lCount, long lStride, int *pnData );
void FreeAFPBuffer(void);
//------------- m a i n ( ) ----------------//
int main(void)
{
SECTORLOCATION *pSectorInfo;
// open the device
AFP_Error = ADIS29AL004D_8DEntryPoint.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
// get flash manufacturer & device codes, title & desc
if (( AFP_Error = GetFlashInfo()) != NO_ERR)
return FALSE;
// get the number of sectors for this device
if( GetNumSectors() != NO_ERR )
return FALSE;
// malloc enough space to hold our start and end offsets
pSectorInfo = (SECTORLOCATION *)malloc(AFP_NumSectors);
// setup the device so the DSP can access it
if (SetupForFlash() != NO_ERR)
return FALSE;
// allocate AFP_Buffer
if (( AFP_Error = AllocateAFPBuffer()) != NO_ERR)
return FALSE;
// get sector map
if (( AFP_Error = GetSectorMap(pSectorInfo))!= NO_ERR)
return FALSE;
// point AFP_SectorInfo to our sector info structure
AFP_SectorInfo = (int*)pSectorInfo;
// command processing loop
while ( !bExit )
{
// the plug-in will set a breakpoint at "AFP_BreakReady" so it knows
// when we are ready for a new command because the DSP will halt
//
// the jump is used so that the label will be part of the debug
// information in the driver image otherwise it may be left out
// since the label is not referenced anywhere
asm("AFP_BreakReady:");
asm("nop;");
if ( FALSE )
asm("jump AFP_BreakReady;");
// Make a call to the ProcessCommand
AFP_Error = ProcessCommand();
}
//Clear the AFP_Buffer
FreeAFPBuffer();
//Close the Device
AFP_Error = ADIS29AL004D_8DEntryPoint.adi_pdd_Close(NULL);
free(pSectorInfo);
return 1;
}
//----------- P r o c e s s C o m m a n d ( ) ----------//
//
// PURPOSE
// Process each command sent by the GUI based on the value in
// the AFP_Command.
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs during Opcode scan
// NO_ERR - otherwise
//
// CHANGES
// 9-28-2005 Created
ERROR_CODE ProcessCommand(void)
{
ERROR_CODE ErrorCode = NO_ERR; //return error code
COMMAND_STRUCT CmdStruct;
// switch on the command and fill command structure.
switch ( AFP_Command )
{
// erase all
case ERASE_ALL:
CmdStruct.SEraseAll.ulFlashStartAddr = FLASH_START_ADDR; //FlashStartAddress
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_ERASE_ALL, &CmdStruct );
break;
// erase sector
case ERASE_SECT:
CmdStruct.SEraseSect.nSectorNum = AFP_Sector; // Sector Number to erase
CmdStruct.SEraseSect.ulFlashStartAddr = FLASH_START_ADDR; // FlashStartAddress
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_ERASE_SECT, &CmdStruct);
break;
// fill
case FILL:
ErrorCode = FillData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
break;
// get manufacturer and device codes
case GET_CODES:
CmdStruct.SGetCodes.pManCode = (unsigned long *)&AFP_ManCode; // Manufacturer Code
CmdStruct.SGetCodes.pDevCode = (unsigned long *)&AFP_DevCode; // Device Code
CmdStruct.SGetCodes.ulFlashStartAddr = FLASH_START_ADDR;
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_CODES, &CmdStruct);
break;
// get sector number based on address
case GET_SECTNUM:
CmdStruct.SGetSectNum.ulOffset = AFP_Offset; // offset from the base address
CmdStruct.SGetSectNum.pSectorNum = (unsigned long *)&AFP_Sector; //Sector Number
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_SECTNUM, &CmdStruct);
break;
// get sector number start and end offset
case GET_SECSTARTEND:
CmdStruct.SSectStartEnd.nSectorNum = AFP_Sector; // Sector Number
CmdStruct.SSectStartEnd.pStartOffset = &AFP_StartOff;// sector start address
CmdStruct.SSectStartEnd.pEndOffset = &AFP_EndOff; // sector end address
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_SECSTARTEND, &CmdStruct );
break;
// read
case READ:
ErrorCode = ReadData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
break;
// reset
case RESET:
CmdStruct.SGetCodes.ulFlashStartAddr = FLASH_START_ADDR; //Flash start address
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_RESET, &CmdStruct);
break;
// write
case WRITE:
ErrorCode = WriteData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
break;
// no command or unknown command do nothing
case NO_COMMAND:
default:
// set our error
ErrorCode = UNKNOWN_COMMAND;
break;
}
// clear the command
AFP_Command = NO_COMMAND;
return(ErrorCode);
}
//----------- A l l o c a t e A F P B u f f e r ( ) ----------//
//
// PURPOSE
// Allocate memory for the AFP_Buffer
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
//
// CHANGES
// 9-28-2005 Created
ERROR_CODE AllocateAFPBuffer(void)
{
ERROR_CODE ErrorCode = NO_ERR; //return error code
// by making AFP_Buffer as big as possible the plug-in can send and
// receive more data at a time making the data transfer quicker
//
// by allocating it on the heap the compiler does not create an
// initialized array therefore making the driver image smaller
// and faster to load
//
// The linker description file (LDF) could be modified so that
// the heap is larger, therefore allowing the BUFFER_SIZE to increase.
AFP_Buffer = (int *)malloc(BUFFER_SIZE);
// AFP_Buffer will be NULL if we could not allocate storage for the
// buffer
if ( AFP_Buffer == NULL )
{
// tell GUI that our buffer was not initialized
ErrorCode = BUFFER_IS_NULL;
}
return(ErrorCode);
}
//----------- F r e e A F P B u f f e r ( ) ----------//
//
// PURPOSE
// Free the AFP_Buffer
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
//
// CHANGES
// 9-28-2005 Created
void FreeAFPBuffer(void)
{
// free the buffer if we were able to allocate one
if ( AFP_Buffer )
free( AFP_Buffer );
}
//----------- 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) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GETNUM_SECTORS, (COMMAND_STRUCT *)&SGetNumSectors );
return(ErrorCode);
}
//----------- 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 SetupForFlash(void)
{
ERROR_CODE ErrorCode = NO_ERR; //return error code
*pEBIU_AMGCTL = 0x0F;
ErrorCode = GetNumSectors();
return NO_ERR;
}
//----------- 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 GetSectorMap(SECTORLOCATION *pSectInfo)
{
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 = &pSectInfo[i].ulStartOff;
SSectStartEnd.pEndOffset = &pSectInfo[i].ulEndOff;
ErrorCode = (ERROR_CODE) ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_SECSTARTEND, (COMMAND_STRUCT *)&SSectStartEnd );
}
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 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;
AFP_Error = ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_CODES, &CmdStruct );
AFP_Error = ADIS29AL004D_8DEntryPoint.adi_pdd_Control(NULL, CNTRL_GET_DESC, &CmdStruct );
AFP_Description = CmdStruct.SGetDesc.pDesc;
AFP_DeviceCompany = CmdStruct.SGetDesc.pFlashCompany;
return(ErrorCode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -