📄 at29c040x.c
字号:
/****************************************Copyright (c)**************************************************
**
**
**
**
**--------------File Info-------------------------------------------------------------------------------
** File name: AT29C04X.h
** Last modified Date:
** Last Version: 1.0
** Descriptions: 读写ATMEL FLASH
**
**------------------------------------------------------------------------------------------------------
** Created by: 潘妙青
** Created date: 2008-2-26
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
#include "delay.h"
#define __SRC
#include "AT29C040X.h"
#undef __SRC
#define FLASH_BASE_ADDR 0x82000000
#define MAX_SECTOR_NUMBER 2048
#define SECTOR_SIZE 256
#define TWC 1
void delay_20ms(void)
{
int i;
for(i = 0;i < 2;i++)
delay_10ms();
}
void delay_flash()
{
int i;
for(i = 0; i< TWC; i++)
delay_10ms();
}
/****************************************************************************
* 名称:flash_SDP_enable()
* 功能:使能SDP功能
* 入口参数:
* 出口参数:
****************************************************************************/
void flash_SDP_enable(void)
{
uint8 *flash_addr = NULL;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x5555);
*flash_addr = 0xAA;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x2AAA);
*flash_addr = 0x55;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x5555);
*flash_addr = 0xA0;
}
/****************************************************************************
* 名称:entry_id_mode()
* 功能:进入ID模式
* 入口参数:
* 出口参数:
****************************************************************************/
void entry_id_mode(void)
{
uint8 *flash_addr = NULL;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x5555);
*flash_addr = 0xAA;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x2AAA);
*flash_addr = 0x55;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x5555);
*flash_addr = 0x90;
}
/****************************************************************************
* 名称:leave_id_mode()
* 功能:退出ID模式
* 入口参数:
* 出口参数:
****************************************************************************/
void leave_id_mode(void)
{
uint8 *flash_addr = NULL;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x5555);
*flash_addr = 0xAA;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x2AAA);
*flash_addr = 0x55;
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x5555);
*flash_addr = 0xF0;
}
/****************************************************************************
* 名称:Init_Flash()
* 功能:初始化FLASH
* 入口参数:
* 出口参数:
****************************************************************************/
int Init_Flash(void)
{
uint8 flash_id;
uint8 *flash_addr = NULL;
entry_id_mode(); //进入读ID模式
delay_20ms();
flash_addr = (uint8 *)(FLASH_BASE_ADDR + 0x0001); //ID地址为0X0001
flash_id = *flash_addr;
leave_id_mode(); //退出读ID模式
delay_20ms();
if(flash_id != 0xa4)
return -1;
/*
switch(flash_id)
{
case 0x5b:
sector_size = 512; //29C040
twc = 1;
break;
case 0xa4:
sector_size = 256; //29C040A
twc = 1;
break;
case 0x3b:
secotr_size = 512; //29LV040
twc = 2;
break;
case 0xc4:
sector_size = 256; //29LV040A
twc = 2;
break;
default:
sector_size = 0;
twc = 0;
}
*/
return 0;
}
/****************************************************************************
* 名称:Write_Flash_Sector()
* 功能:写数据到一扇区中
* 入口参数:FlashAddr(0x82000000-0x8207FFFF) / length of data is sector_size
* sector:0-2047
* 出口参数:
****************************************************************************/
int Write_Flash_Sector(uint8 sector, uint8 *data)
{
int i;
uint8 *addr = (uint8 *)(FLASH_BASE_ADDR + sector * SECTOR_SIZE);
flash_SDP_enable(); //使能SDP功能,保护数据
for(i = 0; i < SECTOR_SIZE; i++)
*(addr + i) = *(data + i);
delay_flash(); //DELAY 10ms
return 0;
}
/****************************************************************************
* 名称:Write_Flash()
* 功能:写SRAM数据到FLASH中
* 入口参数:FlashAddr(0x82000000-0x8207FFFF)
* 出口参数:
****************************************************************************/
int Write_Flash(uint32 FlashAddr, uint8 *data, int datalen)
{
int i;
uint8 sector,offset;
uint8 sector_buf[SECTOR_SIZE];
uint8 check_buf[SECTOR_SIZE];
if(data == NULL || datalen == 0)
return -1;
if(datalen > FlashAddr - FLASH_BASE_ADDR) //越界
return -1;
sector = (FlashAddr - FLASH_BASE_ADDR) >> 8; //计算起始扇区号
offset = FlashAddr & 0xFF; //计算扇区内偏移
while(datalen > 0) {
Read_Flash((FLASH_BASE_ADDR + sector * SECTOR_SIZE),sector_buf, SECTOR_SIZE); //读取当前扇区
for( i = 0; (i < SECTOR_SIZE - offset) && (datalen > 0); i++, datalen--) {
data += i;
sector_buf[offset + i] = *data;
}
Write_Flash_Sector(sector, sector_buf); //写入一扇区
Read_Flash((FLASH_BASE_ADDR + sector * SECTOR_SIZE),check_buf, SECTOR_SIZE);
for(i = 0; i < SECTOR_SIZE; i++) { //验证
if(*(check_buf + i) != *(sector_buf + i))
return -1;
}
offset = 0;
sector++;
}
return 0;
}
/****************************************************************************
* 名称:Read_Flash()
* 功能:读取一扇区数据到SRAM中
* 入口参数:FlashAddr(0x82000000-0x8207FFFF)
* 出口参数:
****************************************************************************/
int Read_Flash(uint32 FlashAddr, uint8 *buf, int buflen)
{
int i;
uint8 *flash_addr = (uint8 *)FlashAddr;
if(buf == NULL || buflen == 0)
return -1;
if(buflen > FlashAddr - FLASH_BASE_ADDR) // 越界
return -1;
for(i = 0; i < buflen; i++)
*(buf + i) = *(flash_addr + i);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -