tiny6410裸机实验第6章--------------NAND(初始化代码及NAND操作)
来源:互联网 发布:中原 知乎 编辑:程序博客网 时间:2024/06/11 11:55
【说明】
前面我们已经说明了初始化NAND控制器的原理,这一节就是源代码了,这个源代码不是用的友善的源代码,因为我的NAND FLASH 是8KB块的。友善给的源代码是2KB的。这个代码是一位网友提供的。初始化步骤就是按前面的原理来的。这节还会介绍读写NAND的操作
【初始化代码】
其中的nand_reset 在下面,它和初始化没关系的。
#define GPOCON (*(volatile unsigned long*)(0x7F008140))#define GPOPUD (*(volatile unsigned long*)(0x7F008148))#define GPPCON (*(volatile unsigned long*)(0x7F008160))#define GPPPUD (*(volatile unsigned long*)(0x7F008168))#define TACLS 7#define TWRPH0 7#define TWRPH1 7void nand_init(){ GPOCON = (GPOCON & ~0xf) | 0xa;//nCS[3:2] GPOPUD &= ~0xf; GPPCON = (GPPCON & ~(0xfff << 4)) | (0xaaa << 4);//nWAIT, FALE, FCLE, GPPPUD &= ~(0xfff << 4);//FWEn, FREn, FRnB MEM_SYS_CFG &= ~(1<<1); NFCONF &= ~((0x7<<4)|(0x7<<8)|(0x7<<12)|(1<<30)); NFCONF |= (TWRPH1<<4)|(TWRPH0<<8)|(TACLS<<12); NFCONT |= 1; NFCONT &= ~(1<<16); nand_reset();}
【选中和取消片选】
1】原理
这个寄存器我们前面见过的,它里面就有控制片选信号的位
因为我们的片选信号用的是XM0CSN2,所以用下面的位
2】代码
void nand_select(){ NFCONT &= ~(1<<1);}void nand_deselect(){ NFCONT |= 1<<1;}
【发送命令】
1】原理
一眼就看到这个寄存器了!
可是该往里面写什么呢。。命令是些什么呢?在NAND的芯片手册上有相应的命令的编号,我们看看!
2】源代码
void nand_cmd(unsigned char cmd){ NFCMMD = cmd;}
【发送地址】
1】原理
显然要用这个寄存器
但是一样的,我们要怎么发地址呢,还记得吗,我们数据地址命令都只用同样一组线,而且只有8根,,显然地址要分多次发送
在NAND 芯片手册中我们找到了,没错!一次地址要发送5个周期。。。。
2】源代码
void nand_addr(unsigned long addr){ unsigned long row = addr/PAGE_SIZE; unsigned long column = addr%PAGE_SIZE; NFADDR = column&0xFF; NFADDR = (column>>8)&0xFF; NFADDR = row&0xFF; NFADDR = (row>>8)&0xFF; NFADDR = (row>>16)&0xFF;}
【等待就绪】
1】原理
还记得我们原理图中的RNB吗,没错,就是和这个寄存器的第一位直接挂钩
2】源代码
void nand_ready(){ while((NFSTAT&0x1) == 0);}
【RESET】
从上边知道要RESET就要发送0XFF命令,我们直接来看代码,体会一下各个函数如何组合使用
void nand_reset(){ nand_select(); nand_cmd(0xff); nand_ready(); nand_deselect();}
【读,擦除,写】
我觉得直接放源代码就能懂了。。没什么新东西,唯一要注意的就是要先擦除才能写。
另外就是NAND 是按页来存储的,我的NAND 是一页8KB。。发送一次地址,NAND 会为你准备一整页的数据,读这一整页不需要重新发地址。。
int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len){ unsigned long rest = len; unsigned long addr = nand_start; unsigned long page; unsigned char *dest = (unsigned char *)ddr_start; int i; nand_select(); while(rest > 0){ nand_cmd(0x00); nand_addr(addr); nand_cmd(0x30); nand_ready(); page = rest>PAGE_SIZE?PAGE_SIZE:rest; for(i = 0; i != page; ++i){ *dest++ = NFDATA; } rest -= page; addr += page; } nand_deselect(); return 0;}void nand_erase(unsigned long addr){ int page = addr/PAGE_SIZE; nand_select(); nand_cmd(0x60); NFADDR = page&0xff; NFADDR = (page>>8)&0xff; NFADDR = (page>>16)&0xff; nand_cmd(0xd0); nand_ready(); nand_deselect();}void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len){ unsigned long count = 0; unsigned long addr = nand_start; int i = nand_start % PAGE_SIZE; nand_select(); while (count < len) { nand_cmd(0x80); nand_addr(addr); for (; i < PAGE_SIZE && count < len; i++) { NFDATA = buf[count++]; addr++; } nand_cmd(0x10); nand_ready(); i = 0; } nand_deselect();}
【真正的重定位】
这下好了,我们可以使用NAND 了,,那么我们就可以写个函数,把程序从NAND 中复制到DDR中了。由于复制的时候前4页要特殊处理(前4页每页2K)后面的就按页大小来复制咯。。代码如下。。用来代替前一章的复制函数
void copy2ddr(unsigned long length){ unsigned long rest = length; unsigned long size; unsigned long i; for(i = 0; i != 4; ++i){ size = rest>2048?2048:rest; nand_read(PAGE_SIZE*i, 0x50000000+i*2048, size); rest -= size; if(rest == 0) return; } nand_read(PAGE_SIZE*4, 0x50000000+PAGE_SIZE, rest);}
- tiny6410裸机实验第6章--------------NAND(初始化代码及NAND操作)
- tiny6410裸机实验第6章--------------NAND(初始化原理)
- tiny6410裸机实验第6章--------------NAND(初始化原理)
- tiny6410裸机实验第5章--------------DDR(初始化原理)
- tiny6410裸机实验第5章--------------DDR(初始化原理)
- tiny6410裸机实验第5章--------------DDR初始化等(代码)
- S3C2440裸机实验(6) ----NAND FLASH
- tiny6410裸机实验第5章--------------DDR(代码)
- tiny6410裸机实验第7章--------------异常(代码)
- tiny6410裸机实验第8章--------------中断(原理及代码)
- tiny6410裸机实验第10章--------------PWM定时器(原理及代码)
- tiny6410裸机实验第11章--------------蜂鸣器(原理及代码)
- tiny6410裸机实验第2章--------------点亮LED灯(原理和代码分析)
- tiny6410裸机实验第3章--------------系统时钟(代码分析)
- tiny6410裸机实验第5章--------------DDR(代码重定位)
- tiny6410裸机实验第5章--------------DDR(代码重定位)
- tiny6410裸机实验第9章--------------LCD(原理及源代码)
- tiny6410裸机实验第4章--------------UART(原理分析)
- mysql索引原理和优化相关介绍
- iOS图片拉伸技巧
- 二进制、八进制、十进制、十六进制之间转换
- 回文数判断
- java中重载与重写的区别
- tiny6410裸机实验第6章--------------NAND(初始化代码及NAND操作)
- 线性表——顺序存储结构
- 杭电ACM 1205 吃糖果
- Pat(Basic Level)Practice--1025(反转链表)
- RTEMS CPU 架构增补
- jni/opencv2/core/core.cpp:5:20: error: No such file or directory
- "0x%08x"?
- 数据库sharding(scale up to scale out)
- 一次面试的经过