📄 at49bv040aflashwritesector.c
字号:
#include "stdio.h"
#include "stdlib.h"
/*
外部提供的函数:
参数:无
返回值:
0:空闲
1:忙
-1:设备没有成功初始化
*/
int getflashAT49BV040AStatus();
/*
外部提供的函数:
参数:
offset:FLASH偏移
data:要写的数据
返回值:
0:成功
-1:设备没有初始化成功
*/
int writeflashAT49BV040A(unsigned long offset,unsigned char data);
/*
外部提供的函数:
参数:
offset:偏移地址
返回值:
读回的值
*/
unsigned char readflashAT49BV040A(unsigned long offset);
/*延时函数*/
static void flashDelay( unsigned long Tns )
{
unsigned long i;
for (i=0; i<Tns; i++)
;
}
/*延时1000 纳秒(即1us)*/
#define FS_FLASH_DELAY_TIME 200
/*延时1ms*/
#define FS_FLASH_TASKDELAY_TIME 200000
/*BOOTBLOCK段*/
#define FS_FLASH_BOOT_BLOCK_START_ADDRESS (0x00000000)
#define FS_FLASH_BOOT_BLOCK_ADDRESS(sn) (FS_FLASH_BOOT_BLOCK_START_ADDRESS + (sn) * FS_FLASH_BOOT_BLOCK_SIZE)
#define FS_FLASH_BOOT_BLOCK_SIZE (16 * 1024)
#define FS_FLASH_BOOT_BLOCK_COUNT 1
#define FS_BOOT_BLOCK_SIZE (FS_FLASH_BOOT_BLOCK_SIZE * FS_FLASH_BOOT_BLOCK_COUNT)
/*PARAMETERBLOCK段*/
#define FS_FLASH_PARAMETER_BLOCK_START_ADDRESS (0x00004000)
#define FS_FLASH_PARAMETER_BLOCK_ADDRESS(sn) (FS_FLASH_PARAMETER_BLOCK_START_ADDRESS + (sn) * FS_FLASH_PARAMETER_BLOCK_SIZE)
#define FS_FLASH_PARAMETER_BLOCK_SIZE (8 * 1024)
#define FS_FLASH_PARAMETER_BLOCK_COUNT 2
#define FS_PARAMETER_BLOCK_SIZE (FS_FLASH_SECTOR_SIZE * FS_FLASH_SECTOR_COUNT)
/*32KMAINMEMORYBLOCK段*/
#define FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS (0x00008000)
#define FS_FLASH_MAINMEMORY_32K_BLOCK_ADDRESS(sn) (FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS + (sn) * FS_FLASH_MAINMEMORY_32K_BLOCK_SIZE)
#define FS_FLASH_MAINMEMORY_32K_BLOCK_SIZE (32 * 1024)
#define FS_FLASH_MAINMEMORY_32K_BLOCK_COUNT 1
#define FS_MAINMEMORY_32K_BLOCK_SIZE (FS_FLASH_MAINMEMORY_32K_BLOCK_SIZE * FS_FLASH_MAINMEMORY_32K_BLOCK_COUNT)
/*64KMAINMEMORYBLOCK段*/
#define FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS (0x00010000)
#define FS_FLASH_MAINMEMORY_64K_BLOCK_ADDRESS(sn) (FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS + (sn) * FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE)
#define FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE (64 * 1024)
#define FS_FLASH_MAINMEMORY_64K_BLOCK_COUNT 7
#define FS_MAINMEMORY_64K_BLOCK_SIZE (FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE * FS_FLASH_MAINMEMORY_64K_BLOCK_COUNT)
/*
Boot Block Programing Lockout, 返回0成功
*/
static int flashAT49BV040ABootBlockLockout()
{
volatile unsigned long addr;
unsigned char lockout;
addr=0x555;
lockout=0xAA;
writeflashAT49BV040A(addr,lockout);
addr=0xAAA;
lockout=0x55;
writeflashAT49BV040A(addr,lockout);
addr=0x555;
lockout=0x80;
writeflashAT49BV040A(addr,lockout);
addr=0x555;
lockout=0xAA;
writeflashAT49BV040A(addr,lockout);
addr=0xAAA;
lockout=0x55;
writeflashAT49BV040A(addr,lockout);
addr=0x555;
lockout=0x40;
writeflashAT49BV040A(addr,lockout);
/*延时1ns*/
flashDelay(1000*FS_FLASH_TASKDELAY_TIME);
return 0;
}
/*
进入SoftwareProductIdentification模式,检查Boot Block 是否加锁
返回1:已经加锁
返回0:没有加锁
*/
static int flashAT49BV040ABootBlockLockoutDetection()
{
volatile unsigned long addr;
unsigned char cmd;
unsigned char lockoutdetection;
addr=0x555;
cmd=0xAA;
writeflashAT49BV040A(addr,cmd);
addr=0xAAA;
cmd=0x55;
writeflashAT49BV040A(addr,cmd);
addr=0x555;
cmd=0x90;
writeflashAT49BV040A(addr,cmd);
addr=0x00002;
lockoutdetection=readflashAT49BV040A(addr);
if(!(lockoutdetection&(0x01)))
return 0;
else
return 1;
}
/*
退出SoftwareProductIdentification模式,进入标准操作模式,返回0成功
*/
static int flashAT49BV040AExitSoftwareProductIdentificationMode()
{
volatile unsigned long addr;
unsigned char cmd;
addr=0x555;
cmd=0xAA;
writeflashAT49BV040A(addr,cmd);
addr=0xAAA;
cmd=0x55;
writeflashAT49BV040A(addr,cmd);
addr=0x555;
cmd=0xF0;
writeflashAT49BV040A(addr,cmd);
return 0;
}
/*擦除指定段,成功返回0*/
static int flashAT49BV040A_block_erase(int block)
{
volatile unsigned long addr;
unsigned char cmd;
unsigned long SA;
unsigned char readdata;
int start;
if(block==1)
{
SA=FS_FLASH_BOOT_BLOCK_START_ADDRESS;
}
else if((block>=2)&&(block<=3))
{
SA=(FS_FLASH_PARAMETER_BLOCK_START_ADDRESS+((block-2)*FS_FLASH_PARAMETER_BLOCK_SIZE));
}
else if(block==4)
{
SA=FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS;
}
else
{
SA=(FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS+((block-5)*FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE));
}
addr=0x555;
cmd=0xAA;
writeflashAT49BV040A(addr,cmd);
addr=0xAAA;
cmd=0x55;
writeflashAT49BV040A(addr,cmd);
addr=0x555;
cmd=0x80;
writeflashAT49BV040A(addr,cmd);
addr=0x555;
cmd=0xAA;
writeflashAT49BV040A(addr,cmd);
addr=0xAAA;
cmd=0x55;
writeflashAT49BV040A(addr,cmd);
addr=SA;
cmd=0x30;
writeflashAT49BV040A(addr,cmd);
flashDelay(1200*FS_FLASH_TASKDELAY_TIME);
/*最大延时12s,检查擦数据是否完成*/
readdata=readflashAT49BV040A(addr);
start=120;
while(!(readdata&(0x40)))
{
flashDelay(100*FS_FLASH_TASKDELAY_TIME);
readdata=readflashAT49BV040A(addr);
if(start--==0)
{
printf("Flash erase failly at block %d\n", block);
return -1;
}
}
return 0;
}
/*
向FLASH中写一个8位的数据,返回0成功,-1超时,-2该sector没有擦除
*/
static int flashAT49BV040A_program_chardata(unsigned long dest,unsigned char data)
{
volatile unsigned long addr;
unsigned char cmd;
unsigned char readdata;
int start;
addr=dest;
readdata=readflashAT49BV040A(addr);
if((readdata&data)!=data)
return (-2);
addr=0x555;
cmd=0xAA;
writeflashAT49BV040A(addr,cmd);
addr=0xAAA;
cmd=0x55;
writeflashAT49BV040A(addr,cmd);
addr=0x555;
cmd=0xA0;
writeflashAT49BV040A(addr,cmd);
addr=dest;
cmd=data;
writeflashAT49BV040A(addr,cmd);
flashDelay(50*FS_FLASH_DELAY_TIME);
/*最大延时1ms,来检查写数据是否正确*/
start=20;
readdata=readflashAT49BV040A(addr);
while(readdata^data)
{
flashDelay(50*FS_FLASH_DELAY_TIME);
readdata=readflashAT49BV040A(addr);
if(start--==0)
return -1;
}
return (0);
}
/*
向block写入一段数据,返回0成功
*/
static int flashAT49BV040A_sector_programmedata(int block,const unsigned char*pBuf)
{
unsigned long addr;
unsigned char data;
unsigned long i, rc;
unsigned long SA;
unsigned long blocksize;
if(block==1)
{
SA=FS_FLASH_BOOT_BLOCK_START_ADDRESS;
blocksize=16 * 1024;
}
else if((block>=2)&&(block<=3))
{
SA=(FS_FLASH_PARAMETER_BLOCK_START_ADDRESS+((block-2)*FS_FLASH_PARAMETER_BLOCK_SIZE));
blocksize=8 * 1024;
}
else if(block==4)
{
SA=FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS;
blocksize=32 * 1024;
}
else
{
SA=(FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS+((block-5)*FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE));
blocksize=64 * 1024;
}
addr=SA;
for (i = 0;i<blocksize;i+=1)
{
data = pBuf[i];
rc = flashAT49BV040A_program_chardata(addr,data);
if (rc != 0)
{
return (rc);
}
addr += 1;
}
return 0;
}
/*
提供给外部使用的函数
参数:
block:段号
const unsigned char*PData:要写的数据
返回值:
2:Boot Block lockout
1:flash设备忙
0:成功返回
-1:flash擦除失败
-2:向flash写数据失败
-3:段号超过范围
*/
int flashAT49BV040AwriteSector(int block, const unsigned char*PData)
{
if(getflashAT49BV040AStatus()!=0)
{
printf("flash is busy now!\n");
return 1;
}
else if((block==1)&&(flashAT49BV040ABootBlockLockoutDetection()==1))
{
flashAT49BV040AExitSoftwareProductIdentificationMode();
printf("Boot Block Lockout!\n");
return 2;
}
else if((block>11)||(block<1))
{
printf("the number of block can not larger than 11,smaller than 1!\n");
return -3;
}
else if(flashAT49BV040A_block_erase(block)!=0)
{
return -1;
}
else if(flashAT49BV040A_sector_programmedata(block,PData)!=0)
{
printf("program flash failly at block %d/n",block);
return -2;
}
else
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -