.globl _start
_start:
/* 硬件相关的设置 */
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
/* 关看门狗 */
/* 往WTCON(0x7E004000)写0 */
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
/* 设置栈 */
ldr sp, =8*1024
/* 设置时钟 */
bl clock_init
/* 设置DDR */
bl ddr_init
/* 重定位 */
/* 把程序的代码段、数据段复制到它的链接地址去 */
adr r0, _start /* 获得_start指令当前所在的地址 : 0*/
ldr r1, =_start /* _start的链接地址 0x51000000 */
ldr r2, =bss_start /* bss段的起始链接地址 */
sub r2, r2, r1
cmp r0,r1
beq clean_bss
bl copy2ddr //copy2ddr函数第一个参数nand_start会装到r0,
第二个参数ddr_start装入r1,
第三个参数len装入r2中(参数传递规则中说明)
cmp r0, #0
bne halt
/* 清BSS */
/* 把BSS段对应的内存清零 */
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
mov r3, #0
cmp r0, r1
beq on_ddr
clean_loop:
str r3, [r0], #4
cmp r0, r1
bne clean_loop
on_ddr:
ldr pc, =main
halt:
b halt
/***************copy2ddr函数**************/
int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
int ret;
/* 初始化nand flash controller */
nand_init();
/* 读nand flash */
ret = nand_read(nand_start, ddr_start, len);
return ret;
}
/*************nand_init函数********************/
void nand_init(void)
{
/* 让xm0csn2用作nand flash cs0 片选引脚 */
MEM_SYS_CFG &= ~(1<<1);
/* 设置时间参数 */
#define TACLS 0 //在发出CLE或ALE信号之后,再过多长时间才发出WE(写使能)信号,
等价于图一中(tcls-twp)或者(tals-twp)时间长,设置为0,意为CLE,ALE,WE信号同时发出
则TACLS为0
#define TWRPH0 1 //如图二,TWRPH0表示WE脉冲信号长度;1:两个脉冲,0:一个脉冲
//计算如下:
则TWRPH0需大于等于1,取1
#define TWRPH1 0 //如图二,TWRPH1表示WE释放后,过多少时间,将CLE或ALE信号释放
如图一,TWRPH1等价于tclh或talh
//计算如下:
图一
图二
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4)); //清零
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));
/* 使能nand flash controller */
NFCONT |= 1;
nand_reset(); //自己了解
}
void nand_send_addr(unsigned int addr)
{
#if 0
unsigned int page = addr / 2048; //哪一页
unsigned int column = add & (2048 - 1);
/* 这两个地址表示从页内哪里开始 */
nand_addr( column & 0xff);
nand_addr((column >> 8) & 0xff);
/* 下面三个地址表示哪一页 */和上面程序等价
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
#else
nand_addr(addr & 0xff); /* a0~a7 */
nand_addr((addr >> 8) & 0x7); /* 程序的角度: a8~a10 */
nand_addr((addr >> 11) & 0xff); /* 程序的角度: a11~a18 */
nand_addr((addr >> 19) & 0xff); /* 程序的角度: a19~a26 */
nand_addr((addr >> 27) & 0xff); /* 程序的角度: a27~ */
#endif
}
nand Flash 原理: