#define NFCONF (*(volatile unsigned long*)0x4E000000) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
#define NFCONT (*(volatile unsigned long*)0x4E000004)
#define NFCMD? (*(volatile unsigned char*)0x4E000008)
#define NFADDR (*(volatile unsigned char*)0x4E00000C)
#define NFDATA (*(volatile unsigned char*)0x4E000010)
#define NFSTAT (*(volatile unsigned char*)0x4E000020)
?
#define TACLS 1
#define TWRPH0 2
#define TWRPH1 1
?
?
void select_chip()
{
??? NFCONT &= ~(1<<1);??????
}
?
void deselect_chip()
{
??? NFCONT |= (1<<1);?
}
?
void clear_RnB()
{
?? NFSTAT |= (1<<2);
}
?
void send_cmd(unsigned cmd)
{
???? NFCMD = cmd;
}
?
void send_addr(unsigned addr)
{
???? NFADDR = addr;
}
?
void wait_RnB()
{
?? while (!(NFSTAT&(1<<2)))?
?? {
?????? ;
?? }
}
?
void nand_reset()
{
??? //选中flash
??? select_chip();
???
??? //清除RnB
??? clear_RnB();
???
???
??? //发送0xff命令
??? send_cmd(0xff);
???
???
??? //等待RnB
??? wait_RnB();
???
????????
??? //取消选中flash
??? deselect_chip();
}
?
void nand_init()
{
??? //初始化NFCONF
??? NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
???
??? //初始化NFCONT
??? NFCONT = (1<<0) | (1<<1);
???
??? //复位
??? nand_reset();?
}
?
void NF_PageRead(unsigned long addr,unsigned char* buff)
{
???????? int i;
????????
???????? //int col = addr % 2048;
???????? //int page = addr / 2048;
???????? int col = 0x0;
???????? int page = addr;
?
???????? //选中nandflash芯片
???????? select_chip();
????????
???????? //清除RnB
???????? clear_RnB();
????????
???????? //发送命令0x00
???????? send_cmd(0x00);
????????
???????? send_addr(col & 0xff);
???????? send_addr((col >> 8) & 0xff);
?
???????? send_addr(page & 0xff);
???????? send_addr((page >> 8) & 0xff);
???????? send_addr((page >> 16) & 0xff);
????????
???????? //发送命令0x30
???????? send_cmd(0x30);
????????
???????? //等待RnB
???????? wait_RnB();
????????
???????? //读取数据
???????? for(i=0;i<2048;i++)
???????? {
???????? ?? buff[i] = NFDATA;? ??
???????? }
????????
???????? //取消选中nandflash芯片
???????? deselect_chip();
}
?
?
void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size)
{
???????? int page = start_addr / 2048;
???????? for(;size>0;)
???????? {
???????? ??? NF_PageRead(page,sdram_addr);
???????? ??? size -= 2048;
???????? ??? sdram_addr += 2048;
???????? ??? page++;
???????? }
}
?
int NF_Erase(unsigned long addr)
{
???????? int ret;
???????? unsigned int page = addr/2048;
????????
? //选中flash芯片
???????? select_chip();
????????
???????? //清除RnB
???????? clear_RnB();
????????
???????? //发送命令0x60
???????? send_cmd(0x60);
????????
???????? //发送行地址
???????? send_addr(page&0xff);
???????? send_addr((page>>8)&0xff);
???????? send_addr((page>>16)&0xff);
????????
???????? //发送命令D0
???????? send_cmd(0xD0);
????????
???????? //等待RnB
???????? wait_RnB();
????????
???????? //发送命令0x70
???????? send_cmd(0x70);
????????
???????? //读取擦除结果
???????? ret = NFDATA;
????????
???????? //取消选中flash芯片
???????? deselect_chip();
????????
???????? return ret;
????????
}
?
int NF_WritePage(unsigned long addr,unsigned char *buff)
{
???????? unsigned int i,ret = 0,page,col;
???????? col = addr % 2048;
???????? page = addr /2048;
???????? //选中nandflash
???????? select_chip();
????????
???????? //清除RnB
???????? clear_RnB();
????????
???????? //发送0x80命令
???????? send_cmd(0x80);
????????
???????? //发送2个列地址
???????? /* 这种写法ok
???????? send_addr(col & 0xff);
???????? send_addr((col >> 8) & 0xff);
???????? send_addr(page & 0xff);
???????? send_addr((page >> 8) & 0xff);
???????? send_addr((page >> 16) & 0xff);
???????? */
?
????????
???????? send_addr(addr & 0xff);???????? // a0~a7
???????? send_addr((addr >> 8) & 0x7);?? // 以程序角度看 a8~a10
?
???????? send_addr((addr >> 11) & 0xff); // 以程序角度看 a12~a19
???????? send_addr((addr >> 19) & 0xff); // 以程序角度看 a20~a27
???????? send_addr((addr >> 27) & 0xff); // 以程序角度看 a28???
????????
/*???? wrong 移位错误
???????? send_addr(addr & 0xff);???????? // a0~a7
???????? send_addr((addr >> 8) & 0x7);?? // 以程序角度看 a8~a10
?
???????? send_addr((addr >> 12) & 0xff); // 以程序角度看 a12~a19
???????? send_addr((addr >> 20) & 0xff); // 以程序角度看 a20~a27
???????? send_addr((addr >> 28) & 0xff); // 以程序角度看 a28???
*/
???????? //发送数据
???????? for(i=0;i<2048;i++)
???????? {
???????? ?? NFDATA = buff[i];? ??
???????? }
????????
???????? //发送0x10命令
???????? send_cmd(0x10);
????????
???????? //等待RnB
???????? wait_RnB();
????????
???????? //发送0x70命令
???????? send_cmd(0x70);
????????
???????? //读取写入结果
???????? ret = NFDATA;
????????
???????? //关闭nandflash
???????? deselect_chip();
???????? ?return ret;
}