/**************flash_sst39vf800a******************/
/*
sst39vf800a: 512k x 16bit
1. Manufacturer’s ID 0000H 00BFH
2. Device ID 0001H 2781H
3. Software Command Sequence
Addr1 Data2 Addr1 Data2 Addr1 Data2 Addr1 Data2 Addr1 Data2 Addr1 Data2
Word-Program 5555H AAH 2AAAH 55H 5555H A0H WA3 Data
Sector-Erase 5555H AAH 2AAAH 55H 5555H 80H 5555H AAH 2AAAH 55H SAX 30H
Block-Erase 5555H AAH 2AAAH 55H 5555H 80H 5555H AAH 2AAAH 55H BAX 50H
Chip-Erase 5555H AAH 2AAAH 55H 5555H 80H 5555H AAH 2AAAH 55H 5555H 10H
Software ID Entry 5555H AAH 2AAAH 55H 5555H 90H
CFI Query Entry5 5555H AAH 2AAAH 55H 5555H 98H
Software ID Exit7/XXH F0H
CFI Exit
Software ID Exit7/5555H AAH 2AAAH 55H 5555H F0H
CFI Exit
Address Data Data
10H 0051H Query Unique ASCII string “QRY”
11H 0052H
12H 0059H
13H 0001H Primary OEM command set
14H 0007H
15H 0000H Address for Primary Extended Table
16H 0000H
17H 0000H Alternate OEM command set (00H = none exists)
18H 0000H
19H 0000H Address for Alternate OEM extended Table (00H = none exits)
1AH 0000H
1BH 0027H1 VDD Min (Program/Erase)0030H1 DQ7-DQ4: Volts, DQ3-DQ0: 100 millivolts
1CH 0036H VDD Max (Program/Erase)DQ7-DQ4: Volts, DQ3-DQ0: 100 millivolts
1DH 0000H VPP min (00H = no VPP pin)
1EH 0000H VPP max (00H = no VPP pin)
1FH 0004H Typical time out for Word-Program 2N μs (24 = 16 μs)
20H 0000H Typical time out for min size buffer program 2N μs (00H = not supported)
21H 0004H Typical time out for individual Sector/Block-Erase 2N ms (24 = 16 ms)
22H 0006H Typical time out for Chip-Erase 2N ms (26 = 64 ms)
23H 0001H Maximum time out for Word-Program 2N times typical (21 x 24 = 32 μs)
24H 0000H Maximum time out for buffer program 2N times typical
25H 0001H Maximum time out for individual Sector/Block-Erase 2N times typical (21 x 24 = 32 ms)
26H 0001H Maximum time out for Chip-Erase 2N times typical (21 x 26 = 128 ms)
27H 0014H Device size = 2N Bytes (14H = 20; 220 = 1 MByte)
28H 0001H Flash Device Interface description; 0001H = x16-only asynchronous interface
29H 0000H
2AH 0000H Maximum number of bytes in multi-byte write = 2N (00H = not supported)
2BH 0000H
2CH 0002H Number of Erase Sector/Block sizes supported by device
2DH 00FFH Sector Information (y + 1 = Number of sectors; z x 256B = sector size)
2EH 0000H y = 255 + 1 = 256 sectors (00FFH = 255)
2FH 0010H
30H 0000H z = 16 x 256 Bytes = 4 KByte/sector (0010H = 16)
31H 000FH Block Information (y + 1 = Number of blocks; z x 256B = block size)
32H 0000H y = 15 + 1 = 16 blocks (000FH = 15)
33H 0000H
34H 0001H z = 256 x 256 Bytes = 64 KByte/block (0100H = 256)
4.Program/Erase Cycle Timing Parameters
Word-Program Time 20 μs
Software ID Access and Exit Time 150 ns
Sector-Erase 25 ms
Block-Erase 25 ms
Chip-Erase 100 ms
**************************************************/
// error enum
#include <stdlib.h>
#include "Errors.h"
// #defines
#define TRUE 0x1
#define FALSE 0x0
#define BUFFER_SIZE 0x600
#define NUM_SECTORS 256 // number of sectors in the flash device
// structure for flash sector information
typedef struct _SECTORLOCATION{
long lStartOff;
long lEndOff;
}SECTORLOCATION;
// 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;
// #defines for the assembler
asm ("#define FLASH_START_L 0x0000");
asm ("#define FLASH_START_H 0x2000");
// function prototypes
//库函数
ERROR_CODE ReadFlash( unsigned long ulOffset, int *pnValue );
ERROR_CODE WriteFlash( unsigned long ulOffset, int nValue );
ERROR_CODE PollToggleBit(unsigned long ulOffset);
ERROR_CODE UnlockFlash(unsigned long ulOffset);
//功能函数
ERROR_CODE SetupForFlash(void);
ERROR_CODE GetCodes(void);
ERROR_CODE ResetFlash(void);
ERROR_CODE EraseFlash(void);
ERROR_CODE EraseBlock( int nBlock );
ERROR_CODE WriteData( unsigned long ulStart, long lCount, long lStride, int *pnData );
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 GetSectorNumber( unsigned long ulOffset, int *pnSector );
ERROR_CODE GetSectorStartEnd( long *lStartOff, long *lEndOff, int nSector );
// global data for use with the VisualDSP++ plug-in
char *AFP_Title = "TAP WATCH";
char *AFP_Description = "SST 39VF800A";
enProgCmds AFP_Command = NO_COMMAND;
int AFP_ManCode = -1; // 0xBF = SST
int AFP_DevCode = -1; // 0x2781 = 39VF800A
unsigned long AFP_Offset = 0x0; // Flash Start
int *AFP_Buffer; // 从GUI中取数
long AFP_Size = BUFFER_SIZE; // 供GUI使用
long AFP_Count = -1; // 无效, 从GUI中取数
long AFP_Stride = -1; // 无效, 从GUI中取数
int AFP_NumSectors = NUM_SECTORS;
//long AFP_SectorSize1 = 0x10000;
//int AFP_SectorSize2 = 0x2000;
long AFP_SectorSize = 0x1000; //4K BYTES
int AFP_Sector = -1; // 无效, 从GUI中取数
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 = 0x10; // width of the flash device
int *AFP_SectorInfo;
SECTORLOCATION SectorInfo[NUM_SECTORS];
// flag telling us that the flash had to be reset
char reset = 0x0;
// exit flag
bool bExit = FALSE;
// *********************
// Map of flash sectors
// *********************
// FLASH
// Type START ADDR END ADDR SECTOR NUM
// ------- ---------- -------- ----------
// Main Flash 0x20000000 0x200FFFFF 00 - 255
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
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
AFP_Error = BUFFER_IS_NULL;
}
//initiate sector information structures
for(i=0;i<AFP_NumSectors; i++)
{
GetSectorStartEnd(&SectorInfo[i].lStartOff, &SectorInfo[i].lEndOff, i);
}
AFP_SectorInfo = (int*)&SectorInfo[0];
// setup the flash so the DSP can access it
SetupForFlash();
//setup code so that flash programmer can just read memory instead of call GetCodes().
GetCodes();
// 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:");
if ( FALSE )
asm("jump AFP_BreakReady;");
// switch on the command
switch ( AFP_Command )
{
// get manufacturer and device codes
case GET_CODES:
AFP_Error = GetCodes();
break;
// reset
case RESET:
AFP_Error = ResetFlash();
break;
// write
case WRITE: