📄 main.c
字号:
///////////////////////////////////////////////////////////////////////////
//
// VisualDSP++ 3.5 "Flash Programmer" flash driver for use to
// programm SPI flash/EEPROM devices.
//
// (C) Copyright 2006 - Analog Devices, Inc. All rights reserved.
//
// Basic understanding of the VisualDSP++ 3.5 flash programmer tool, also
// called "plug-in", is required.
//
// Note: Due to the fact that the plug-in accepts to open intel hex files only
// SPI programming works just for VisualDSP++ version 3.5 and higher!
//
// Ensure that the option intel hex is chosen at the register LOAD
// under Project Options!
//
// In general, when the flash programming tool "Tools->Flash Programmer"
// has been opened a driver file must be loaded. Loading a driver such as this
// one causes VisualDSP++ to upload the driver dxe file to the processor,
// to set a breakpoint at the label "AFP_BreakReady" and to start the processor.
// When the processor halts at the breakpoint the control went back to the
// flash plug-in. In the box "Load File" a loader file "*.ldr" of a project
// must be selected to program a SPI device.
//
// Note: As a standard flash needs to be erased before programming please
// make use of the erase options in surrounding boxes.
//
// Pressing the button "Load File" will cause the plug-in to access the loader
// file and to fill the buffer "AFP_Buffer" with the first portion of data.
// Also, the number of words counted in bytes as well as the SPI start address
// will be stored in certain variables.
//
// The contents of AFP_Buffer will be written to the SPI and sequentially the
// AFP_Buffer will be filled with the next portion of the loader file. After
// the whole loader file has been transferred to the SPI the processor halts
// at the breakpoint as discussed above.
//
//
//////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------//
// Include/Header files //
//--------------------------------------------------------------------------//
#include <sys\platform.h>
#include <sys\exception.h>
#include "Errors.h"
#include "SPI_Device_Settings.h"
#include <cdefBF537.h>
#include <stdio.h>
#include <ccblkfn.h>
//--------------------------------------------------------------------------//
// Defines //
//--------------------------------------------------------------------------//
#define asynchronous_SPORT
// Peripheral Interrupt IDs for various interrupts at SIC_IMASK
#define SPORT1_RX_PID 7
#define SPORT1_TX_PID 8
#define SPORT1_ERR_PID 2
#define DMA_ERR_PID 1
#define SPI_ADRS_ARM_INTERRUPTS (0x00<<8)
#define SPI_ADRS_ARM_INT_EN (0x04<<8)
#define SPI_ADRS_HOST_INTERRUPTS (0x08<<8)
#define SPI_ADRS_HOST_INT_EN (0x0c<<8)
#define SPI_ADRS_HOST_INT_ACK (0x10<<8)
#define SPI_ADRS_GEN_PURP_1 (0x14<<8)
#define SPI_ADRS_GEN_PURP_2 (0x18<<8)
#define SPI_ADRS_DEV_CTRL_STAT (0x26<<8) // high word
#define SPI_ADRS_DMA_DATA (0x28<<8)
#define SPI_ADRS_DMA_WRITE_CTRL (0x2c<<8)
#define SPI_ADRS_DMA_WRITE_LEN (0x2e<<8)
#define SPI_ADRS_DMA_WRITE_BASE (0x30<<8)
#define SPI_ADRS_DMA_READ_CTRL (0x34<<8)
#define SPI_ADRS_DMA_READ_LEN (0x36<<8)
#define SPI_ADRS_DMA_READ_BASE (0x38<<8)
// Note that these defines are used by the plug-in also. Deleting these defines
// can lead to Plug-in crashs.
#define TRUE 0x1
#define FALSE 0x0
#define BUFFER_SIZE 0x600
#define NUM_SECTORS 4
#define SECTORBASE 0
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef struct DMA_1D_Array_Desc
{
u16 START_ADDR_L;
u16 START_ADDR_H;
u16 CONFIG;
u16 X_CNT;
u16 X_MOD;
} DMA_1D_Array_Desc_t;
typedef struct sm_sport_desc // struct holding descriptors for a sport_read
{
DMA_1D_Array_Desc_t MOSI_regs_addr; // MOSI writes one 16-bit target register address
DMA_1D_Array_Desc_t MOSI_regs_value; // MOSI writing register value (or dummy write in case of sm_sport_read)
DMA_1D_Array_Desc_t MOSI_regs_value2; // MOSI writing register value2 (or dummy write in case of sm_sport_read)
DMA_1D_Array_Desc_t MISO_regs_addr; // MISO desc when MOSI writes 16-bit target reg addr (always dummy read)
DMA_1D_Array_Desc_t MISO_regs_value; // MISO reads register value (or dummy read in case of sm_sport_write)
u16 dummy_read; // place holder for dummy_read data
u16 dummy_write; // place holder for dummy_write data
}sm_sport_desc_t;
// For the purpose of erase single sectors of the SPI flash the right sector
// must be chosen. This structure will be taken by the plug-in to display memory space.
typedef struct _SECTORLOCATION
{
long lStartOff;
long lEndOff;
}SECTORLOCATION;
// Flash Programmer commands
// The VisualDSP++ flash progammer plug-in "Flash Programmer Tool" will send commands
// to this driver. These commands will be taken to execute the corresponding C function
// The commands are used at the switch case below.
// Note: As the commands are used by the plug-in deleting or changing can lead to misfuction.
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
}enProgCmds;
//--------------------------------------------------------------------------//
// Variables //
//--------------------------------------------------------------------------//
sm_sport_desc_t sm_sport_write_8bits_desc, sm_sport_read_multiple_8bits_desc;
sm_sport_desc_t spi_wren_desc, spi_se_desc, sm_sport_read_8bits_desc;
//--------------------------------------------------------------------------//
// Prototypes //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(SPORT1_ISR);
EX_INTERRUPT_HANDLER(HW_ERR_ISR);
EX_INTERRUPT_HANDLER(SYS_ERR_ISR);
EX_INTERRUPT_HANDLER(EXCEP_ISR);
void Init_PLL(void);
ERROR_CODE EraseFlash(void);
ERROR_CODE GetCodes(void);
ERROR_CODE ResetFlash(void);
ERROR_CODE WriteData(unsigned long ulStart, long lCount, long lStride, int *pnData);
ERROR_CODE ReadData(unsigned long ulStart, long lCount, long lStride, int *pnData);
ERROR_CODE EraseBlock(int nBlock);
ERROR_CODE FillData( unsigned long ulStart, long lCount, long lStride, int *pnData );
ERROR_CODE WriteFlash (unsigned long ulStartAddr, long lTransferCount, long lModify, int *iDataSource, long *lWriteCount);
ERROR_CODE Wait_For_Status(char Statusbit);
ERROR_CODE GetSectorNumber( unsigned long ulOffset, int *pnSector );
ERROR_CODE Wait_For_nStatus(void);
void Init_Descriptors(void);
void Init_SPORT(void);
char ReadStatusRegister(void);
void SendSingleCommand(u8 addr);
void SectorErase(u8 opcode, u8 *addr);
int sm_spi_read_8bits(u8 addr, u8 *data, u32 len);
void sm_spi_write_8bits(u8 addr, u8 *data, u8 *dataout, u32 len, u32 modify);
void sm_spi_read_multiple_8bits(u8 opcode, u8 *addr, u8 *datain, u32 len);
// Global data for use with the VisualDSP++ plug-in
// The plug-in will modify some AFP variables to control this driver
char *AFP_Title = "ADSP-BF537 EZ-KIT Lite"; // This title will be displayed in the plug-in
char *AFP_Description = SPI_Description; // The description will also be displayed in the plug-in. See the file "SPI_Device_Settings.h".
enProgCmds AFP_Command = NO_COMMAND; // AFP_Command is dedicated to control program flow. Look at the switch case below.
int AFP_ManCode = 0x0; // Some devices have Manufacturer codes to autodetect the device
int AFP_DevCode = 0x0; // Some devices have device codes to autodetect the device
unsigned long AFP_Offset = 0; // AFP_Offset holds the start address to the SPI device
int i, *AFP_Buffer; // The plug-in copies the content of the *.ldr file to the buffer in small portions
long AFP_Size = BUFFER_SIZE; // The AFP_Buffer size can be modified.
long AFP_Count = -1; // The plug-in copies the number of transfers to be executed to the AFP_Count
long AFP_Stride = -1; // For the plug-in "Fill" function a stride can optionally be inserted
int AFP_NumSectors = 0; // The number of SPI sectors are given for sector erase function
long AFP_SectorSize = 0; // The multiplier factor from sector to sector must be given
int AFP_Sector = -1; // In case of sector erase the right sector must be chosen and hold in here
int AFP_Error = 0; // contains last error encountered
bool AFP_Verify = FALSE; // verify writes or not
long AFP_StartOff = 0x0; // sector start offset
long AFP_EndOff = 0x0; // sector end offset
int AFP_FlashWidth = 0x8; // width of the flash device taken
int *AFP_SectorInfo;
SECTORLOCATION SectorInfo[NUM_SECTORS];
// exit flag
bool bExit = FALSE;
//--------------------------------------------------------------------------//
// Function: main //
// //
// Parameters: None //
// //
// Return: None //
// //
// Description: main routine //
//--------------------------------------------------------------------------//
main()
{
int i = 0;
// 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.
//
// We have modified the linker description file (LDF) so that the heap
// is large enough to store BUFFER_SIZE elements at this point
// The AFP_Buffer gets filled by the programmer plug-in. The data the plug-in fetches
// from the *.ldr file will be stored in the AFP_Buffer byte wise to avoid gaps in the buffer.
// The verify command uses the buffer to store the data read from the SPI flash for comparison.
// The fill command uses the first address of the buffer to hold the value to be filled.
// -In case of loading the code to the SPI flash the plug-in will fill the buffer automatically
// so that this driver just has to fetch the data from the buffer and transfer it to the SPI flash.
// -In case of reading the data from the SPI flash (plug-in command "VERIFY") this driver just has
// to fetch the data from the SPI flash and store it in the buffer.
Init_PLL();
GetCodes(); // Instead of getting manufacturer codes this driver does organize the
AFP_Buffer = (int *)malloc(BUFFER_SIZE);
// memory stucture "sectors" in the function GetCodes().
// 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
AFP_Error = BUFFER_IS_NULL;
}
Init_Descriptors();
Init_SPORT();
AFP_SectorInfo = (int*)&SectorInfo[0]; //Points to the beginnig of the sector table.
// The while loop below is inserted to give the programmer plug-in control over this driver
// The plug-in will set a breakpoint at "AFP_BreakReady" forcing the processor to halt.
// After the plug-in starts the processor again the function which is selected by AFP_Command will be executed.
// After execution the function the processor halts again at the breadpoint at "AFP_BreakReady".
// Now the plug-in can place the next command in AFP_Command and start the processor again.
while ( !bExit )
{
asm("AFP_BreakReady:"); // After loading the driver to the processor it halt at this point.
if ( FALSE )
asm("jump AFP_BreakReady;");
// switch on the command
switch ( AFP_Command )
{
//In this driver GetCodes does create the sector table
case GET_CODES:
AFP_Error = GetCodes();
break;
// The plug-in offers to reset the flash. This function will send a "write disable command to the SPI flash.
// Additionally, it checks the status register for the write enable bit "WEL" to be cleared.
case RESET:
AFP_Error = ResetFlash();
break;
// By taking the parameters the function "WriteData" will program the flash.
// AFP_Offset points to the SPI destination address, AFP_Count holds the number of transfers to execute.
// AFP_Stride holds the address increment and finally AFP_Buffer points to the source buffer.
case WRITE:
AFP_Error = WriteData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
break;
// As the programmer plug-in allows to simply fill the SPI flash with any value the
// "FILL" function includes the code. The AFP_Offset points to the destination while the AFP_Count
// holds the number of locations where the value will be placed. AFP_Stride holds the increment
// while AFP_Buffer points to the memory source.
case FILL:
AFP_Error = FillData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
break;
// Pushing the "Erase" button on the programmer plug-in the driver executes an erase all command.
case ERASE_ALL:
#ifdef SPI_FLASH //just flashs can be erased!
AFP_Error = EraseFlash();
#endif
break;
// Pushing the "Erase Sectors" button on the programmer plug-in makes the driver to take the value from
// AFP_Sector and sends the erase sector command followed by the start address of the dedicated sector.
// The AFP_Sector gets filled by running the function GET_SECTNUM driven by the plug-in
case ERASE_SECT:
#ifdef SPI_FLASH //just flashs can be erased!
AFP_Error = EraseBlock( AFP_Sector );
#endif
break;
// In order to verify the data that has been programmed to the flash the data must been read.
// This function will be entered when pushing the Verify button.
case READ:
AFP_Error = ReadData( AFP_Offset, AFP_Count, AFP_Stride, AFP_Buffer );
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -