NandFlash操作详解(三)
2015-07-20 09:48
302 查看
代码正确性验证:
验证代码的正确性可以使用先写入特定字符,然后在读出来的方法验证。实验板:MINI2440 256M
首先下载一个可用的u-boot到NorFlash中,用于查看NandFlash中的数据。
然后以NorFlash启动进入u-boot,使用tftp工具或者其他工具把测试程序下载到NandFlash的0地址。以NandFlash启动查看测试结果。
测试文件main.c: int xboot_main() { int num = 0; int a = 1; int b = 2; char buf[2048] = {"hello NandFlash"}; char buf2[2048] = {}; uart_init(); printf("start nandflash read/write\n\r"); NF_Erase(0x32345); NF_WritePage(0x32345,buf); NF_PageRead(0x32345,buf2); printf("\n\n%s\n\r",buf2); while(1) { printf("\n***************************************\n\r"); printf("\n****************XBOOT*****************\n\r"); printf("1:Download Linux Kernel from TFTP Server!\n\r"); printf("2:Boot Linux from RAM!\n\r"); printf("3:Boot Linux from Nand Flash!\n\r"); printf("\n Plese Select:"); scanf("%d",&num); switch (num) { case 1: //tftp_load(); break; case 2: //boot_linux_ram(); break; case 3: //boot_linux_nand(); break; default: printf("Error: wrong selection!\n\r"); break; } } return 0; } |
完整的nand.c文件: #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; } |
使用到的命令: tftp 30000000 xboot.bin; nand erase 0 10000; nand write 30000000 0 10000 下载成功后把把拨码开关拨到Nand启动,使用命令: reset |
可以看到NandFlash已经能正常写入并读取了,安全起见,再来使用u-boot查看一下NandFlash中的情况:
以Nor启动进入u-boot: nand read 33000000 0x32000 10000; md.b 33000000 100 回车 回车 回车 回车,可以看到: |
这就完全可以清晰的看到NandFlash中的值了。
移植u-boot的过程中,为了实现NandFlash启动会使用一段实现u-boot.bin从NandFlash拷贝到SDRAM的代码,学习完上述NandFlash的操作再去看那段代码就没有任何难度了。
完整工程下载地址:http://download.csdn.net/detail/doccode/8914847
使用到的u-boot.bin下载地址:http://download.csdn.net/detail/doccode/8914859
相关文章推荐
- NandFlash操作详解(一)
- NandFlash操作详解(二)
- 用户用浏览器访问一个网站的时候具体的过程与步骤
- 简单的电话拨打
- PAT (Basic Level) Practise (中文)1018. 锤子剪刀布 (20)
- java之XML解析(Dom及Sax)
- Android 内存溢出问题
- Matlab中transpose函数的使用
- UVa 740 - Baudot Data Communication Code
- U盘杀毒专家3.21 官方最新版已破解
- AVFoundation视频播放、存储原理分析与使用
- Xcode7 真机调试步骤以及遇到的问题解决办法
- thinkphp复合WHERE查询的写法
- hdu 1071 The area
- Oracle ltrim() rtrim() 函数详细用法
- FLAG_ACTIVITY_BROUGHT_TO_FRONT与FLAG_ACTIVITY_REORDER_TO_FRONT区别
- UIApplication深入研究
- 苹果审核状态
- Python命令行参数
- php生成随机颜色代码