【原创连载】JZ2440学习笔记3-移植u-boot-2015.04支持jz2440的Nand

BloomW 2015-05-16 07:07:44
加精
JZ2440学习笔记

Chili

2015.5

第三部分,移植uboot2015支持JZ2440的nand flash
6,修改uboot支持nand flash
与nor flash的初始化类似,nand flash初始化在文件u-boot-2015.04-rc4\u-boot-2015.04-rc4-my2440\arch\arm\lib\Board.c 中的函数void board_init_r(gd_t *id, ulong dest_addr)中的nand_init()中进行,用sourceInsight一路跟踪代码,发现最后调用了S3c2410_nand.c (u-boot-2015.04-rc4\u-boot-2015.04-rc4-my2440\drivers\mtd\nand)对nand进行初始化,那么本次我们就需要修改此文件。
6.1 修改S3c2410_nand.c 寄存器偏移宏定义
book@book-desktop:~/uboot/u-boot-2015.04-rc4$ vim drivers/mtd/nand/s3c2410_nand.c
因为,S3C2440和2410的nand控制器有些区别,时序设置需要多设置一个寄存器,而且寄存器偏移不一致,因此添加如下图所示的宏定义,添加:
#define S3C2440_ADDR_NALE 12
#define S3C2440_ADDR_NCLE 8
#define S3C2440_NFCONT_nFCE (1<<1)

图 1

6.2修改board_nand_init函数设置时序
由于2440的nand控制寄存器与2410有区别,所以要做修改:
tacls = 0;
twrph0 = 4;
twrph1 = 2;
...
writel(((tacls<<12) | (twrph0<<8)|(twrph1<<4)), &nand_reg->nfconf);
writel((1<<0)|(0<<1)|(1<<4), &nand_reg->nfcont);

图 2

6.3修改s3c24x0_hwcontrol函数
Uboot的nand驱动最重要的就是这个函数了,它实现了nand读写的最底层控制,此处修改不当直接导致nand驱动不起来,因此需要特别注意。修改如下:
#if defined(CONFIG_S3C2410)
if (ctrl & NAND_NCE)
writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
&nand->nfconf);
else
writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
&nand->nfconf);
#elif defined(CONFIG_S3C2440)
if (ctrl & NAND_NCE)/* modified by chili, 2440*/
writel(readl(&nand->nfcont) & ~S3C2440_NFCONT_nFCE,
&nand->nfcont);
else
writel(readl(&nand->nfcont) | S3C2440_NFCONT_nFCE,
&nand->nfcont);
#endif


图 3
6.4编译烧写
book@book-desktop:~/uboot/u-boot-2015.04-rc4$ make
编译成功,烧写启动,打印如下,说明nand驱动成功。至此就可以使用nand命令进行操作flash了


图 4
6.5 解决nand write失败
经过上面一番更改,我们已经可以使用uboot自带的一些nand操作指令了,下面我们就来测试下效果如何,nand命令网上非常多资料,这种东西就可自行百度了解,其实百度上的都是别人看uboot后发上去的,那我们都可以自己看uboot帮助信息的,直接:
SMDK2410 # nand

图 5

帮助信息,说的很清楚哦,也别啥事都想到百度,自己可以想想想,解决看看。
先试试擦除,再nand dump 看下flash内数据:
SMDK2410 # nand erase 100000 100000
SMDK2410 # nand dump 100000
显示如下说明erase成功:

图 6

我们准备将内存30000000数据烧写进nand中,事先先看看内存中的数据是什么,等下好对比:
SMDK2410 # md 30000000

图 7

万事具备,开始烧写nand:
SMDK2410 # nand write 300000 100000 100000
SMDK2410 # nand dump 100000

图 8


咦?明明显示写入成功,为何数据还是FF,这说明数据压根都没写进去啊,多写几次还是如此,怎么回事啊?难道uboot有问题?放心这一般不可能,一定是你自己底层驱动写的有问题。先让我们理一理我们干了什么,忘了的童孩可以把6.1-6.3节重新复习遍:
6.1 设置S3C2440寄存器偏移和片选宏。
分析:可以读,但是写不进去,这里应该没问题,否则绝对无法读取数据的。
6.2 设置nand操作时序。
分析:还是那个原理,读数据都可以,说明读时序没问题,那么是不是写时序有问题?有可能,去检查设置时序和韦老师给的uboot1.6中nand 操作时序,发现一致,说明时序肯定也没问题。
6.3 修改s3c24x0_hwcontrol底层命令控制函数
刚说这个函数很重要,是上层操作nand函数的最底层函数,ok,我们仔细看看,是不是哪里疏忽了:

图 9


在最后,添加IO_W的默认寄存器指向。

图 10

保存编译烧写,启动,测试:
SMDK2410 # nand erase 100000 100000
SMDK2410 # nand dump 100000
SMDK2410 # nand write 30000000 100000 100000
SMDK2410 # nand dump 100000
擦除后数据:


图 11


Ok,写入成功!至此,nand flash驱动工作完全正常!
...全文
5543 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
名字很费劲 2016-02-24
  • 打赏
  • 举报
回复
引用 10 楼 CSDNHYM 的回复:
楼主最后一个添加IO_W的默认寄存器指向解决了困扰我很久的问题,就是不明白,为什么要加一个else呢,这样就是在 cmd = NAND_CMD_NONE时才令chip->IO_ADDR_W = (void *)&(nand->nfdata); 不加else 每次都将chip->IO_ADDR_W还原成 (void *)&(nand->nfdata),但我试了,不加else不行,这里有点想不通,望解答
这里你要认真看看 nand_command_lp 这个函数 你就会明白了 在这个函数中会多次调用s3c24x0_hwcontrol 你要注意chip->IO_ADDR_W = (void *)IO_ADDR_W; 这句话是在 if (ctrl & NAND_CTRL_CHANGE) 这个条件下的,不是每次进入都会满足这个条件 在nand_command_lp 中 退出前会调用 chip->cmd_ctrl(mtd, NAND_CMD_NONE, …………);
匠_心 2016-01-18
  • 打赏
  • 举报
回复
楼主最后一个添加IO_W的默认寄存器指向解决了困扰我很久的问题,就是不明白,为什么要加一个else呢,这样就是在 cmd = NAND_CMD_NONE时才令chip->IO_ADDR_W = (void *)&(nand->nfdata); 不加else 每次都将chip->IO_ADDR_W还原成 (void *)&(nand->nfdata),但我试了,不加else不行,这里有点想不通,望解答
tracy760 2015-07-16
  • 打赏
  • 举报
回复
不错 !!!
程序员鼓励师 2015-07-05
  • 打赏
  • 举报
回复
qq_29524801 2015-07-03
  • 打赏
  • 举报
回复
支持了!!!!!!!!!!!!!!!!!!
bob76012 2015-07-01
  • 打赏
  • 举报
回复
写的很好
laoer_2002 2015-06-30
  • 打赏
  • 举报
回复
学习谢谢楼主分享
提后在 2015-06-25
  • 打赏
  • 举报
回复
我就看看,不说话。
_明月 2015-06-24
  • 打赏
  • 举报
回复
感觉此贴技术很牛,收藏一下,哈哈。
曹大夯 2015-06-24
  • 打赏
  • 举报
回复
写得很详尽,学习了!

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧