📄 flash.c
字号:
//*----------------------------------------------------------------------------
//* File Name : flash.c
//* Object : flash application written in C for SST 39VF160
//* Creation : dxb 3/8/2004
//*
//*----------------------------------------------------------------------------
#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"
#include "sys.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define DEV_SIZE 2048*1024 /* 2M byte */
#define SECTOR_SIZE 2048 /* Must be 2048 words for 39VF160 */
#define SECTOR_NUM 1024
#define BLOCK_SIZE 32768 /* Must be 32K words for 39VF160 */
#define SST_ID 0xBF /* SST Manufacturer's ID code */
#define SST_39LFVF160A 0x2782 /* SST 39LF/VF160A device code */
#define SST_39LFVF800A 0x2781 /* SST 39LF/VF800A device code */
#define SST_39LFVF400A 0x2780 /* SST 39LF/VF400A device code */
#define SST_39VF1601 0x234B /* SST 39VF1601 device code */
unsigned short * BASE_ADDRESS;
unsigned short * END_ADDRESS;
unsigned int wrong_code_number;
unsigned short flash_data;
unsigned short sdram_data;
extern unsigned int SHIFT_SECTOR_ADDR;
#define FLASH_SEQ_ADD1 (0x5555)
#define FLASH_SEQ_ADD2 (0x2AAA)
#define FLASH_CODE1 ((unsigned short)(0x00AA))
#define FLASH_CODE2 ((unsigned short)(0x0055))
#define ID_IN_CODE ((unsigned short)(0x0090))
#define ID_OUT_CODE ((unsigned short)(0x00F0))
#define WRITE_CODE ((unsigned short)(0x00A0))
#define FLASH_READY ((unsigned short)(0x0080))
#define ERASE_CHIP_CODE ((unsigned short)(0x0010))
#define ERASE_SECTOR_CODE ((unsigned short)(0x0030))
#define ERASE_BLOCK_CODE ((unsigned short)(0x0050))
#define ERASE_SUSPEND ((unsigned short)(0x00B0))
#define ERASE_RESUME ((unsigned short)(0x0030))
unsigned int Check_Chip()//检查Flash
{
unsigned int SST_id1;
unsigned int SST_id2;
int ReturnStatus;
volatile unsigned short *baseAddress;
baseAddress =(unsigned short *)BASE_ADDRESS;
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = ID_IN_CODE;
Sleep(1);
SST_id1 = (short) *baseAddress;
SST_id2 = *(baseAddress + 1);
if ((SST_id1 == SST_ID) && (SST_id2 == SST_39LFVF160A))
ReturnStatus = 1;
else if ((SST_id1 == SST_ID) && (SST_id2 == SST_39LFVF800A))
ReturnStatus = 2;
else if ((SST_id1 == SST_ID) && (SST_id2 == SST_39LFVF400A))
ReturnStatus = 3;
else if ((SST_id1 == SST_ID) && (SST_id2 == SST_39VF1601))
ReturnStatus = 4;
else
ReturnStatus = FALSE;
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = ID_OUT_CODE;
Sleep(1);
return(ReturnStatus);
}
unsigned int Erase_Entire_Chip()//整片擦除
{
volatile unsigned short *baseAddress;
volatile unsigned short *checkAddress;
volatile unsigned short *endAddress;
baseAddress = (unsigned short *)BASE_ADDRESS;
checkAddress =(unsigned short *)BASE_ADDRESS;
endAddress = (unsigned short *)END_ADDRESS;
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_READY;//80
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = ERASE_CHIP_CODE;//10
Sleep(5000);
//check
for(;checkAddress < endAddress; checkAddress++)
{
if(*checkAddress != 0xffff)
return(FALSE);
}
return(TRUE);
}
unsigned int Bsy2Rdy(volatile unsigned short * addr)
{
unsigned short Loop = TRUE;
unsigned short PreData;
unsigned short CurrData;
unsigned long TimeOut = 0;
unsigned long tmpaddr[2];
PreData = *addr;
PreData = PreData & 0x4040;
while ((TimeOut < 0x07FFFFFF) && (Loop))
{
CurrData = *addr;
CurrData = CurrData & 0x4040;
if (PreData == CurrData)
Loop = FALSE;
PreData = CurrData;
TimeOut++;
if(TimeOut == 0x07FFFFFF)
{
tmpaddr[1] = 0;
US1_Printf(tmpaddr);
}
}
return (FALSE);
}
unsigned int Burn_whole_Chip(unsigned int length)//烧写Flash
{
unsigned int i;
unsigned short *DataBuf;
volatile unsigned short *baseAddress;
unsigned short * pgm_addr;
unsigned short data;
baseAddress = (unsigned short *)BASE_ADDRESS;
pgm_addr = (unsigned short *)BASE_ADDRESS;
DataBuf = (unsigned short *)RxBuf_Bin;
for(i=0;i<=length;i++)
{
data = DataBuf[i];
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = WRITE_CODE;
*(pgm_addr) = data;
Bsy2Rdy(pgm_addr);
pgm_addr ++;
// Sleep_100us(1);
}
return(0);
}
unsigned int Verify_whole_chip(unsigned int length)
{
volatile unsigned short *flash_code_address;
volatile unsigned short *sdram_code_address;
flash_code_address = (unsigned short *)BASE_ADDRESS;
sdram_code_address = (unsigned short *)RxBuf_Bin;
for(wrong_code_number=0;wrong_code_number<length;wrong_code_number++)
{
flash_data = flash_code_address[wrong_code_number];
sdram_data = sdram_code_address[wrong_code_number];
if(flash_data!=sdram_data)
return (FALSE);
}
return (TRUE);
}
unsigned int CFI_Query()//CFI 操作
{
unsigned int *Temp1;
//读操作控制字
Temp1 = ( unsigned int *)0x00005555; /* set up address to be 1000:5555h */
*Temp1= 0xAAAA; /* write data 0xAAAA to the address */
Temp1 = ( unsigned int *)0x00002AAA; /* set up address to be 1000:2AAAh */
*Temp1= 0x5555; /* write data 0x5555 to the address */
Temp1 = ( unsigned int *)0x00005555; /* set up address to be 1000:5555h */
*Temp1= 0x9898; /* write data 0x9898 to the address */
Sleep(1);
/* --------------------------------- */
/* Perform all CFI operations here */
/* NOTE: no sample code provided */
/* --------------------------------- */
/* Issue the CFI Exit code thus returning the 39VF160 */
/* to the read operating mode */
Temp1 = ( unsigned int *)0x00005555; /* set up address to be 1000:5555h */
*Temp1 = 0xAAAA; /* write data 0xAAAA to the address */
Temp1 = ( unsigned int *)0x00002AAA; /* set up address to be 1000:2AAAh */
*Temp1 = 0x5555; /* write data 0x5555 to the address */
Temp1 = ( unsigned int *)0x00005555; /* set up address to be 1000:5555h */
*Temp1 = 0xF0F0; /* write data 0xF0F0 to the address */
Sleep(1);
return 0;
}
unsigned int Erase_One_Sector ()//擦除一个扇区,2048 words,4k byte
{
unsigned int *Temp;
volatile unsigned short *baseAddress;
volatile unsigned short *checkAddress;
volatile unsigned short *endAddress;
baseAddress = (unsigned short *)BASE_ADDRESS;
checkAddress =baseAddress + SHIFT_SECTOR_ADDR;
endAddress = baseAddress + SHIFT_SECTOR_ADDR+0x1000;
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;//AA
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;//55
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_READY;//80
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;//AA
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;//55
//*(baseAddress + FLASH_SEQ_ADD1) = ERASE_CHIP_CODE;//10
*(baseAddress + SHIFT_SECTOR_ADDR) =ERASE_SECTOR_CODE;//30
Sleep(30);
//check
for(;checkAddress < endAddress; checkAddress++)
{
if(*checkAddress != 0xffff)
return(FALSE);
}
return(TRUE);
}
unsigned int Burn_One_Sector(unsigned int length)//烧写Flash
{
unsigned int i;
unsigned short *DataBuf;
volatile unsigned short *baseAddress;
volatile unsigned short * pgm_addr;
unsigned short data;
baseAddress = (unsigned short *)BASE_ADDRESS;
pgm_addr = baseAddress + SHIFT_SECTOR_ADDR;
DataBuf = (unsigned short *)RxBuf_Bin;
if(length>0x800)
length=0x800;
for(i=0;i<=length;i++)
{
data = DataBuf[i];
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = WRITE_CODE;
*(pgm_addr) = data;
Bsy2Rdy(pgm_addr);
pgm_addr ++;
// Sleep_100us(1);
}
return(0);
}
unsigned int Verify_One_Sector(unsigned int length)
{
volatile unsigned short *flash_code_address;
volatile unsigned short *sdram_code_address;
flash_code_address = (unsigned short *)BASE_ADDRESS;
flash_code_address=flash_code_address+SHIFT_SECTOR_ADDR;
sdram_code_address = (unsigned short *)RxBuf_Bin;
if(length>0x800)
length=0x800;
for(wrong_code_number=0;wrong_code_number<length;wrong_code_number++)
{
flash_data = flash_code_address[wrong_code_number];
sdram_data = sdram_code_address[wrong_code_number];
if(flash_data!=sdram_data)
return (FALSE);
}
return (TRUE);
}
int Erase_One_Block (unsigned int *Dst)//擦除一块,32K words,64k byte
{
unsigned int *Temp;
Temp = (unsigned int *)0x00005555; /* set up address to be 0000:5555h */
*Temp = 0xAAAA; /* write data 0xAAAA to the address */
Temp = (unsigned int *)0x00002AAA; /* set up address to be 0000:2AAAh */
*Temp = 0x5555; /* write data 0x5555 to the address */
Temp = (unsigned int *)0x00005555; /* set up address to be 0000:5555h */
*Temp = 0x8080; /* write data 0x8080 to the address */
Temp = (unsigned int *)0x00005555; /* set up address to be 0000:5555h */
*Temp = 0xAAAA; /* write data 0xAAAA to the address */
Temp = (unsigned int *)0x00002AAA; /* set up address to be 0000:2AAAh */
*Temp = 0x5555; /* write data 0x5555 to the address */
Temp = Dst; /* set up starting address to be erased */
*Temp = 0x5050; /* write data 0x5050 to the address */
Sleep(30); /* Delay time = Tbe */
return 0;
}
void Program_One_Word (unsigned int SrcWord, unsigned int *Dst)//写一个字
{
/* unsigned int *Temp;
unsigned int *SourceBuf;
unsigned int *DestBuf;
int Index;
DestBuf = Dst;
Temp = (unsigned int *)0x00005555; set up address to be C000:555h
*Temp = 0xAAAA; // write data 0xAAAA to the address
Temp = (unsigned int *)0x00002AAA; // set up address to be C000:2AAAh
*Temp = 0x5555; // write data 0x5555 to the address
Temp = (unsigned int *)0x00005555; // set up address to be C000:5555h
*Temp = 0xA0A0; // write data 0xA0A0 to the address
*DestBuf = SrcWord; // transfer the byte to destination
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -