📄 main.c
字号:
/////////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2004 - Analog Devices, Inc. All rights reserved.
//
// FILE: M a i n ( )
//
// CHANGES: 1.00.0 - initial release
// 1.00.1 - modified to support the M29W320DB flash library
// 1.00.2 - In Write Data we were using an uninitialized
// pointer called pnValue
//
// PURPOSE: VisualDSP++ "Flash Programmer" flash driver for use with the
// ADSP-BF538 EZ-KIT Lite containing the STMicroelectronics
// M29W320DB 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\util.h> // library struct includes
#include <drivers\flash\adi_m29w320.h> // flash-M29W320 includes
#include <drivers\flash\Errors.h> // error type includes
#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 ; // EzKit info: ADSP-BF538 EZ-KIT Lite
char *AFP_Description; // Flash Description: STMicro. M29W320DB
char *AFP_DeviceCompany; // Flash Company
char *AFP_DrvVersion = "1.00.2"; // 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 = M29W320DB
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 = NUM_SECTORS; // 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 = ADIM29W320EntryPoint.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 == NO_ERR )
{
AFP_Error = GetFlashInfo();
}
// get the number of sectors for this device
if( AFP_Error == NO_ERR )
{
AFP_Error = GetNumSectors();
}
if( AFP_Error == NO_ERR )
{
// 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( AFP_Error == NO_ERR )
{
AFP_Error = SetupForFlash();
}
// allocate AFP_Buffer
if( AFP_Error == NO_ERR )
{
AFP_Error = AllocateAFPBuffer();
}
// get sector map
if( AFP_Error == NO_ERR )
{
AFP_Error = GetSectorMap(pSectorInfo);
}
// point AFP_SectorInfo to our sector info structure
if( AFP_Error == NO_ERR )
{
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 = ADIM29W320EntryPoint.adi_pdd_Close(NULL);
return TRUE;
}
//----------- 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()
{
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) ADIM29W320EntryPoint.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) ADIM29W320EntryPoint.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) ADIM29W320EntryPoint.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) ADIM29W320EntryPoint.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) ADIM29W320EntryPoint.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) ADIM29W320EntryPoint.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()
{
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()
{
// 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) ADIM29W320EntryPoint.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()
{
ERROR_CODE ErrorCode = NO_ERR; //return error code
*pEBIU_AMGCTL = 0xFF;
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) ADIM29W320EntryPoint.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()
{
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;
ErrorCode = (ERROR_CODE) ADIM29W320EntryPoint.adi_pdd_Control(NULL, CNTRL_GET_CODES, &CmdStruct );
if(!ErrorCode)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -