📄 flash.c
字号:
/*********************************************************************************************
* File: flash.c
* Author: Embest
* Desc: source code of flash
* History:
*
*********************************************************************************************/
#include "flash.h"
#define OS_CRITICAL_METHOD 0
#define OS_CPU_SR unsigned int
#define OS_ENTER_CRITICAL()
#define OS_EXIT_CRITICAL()
/*------------------------------------------------------------------------------------------*/
/* static global variables */
/*------------------------------------------------------------------------------------------*/
static unsigned short id_man, id_dev, id_ade; // Flash ID
/*********************************************************************************************
* name: Flash_Delay
* func: flash delay
* para: none
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void Flash_Delay(void)
{
volatile unsigned int i;
// delay about 70 us
//for(i=0; i<231; i++);
for(i=0; i<21; i++); // R.X.Huang 2005-04-28 modified for EduKit II 2410
}
/*********************************************************************************************
* name: FlashID_AT49BV1614A
* func: about flash ID
* para: unsigned int base_addr -- base_addr of flash AT49BV1614A
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void FlashID_AT49BV1614A(unsigned int base_addr)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
base_addr &= ~AT49BV1614A_FLASH_MASK;
OS_ENTER_CRITICAL();
// enter read ID mode
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0xAAA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0x90;
// read ID
id_man = *(volatile unsigned short *)(base_addr + (0x00<<1));
id_dev = *(volatile unsigned short *)(base_addr + (0x01<<1));
id_ade = *(volatile unsigned short *)(base_addr + (0x03<<1));
// exit read ID mode
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0xAAA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xF0;
OS_EXIT_CRITICAL();
}
/*********************************************************************************************
* name: FlashEraseSector_AT49BV1614A
* func: erase flash sector
* para: unsigned int base_addr -- base_addr of flash AT49BV1614A
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void FlashEraseSector_AT49BV1614A(unsigned int base_addr)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
unsigned int i, sector_addr;
sector_addr = (base_addr & AT49BV1614A_FLASH_MASK);
sector_addr >>= 1;
sector_addr <<= 1;
base_addr &= ~AT49BV1614A_FLASH_MASK;
OS_ENTER_CRITICAL();
// enter erase sector mode
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0xAAA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0x80;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0xAAA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (sector_addr)) = 0x30;
// delay about 420 ms
for(i=0; i<6000; i++)
Flash_Delay();
OS_EXIT_CRITICAL();
}
/*********************************************************************************************
* name: FlashProgram_AT49BV1614A
* func: program flash
* para: unsigned int base_addr -- base_addr of flash AT49BV1614A
* unsigned short *data_addr -- address of data to be programmed
* unsigned int bytes -- bytes of data to be programmed
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void FlashProgram_AT49BV1614A(unsigned int base_addr, unsigned short *data_addr, unsigned int bytes)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
unsigned int i, word_addr;
word_addr = (base_addr & AT49BV1614A_FLASH_MASK);
base_addr &= ~AT49BV1614A_FLASH_MASK;
if(bytes % 2)
bytes += 1;
bytes >>= 1;
// enter program mode
for(i=0; i<bytes; i++)
{
OS_ENTER_CRITICAL();
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0xAAA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xA0;
*(volatile unsigned short *)(base_addr + (word_addr)) = data_addr[i];
// delay 50 us
Flash_Delay();
word_addr += sizeof(unsigned short);
OS_EXIT_CRITICAL();
}
}
/*********************************************************************************************
* name: FlashSectorSize_AT49BV1614A
* func: get flash sector size of AT49BV1614A
* para: unsigned int base_addr -- base_addr of flash AT49BV1614A
* ret: sector size of AT49BV1614A(unsigned int)
* modify:
* comment:
*********************************************************************************************/
static unsigned int FlashSectorSize_AT49BV1614A(unsigned int base_addr)
{
unsigned int sector_addr = (base_addr & AT49BV1614A_FLASH_MASK);
if(sector_addr >= 0x00 && sector_addr < 0x10000)
return (8*1024);
else if(sector_addr >= 0x10000 && sector_addr < 0x200000)
return (64*1024);
else
return 0;
}
/*********************************************************************************************
* name: FlashID_AM29LV160DB
* func: about flash ID
* para: unsigned int base_addr -- base_addr of flash AM29LV160DB
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void FlashID_AM29LV160DB(unsigned int base_addr)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
base_addr &= ~AM29LV160DB_FLASH_MASK;
OS_ENTER_CRITICAL();
// enter read man_ID mode
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0x2AA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0x90;
// read man_ID
id_man = *(volatile unsigned short *)(base_addr + (0x00<<1));
// enter read dev_ID mode
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0x2AA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0x90;
// read dev_ID
id_dev = *(volatile unsigned short *)(base_addr + (0x01<<1));
id_ade = AM29LV160DB_ADE_ID;
OS_EXIT_CRITICAL();
}
/*********************************************************************************************
* name: FlashEraseSector_AM29LV160DB
* func: erase flash sector
* para: unsigned int base_addr -- base_addr of flash AM29LV160DB
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void FlashEraseSector_AM29LV160DB(unsigned int base_addr)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
unsigned int i, sector_addr;
sector_addr = (base_addr & AM29LV160DB_FLASH_MASK);
sector_addr >>= 1;
sector_addr <<= 1;
base_addr &= ~AM29LV160DB_FLASH_MASK;
OS_ENTER_CRITICAL();
// enter erase sector mode
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0x2AA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0x80;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0x2AA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (sector_addr)) = 0x30;
// delay about 700 ms
for(i=0; i<10000; i++)
Flash_Delay();
OS_EXIT_CRITICAL();
}
/*********************************************************************************************
* name: FlashProgram_AM29LV160DB
* func: program flash
* para: unsigned int base_addr -- base_addr of flash AM29LV160DB
* unsigned short *data_addr -- address of data to be programmed
* unsigned int bytes -- bytes of data to be programmed
* ret: none
* modify:
* comment:
*********************************************************************************************/
static void FlashProgram_AM29LV160DB(unsigned int base_addr, unsigned short *data_addr, unsigned int bytes)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
unsigned int i, word_addr;
word_addr = (base_addr & AM29LV160DB_FLASH_MASK);
base_addr &= ~AM29LV160DB_FLASH_MASK;
if(bytes % 2)
bytes += 1;
bytes >>= 1;
// enter programe mode
for(i=0; i<bytes; i++)
{
OS_ENTER_CRITICAL();
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xAA;
*(volatile unsigned short *)(base_addr + (0x2AA<<1)) = 0x55;
*(volatile unsigned short *)(base_addr + (0x555<<1)) = 0xA0;
*(volatile unsigned short *)(base_addr + (word_addr)) = data_addr[i];
// delay 50 us
Flash_Delay();
word_addr += sizeof(unsigned short);
OS_EXIT_CRITICAL();
}
}
/*********************************************************************************************
* name: FlashSectorSize_AM29LV160DB
* func: get flash sector size of AM29LV160DB
* para: unsigned int base_addr -- base_addr of flash AM29LV160DB
* ret: sector size of AM29LV160DB(unsigned int)
* modify:
* comment:
*********************************************************************************************/
static unsigned int FlashSectorSize_AM29LV160DB(unsigned int base_addr)
{
unsigned int sector_addr = (base_addr & AM29LV160DB_FLASH_MASK);
if(sector_addr >= 0x00 && sector_addr < 0x4000)
return (16*1024);
else if(sector_addr >= 0x4000 && sector_addr < 0x6000)
return (8*1024);
else if(sector_addr >= 0x6000 && sector_addr < 0x8000)
return (8*1024);
else if(sector_addr >= 0x8000 && sector_addr < 0x10000)
return (32*1024);
else if(sector_addr >= 0x10000 && sector_addr < 0x200000)
return (64*1024);
else
return 0;
}
/*********************************************************************************************
* name: FlashID
* func: read flash id success or not
* para: unsigned int base_addr -- base_addr of flash
* ret: 1: read success; 0: read fail
* modify:
* comment:
*********************************************************************************************/
int FlashID(unsigned int base_addr)
{
// read AT49BV1614A flash ID
FlashID_AT49BV1614A(base_addr);
if( id_man == AT49BV1614A_MAN_ID &&
id_dev == AT49BV1614A_DEV_ID &&
id_ade == AT49BV1614A_ADE_ID )
{
return 1;
}
// read AM29LV160B/DB flash ID
FlashID_AM29LV160DB(base_addr);
if( id_man == AM29LV160DB_MAN_ID &&
id_dev == AM29LV160DB_DEV_ID &&
id_ade == AM29LV160DB_ADE_ID )
{
return 1;
}
return 0;
}
/*********************************************************************************************
* name: FlashEraseSector
* func: erase flash sectors
* para: unsigned int base_addr -- base_addr of flash
* ret: none
* modify:
* comment:
*********************************************************************************************/
void FlashEraseSector(unsigned int base_addr)
{
// AT49BV1614A
if( id_man == AT49BV1614A_MAN_ID &&
id_dev == AT49BV1614A_DEV_ID &&
id_ade == AT49BV1614A_ADE_ID )
{
FlashEraseSector_AT49BV1614A(base_addr);
}
// AM29LV160B/DB
else if(id_man == AM29LV160DB_MAN_ID &&
id_dev == AM29LV160DB_DEV_ID &&
id_ade == AM29LV160DB_ADE_ID )
{
FlashEraseSector_AM29LV160DB(base_addr);
}
}
/*********************************************************************************************
* name: FlashProgram
* func: program flash
* para: unsigned int base_addr -- base_addr of flash
* unsigned short *data_addr -- address of data to be programmed
* unsigned int bytes -- bytes of data to be programmed
* ret: none
* modify:
* comment:
*********************************************************************************************/
void FlashProgram(unsigned int base_addr, unsigned short *data_addr, unsigned int bytes)
{
// AT49BV1614A
if( id_man == AT49BV1614A_MAN_ID &&
id_dev == AT49BV1614A_DEV_ID &&
id_ade == AT49BV1614A_ADE_ID )
{
FlashProgram_AT49BV1614A(base_addr, data_addr, bytes);
}
// AM29LV160B/DB
else if(id_man == AM29LV160DB_MAN_ID &&
id_dev == AM29LV160DB_DEV_ID &&
id_ade == AM29LV160DB_ADE_ID )
{
FlashProgram_AM29LV160DB(base_addr, data_addr, bytes);
}
}
/*********************************************************************************************
* name: FlashSectorSize
* func: get size of flash's sector
* para: unsigned int base_addr -- base_addr of flash
* ret: none
* modify:
* comment:
*********************************************************************************************/
unsigned int FlashSectorSize(unsigned int base_addr)
{
unsigned int size = 0;
// AT49BV1614A
if( id_man == AT49BV1614A_MAN_ID &&
id_dev == AT49BV1614A_DEV_ID &&
id_ade == AT49BV1614A_ADE_ID )
{
size = FlashSectorSize_AT49BV1614A(base_addr);
}
// AM29LV160B/DB
else if(id_man == AM29LV160DB_MAN_ID &&
id_dev == AM29LV160DB_DEV_ID &&
id_ade == AM29LV160DB_ADE_ID )
{
size = FlashSectorSize_AM29LV160DB(base_addr);
}
return size;
}
/*********************************************************************************************
* name: FlashSectorBackup
* func: backup data on flash's sector
* para: unsigned int base_addr -- base_addr of flash
* unsigned char *buf -- buf to backup data on flash's sector
* ret: size of data backuped & return the data's address by pointer buf
* modify:
* comment:
*********************************************************************************************/
unsigned int FlashSectorBackup(unsigned int base_addr, unsigned char *buf)
{
unsigned int size;
size = FlashSectorSize(base_addr);
if(size > 0)
{
unsigned int i;
unsigned char *ptr;
ptr = (unsigned char *)(base_addr & (0 - size));
for(i=0; i<size; i++)
buf[i] = *ptr++;
}
return size;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -