📄 main.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: main.c
** Last modified Date:
** Last Version:
** Description:
**
**------------------------------------------------------------------------------------------------------
** Created By:
** Created date:
** Version:
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include "config.h"
// NAND Flash操作宏函数
#define NF_CMD(cmd) rNFCMD = cmd
#define NF_ADDR(addr) rNFADDR = addr
#define NF_nFCE_L() rNFCONF = rNFCONF & (~(1<<11))
#define NF_nFCE_H() rNFCONF = rNFCONF | (1<<11)
#define NF_RSTECC() rNFCONF = rNFCONF | (1<<12)
#define NF_RDDATA() (rNFDATA)
#define NF_WRDATA(data) rNFDATA = data
#define NF_WAITRB() while( !(rNFSTAT&0x01) )
// NAND Flash控制器命令字定义
#define CMD_READ0 0x00
#define CMD_READ1 0x01
#define CMD_PAGEPROG 0x10
#define CMD_READOOB 0x50
#define CMD_ERASE1 0x60
#define CMD_STATUS 0x70
#define CMD_SEQIN 0x80
#define CMD_READID 0x90
#define CMD_ERASE2 0xD0
#define CMD_RESET 0xFF
//add by lgh
#define rNF_ECC0 (*(volatile unsigned char *)0x4e000014)
#define rNF_ECC1 (*(volatile unsigned char *)0x4e000015)
#define rNF_ECC2 (*(volatile unsigned char *)0x4e000016)
#define MAX_BLOCK_NUM 4096
#define PAGE0 0
#define PAGE1 1
uint8 eccbuf[3]={0,0,0};
/*********************************************************************************************************
** Function name: DelayNS
** Descriptions: 长软件延时。
** 延时时间与系统时钟有关。
** Input: dly 延时参数,值越大,延时越久
** Output: 无
** Created by: 黄绍斌
** Created Date: 2005-12-31
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DelayNS(uint32 dly)
{
uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
/*********************************************************************************************************
** Function name: NF_Init
** Descriptions: 初始化NAND Flash控制器
** Input: 无
** Output: 无
** Created by: 黄绍斌
** Created Date: 2006-01-05
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void NF_Init(void)
{
// NAND Flash控制器的I/O设置
rGPACON = rGPACON | (0x2F<<17); //设置为nandflash控制引脚
// NAND Flash控制器配置
rNFCONF = (1<<15) | // 使能NAND Flash控制器
(1<<12) | // 初始化ECC
(0<<11) | // nFCE = H (片选)
(2<<8) | // CLE、ALE延时时间为30nS,HCLK=100MHz
(4<<4) | // TWRPH0为50nS
(2<<0); // TWRPH1为30nS
// 复位NAND Flash
NF_nFCE_L(); // 片选有效
NF_CMD(CMD_ERASE2); // 发送复位命令
NF_WAITRB(); // 等待操作完成
NF_nFCE_H(); // 取消选择
}
/*********************************************************************************************************
** Function name: NF_ReadID
** Descriptions: 读取器件ID (ID Read1)
** Input: 无
** Output: 返回值即时读出的4字节ID信号 (先读出的数据放在最高字节处)
** Created by: 黄绍斌
** Created Date: 2006-01-05
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint32 NF_ReadID(void)
{
uint32 id;
// 发送命令和地址
NF_nFCE_L(); // 片选有效
NF_CMD(CMD_READID); // 发送读ID命令
NF_ADDR(0); // 发送地址0
// 读取ID信息
id = NF_RDDATA(); //manufacture ID
id = id<<8;
id = id | NF_RDDATA(); //device code
id = id<<8;
id = id | NF_RDDATA(); //A5H
id = id<<8; //C0H
id = id | NF_RDDATA();
NF_nFCE_H(); // 取消选择
return(id);
}
/*********************************************************************************************************
** Function name: NF_EraseBlock
** Descriptions: 块擦除操作
** Input: block: 擦除某个块 (不算空闲区,即64MB的地址)
** Output: 擦除成功返回TRUE,否则返回FALSE
** Created by:刘国华
** Created Date: 2007-08-14
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 NF_EraseBlock(uint32 block)
{
uint32 block_page; //块地址
uint8 bak;
block_page=block<<5;// block 00000 (A8 0000 0000:not send),所以左移5位
// 发送命令和地址
NF_nFCE_L();
NF_CMD(CMD_ERASE1); // 发送块擦除命令0x60
//注意只送了3个周期
NF_ADDR(block_page&0xff); // 发送地址A9--A16
NF_ADDR((block_page>>8) & 0xff); // 发送地址A17--A24
NF_ADDR((block_page>>16)& 0xff); // 发送地址A25
NF_CMD(CMD_ERASE2); // 0xd0
NF_WAITRB(); // 等待操作完成
NF_CMD(CMD_STATUS); // 发送读取状态命令0x70
bak = NF_RDDATA();
NF_nFCE_H();
if(bak&0x01)
return(FALSE); //erase fail
else
return(TRUE); //erase success
}
/*********************************************************************************************************
** Function name: NF_WritePage
** Descriptions: 写一页数据
** Input: block: 块号
page 页号
** Output :
** Created by:刘国华
** Created Date: 2007-08-14
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 NF_WritePage(uint32 block,uint8 page,uint8 *buf)
{
uint32 blockpage=(block<<5)+page;//
uint32 i;
uint8 status;
NF_RSTECC(); //ECC使能
NF_nFCE_L();
NF_CMD(CMD_READ0); //从0x00位置开始写一页
NF_CMD(CMD_SEQIN); //0x80
NF_ADDR(0x00); //A7-A0为0x00
NF_ADDR(blockpage&0x000000ff); //A9-A16
NF_ADDR((blockpage>>8)&0x000000ff);//A17-A24
NF_ADDR((blockpage>>16)&0x000000ff); //A25
//写入字节的数据
for(i=0;i<512;i++)
{
NF_WRDATA(*buf++);
}
//写OOB区数据,只写前面的三个为了测试
/*
eccbuf[0]=rNF_ECC0;
eccbuf[1]=rNF_ECC1;
eccbuf[2]=rNF_ECC2; //两种方法都可以
*/
i=rNFECC;
eccbuf[0]=i&0xff;
eccbuf[1]=(i>>8)&0xff;
eccbuf[2]=(i>>16)&0xff;
Uart_Printf("W_EEC0:0x%x,W_EEC1:0x%x,W_EEC2:0x%x\n",eccbuf[0],eccbuf[1],eccbuf[2]);
for(i=0;i<3;i++)
{
NF_WRDATA(eccbuf[i]);
}
NF_CMD(CMD_PAGEPROG);
NF_WAITRB();
NF_CMD(CMD_STATUS);
status=NF_RDDATA();
if(status&0x01)
{
NF_nFCE_H();
return FALSE;
}
else
{
NF_nFCE_H();
return TRUE;
}
}
/*********************************************************************************************************
** Function name: NF_ReadPage
** Descriptions: 读一页数据
** Input: block: 块号 (0-4095)
page 页号(0-31)
** Output :
** Created by:刘国华
** Created Date: 2007-08-14
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 NF_ReadPage(uint32 block,uint8 page,uint8 *buf_ret)
{
uint32 blockpage=(block<<5)+page;//
uint32 i;
uint8 r_ecc0,r_ecc1,r_ecc2;
NF_RSTECC(); //ECC使能
NF_nFCE_L();
NF_CMD(CMD_READ0); //从0x00位置开始写一页
NF_ADDR(0x00); //A7-A0为0x00
NF_ADDR(blockpage&0x000000ff); //A9-A16
NF_ADDR((blockpage>>8)&0x000000ff);//A17-A24
NF_ADDR((blockpage>>16)&0x000000ff); //A25
NF_WAITRB();
for(i=0;i<512;i++)
{
*buf_ret++=NF_RDDATA();
}
//读取该页的3个字节ECC(写的时候的ECC)
for(i=0;i<3;i++)
{
eccbuf[i]=NF_RDDATA();
}
NF_nFCE_H();
//读出此时的ECC校验码(读出数据后产生的ECC)
r_ecc0=rNF_ECC0;
r_ecc1=rNF_ECC1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -