页读只需行addr,随机读需行addr+列addr,本课实现页读
Read Operation:p33
Read Operation:p33
#define NFCONF (*(volatile unsigned long*)0x4E000000)
#define NFCONT (*(volatile unsigned long*)0x4E000004)
#define NFSTAT (*(volatile unsigned char*)0x4E000020)
#define NFCMD (*(volatile unsigned char*)0x4E000008)
#define NFADDR (*(volatile unsigned char*)0x4E00000C)
#define NFDATA (*(volatile unsigned char*)0x4E000010)
#define TACLS 1
#define TWRPH0 2
#define TWRPH1 1
void select_chip()
{
NFCONT &= ~(1<<1);
}
void deselect_chip()
{
NFCONT |= (1<<1);
}
void clear_RnB() //写1清零,当R/nB出现上升沿,该位自动设1,表ready
{
NFSTAT |= (1<<2);
}
void send_cmd(unsigned cmd)
{
NFCMD = cmd;
}
void send_addr(unsigned addr)
{
NFADDR = addr;
}
void wait_RnB()
{
while(!(NFSTAT&(1<<2))); //非1则等待
}
void nand_reset()
{
select_chip();
clear_RnB();
send_cmd(0xff);
wait_RnB();
deselect_chip();
}
void nand_init()
{
NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4); //初始化NFCONF
NFCONT = (1<<0) | (1<<1); //初始化NFCONT
nand_reset();
}
void NF_PageRead(unsigned long addr,unsigned char* buff)
{
int i;
select_chip();
clear_RnB();
send_cmd(0x00);
send_addr(0x00); //列地址,页读,无页偏移
send_addr(0x00);
send_addr(addr&0xff); //先发低8位
send_addr((addr>>8)&0xff);
send_addr((addr>>16)&0xff);
send_cmd(0x30);
wait_RnB();
for(i=0;i<2048;i++)
{
buff[i] = NFDATA;
}
deselect_chip();
}
void nand_to_ram(unsigned long start_addr, unsigned char* sdram_addr, int size)
{
int i;
for( i=(start_addr >>12); size>0;) //右移11位获得页地址
{
NF_PageRead(i,sdram_addr);
size -= 2048;
sdram_addr += 2048;
i++;
}
}
bl nand_init
bl copy_to_ram
copy_to_ram:
mov r0, #0
ldr r1, =_start
ldr r2, =bss_end
sub r2,r2,r1
mov ip,lr
bl nand_to_ram //会破坏lr内容
mov lr, ip
mov pc,lr