📄 sst39vf160.c
字号:
#include "..\inc\44b.h"
#include "sst39vf160.h"
#define __WR(addr,data) *((unsigned short *)(addr<<1))=(unsigned short)data
#define __RD(addr) *((unsigned short *)(addr<<1))
#define __RESET() __WR(0x0,0xf0f0)
//===在sst39vf160_s.s 中定义
extern void ___SST_EraseSector(unsigned int SectorNo); //Erase
extern void ___SST_Prog(unsigned int realAddr,unsigned short data); //编程
//===
void __Sst_EraseSector(unsigned int SectorNo);
void __Sst_Prog(unsigned int realAddr,unsigned short data);
//============================================================
//擦除一个扇区,SectorNo是扇区号地址
//
//=============================================================
void __Sst_EraseSector(unsigned int SectorNo)
{
unsigned short i;
unsigned int sector = SectorNo << 12;
___SST_EraseSector(SectorNo);
//判断是否擦除完成
while(1)
{
i = *((volatile unsigned short *)sector)&0x40;
if(i!=*((volatile unsigned short *)sector)&0x40) //D6 == D6
continue;
if(*((volatile unsigned short *)sector)&0x80)
break; //D7 == 1
}
//for( i = 0 ; i < 700000 ; i++ ); //delay 3ms
}
//===================================================
//编程一个16位的数据到Flash
//
//========================================================
void __Sst_Prog(unsigned int realAddr,unsigned short data)
{
unsigned short i;
___SST_Prog( realAddr, data); //调用汇编程序编程
//判断是否编程完成
while(1)
{
i = *(volatile unsigned short *)realAddr&0x40;
if(i!=*(volatile unsigned short *)realAddr&0x40) //D6 == D6
continue;
if((*(volatile unsigned short *)realAddr&0x80)==(data&0x80))
break; //D7 == D7
}
//for( i = 0 ; i < 200 ; i++ ); //delay 7us
}
//=================
unsigned int __SST_SAVErNCACHBE1;
//禁止0000000到02000000地址的数据进入CACHE
void Sst_Start()
{
__SST_SAVErNCACHBE1 = rNCACHBE1;
rNCACHBE1 = ( 0x00000000 >> 12 ) | ( (0x02000000 >> 12 ) << 16 );
}
//还原rNCACHBE1的数据
void Sst_End()
{
rNCACHBE1 = __SST_SAVErNCACHBE1;
}
//===================================================
//连续编程
//
//========================================================
unsigned int Sst_Program(unsigned int Addr , unsigned short *pBuf , unsigned int Length)
{
unsigned int howWrite = 0;
unsigned short *pPAddr,*pData;
Addr = Addr & 0x1FFFFE;
/*编程*/
pPAddr = (unsigned short*)Addr;
pData = pBuf;
while( (howWrite < Length) && ( (unsigned int)pPAddr < 0x00200000) )
{
__Sst_Prog( (unsigned int)pPAddr, *pData ); ///编程一个字节
pPAddr++;
pData++;
howWrite++;
}
/*校验*/
pPAddr = (unsigned short*)Addr;
pData = pBuf;
howWrite = 0;
while( (howWrite < Length) && ( (unsigned int)pPAddr < 0x00200000) && ( (*pPAddr) == (*pData) ) )
{
pPAddr++;
pData++;
howWrite++;
}
if( (howWrite < Length) && ( (unsigned int)pPAddr < 0x00200000) ) return 0; ///校验不正确时返回0
return 1;
}
//======================================================================
//擦除扇区,每个扇区为2048个字节,但因29F160是16位的,即每个扇区为1024个
//
//如下载英文字库到00F0000~00F0FFF,则SSectors=00F0, ESectors=00F0,
//=============================================-=======================
unsigned short __SST_DATABUF[2048];
unsigned int Sst_Erase(unsigned int SAddr,unsigned int EAddr)
{
unsigned int i,j,S,E;
unsigned short *pBuf,*pSsec;
unsigned int SSectors,ESectors; //开始、结束扇区
SAddr = SAddr & 0x1FFFFE;
EAddr = EAddr & 0x1FFFFE;
//开始结束地址出错
if( EAddr < SAddr ) return 0;
/*计算起始、结束扇区*/
SSectors = SAddr >> 12;
ESectors = EAddr >> 12;
if( SSectors == ESectors ) //只有1扇区
{
//擦除开始扇区
pBuf = (unsigned short*)(SSectors << 12);
pSsec = __SST_DATABUF; //数组
for( i = 0 ; i < 2048 ; i++ )
{
*pSsec++ = *pBuf++; //读出将要擦除的全部数据到__SST_DATABUF数组
}
S = (SAddr >> 1) & 0x07FF; //字节地址转为半字地址
E = (EAddr >> 1) & 0x07FF;
for( i = S ; i <= E ; i++ )
{
__SST_DATABUF[i] = 0xFFFF; //写入数据0FFFF到__SST_DATABUF数组里
}
__Sst_EraseSector(SSectors); //擦除扇区SSectors
return Sst_Program( SSectors << 12 , __SST_DATABUF , 2048); //将__SST_DATABUF数组编程到FLASH
return 1;
}else //多扇区
{
//擦除开始扇区
pBuf = (unsigned short*)(SSectors << 12);
pSsec = __SST_DATABUF;
for( i = 0 ; i < 2048 ; i++ )
{
*pSsec++ = *pBuf++;
}
S = (SAddr >> 1) & 0x07FF;
E = 0x07FF;
for( i = S ; i <= E ; i++ )
{
__SST_DATABUF[i] = 0xFFFF;
}
__Sst_EraseSector(SSectors);
Sst_Program( SSectors << 12 , __SST_DATABUF , 2048);
//擦除结束扇区
pBuf = (unsigned short*)(ESectors << 12);
pSsec = __SST_DATABUF;
for( i = 0 ; i < 2048 ; i++ )
{
*pSsec++ = *pBuf++;
}
S = 0;
E = (EAddr >> 1) & 0x07FF;
for( i = S ; i <= E ; i++ )
{
__SST_DATABUF[i] = 0xFFFF;
}
__Sst_EraseSector(ESectors);
//擦除中间扇区(一个或多个)
for( i = SSectors + 1 ; i < ESectors ; i++ )
{
__Sst_EraseSector(i);
//for( j - 0 ; j < 200000 ; j++ );
}
//校验是否擦除成功
pBuf = (unsigned short*)SAddr;
//for( j - 0 ; j < 600000; j++ );
while( (unsigned int)pBuf <= EAddr )
{
if( *pBuf != 0xFFFF ) return 0;
pBuf++;
}
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -