裸板之NAND FLASH
1) 先从硬件上来了解一下nand flash 问1.?原理图上NAND?FLASH和S3C2440之间只有数据线,? 怎么传输地址? ? ? ?发出地址 ? ? ?发出数据/读数据 ?? ? ? ? ? NAND?FLASH??????????????????????S3C2440 1> ?nand flash里面有一个Page Register(页寄存器),上面的立方体表示它的实体,当我们发出读命令的时候,nand?flash控制器会选中实体的某一页,把内容放到Page Register中去,然后我们就可以继续发读命令,把数据源源不断的读出来。 3> 可以看到,nand flash的地址有5个周期。 3) 代码(以15th_nand为例) <span style="font-family:Microsoft YaHei;"> /* 重定位 */ /* 把程序的代码段、数据段复制到它的链接地址去 */ 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 cmp r0,#0 bne halt</span>重定位部分与以前有些不一样,以前是从6410的片上内存拷贝到链接地址,现在是从nand flash拷贝到链接地址去执行。 2>nand.c #define MEM_SYS_CFG (*((volatile unsigned long *)0x7E00F120)) #define NFCONF (*((volatile unsigned long *)0x70200000)) #define NFCONT (*((volatile unsigned long *)0x70200004)) #define NFCMMD (*((volatile unsigned long *)0x70200008)) #define NFADDR (*((volatile unsigned long *)0x7020000C)) #define NFDATA (*((volatile unsigned char *)0x70200010)) #define NFSTAT (*((volatile unsigned long *)0x70200028)) void nand_select(void) { NFCONT &= ~(1<<1); } void nand_deselect(void) { NFCONT |= (1<<1); } void nand_cmd(unsigned char cmd) { NFCMMD = cmd; } void nand_addr(unsigned char addr) { NFADDR = addr; } unsigned char nand_get_data(void) { return NFDATA; } void wait_ready(void) { while ((NFSTAT & 0x1) == 0); } void nand_reset(void) { /* 选中 */ nand_select(); /* 发出0xff命令 */ nand_cmd(0xff); /* 等待就绪 */ wait_ready(); /* 取消选中 */ nand_deselect(); } void nand_init(void) { /* 让xm0csn2用作nand flash cs0 片选引脚 */ MEM_SYS_CFG &= ~(1<<1); /* 设置时间参数 */ #define TACLS 0 #define TWRPH0 1 #define TWRPH1 0 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; /* 这两个地址表示从页内哪里开始 */ nand_addr(addr & 0xff); nand_addr((addr >> 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 } int nand_read(unsigned int nand_start,unsigned int ddr_start,unsigned int len) { unsigned int addr = nand_start; int i,count = 0; unsigned char *dest = (unsigned char *)ddr_start; /* 选中芯片 */ nand_select(); while (count < len) { /* 发出命令0x00 */ nand_cmd(0x00); /* 发出地址 */ nand_send_addr(addr); /* 发出命令0x30 */ nand_cmd(0x30); /* 等待就绪 */ wait_ready(); /* 读数据 */ for (i = 0; i < 2048 && count < len; i++) { dest[count++] = nand_get_data(); } addr += 2048; } /* 取消片选 */ nand_deselect(); return 0; } int copy2ddr(unsigned int nand_start,unsigned int len) { int ret; /* 初始化nand flash controller */ nand_init(); /* 读nand flash */ ret = nand_read(nand_start,ddr_start,len); return ret; }3>看看应用程序main.c
#include "uart.h" int main() { char c; int a,b; init_uart(); printf("hello,worldnr"); while (1) { printf("please enter two number: nr"); scanf("%d %d",&a,&b); printf("nr"); printf("the sum is: %dnr",a+b); } return 0; }在main中做一个简单的计算。运行代码后,结果正确,说明程序已经从nand flash中拷贝到DDRAM中去了。 16th_nand_all中增加了擦除和写操作。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |