【经验与教训】Uboot的Nand Flash工作不正常的解决过程
【问题】
想要实现的Uboot中的Nand Flash的驱动,
但是在移植了USB Promer那里的,可以正常运行的,Nand Flash的初始化部分代码之后,
此处Uboot中,却无法正常工作。
【解决过程】
随着问题慢慢深入的了解之后,知道了,保证Nand Flash的条件是:
1.有电压,且正常
2.片选正确
3.Nand Flash的控制器的设置正确
4.nand flash的pin脚所用的是GPIO,所以要对GPIO设置正确
5.有clock,且在合理范围内
对应的一一去验证:
1.用万用表测量,flash所引出的pin,vdd_peri_nand,测得电压是3.29V,
在正常范围内。
2.关于片选,之前的AS3525上,是只有一个芯片,不需另外设置。
而此AS3536上,支持4片flash,有4个片选,CS0~CS3,而对应的CCU(Chip Control Unit)模块中,
有Naf(Nand Flash)的控制器,其中有关于片选的设置,
最后通过和正常的USB Promer中的代码运行所测出的片选信号相比,
此时的Uboot中的片选设置,CCU的Naf的寄存器设置也对了,片选信号测出来也是对的。
3.Nand Flash控制器中,几个主要的,和配置相关的寄存器,
Control,Config,Mode等寄存器,其值,设置也都正确了。
4.AS3536中的Naf,其硬件上的Pin脚连接,是通过复用的GPIOI,J,K,L所共同复用的,
首先要保证的是GPIO要Enable启用了,其次要将对应的位设置成Nand Flash模式
(于此对应,此些GPIO也可另外复用为Storage Card,或者就
作为默认的通用输入输出)。
并且也要对应地,在CCU的Naf寄存器中,设置对应的位,表示是GPIOI/J/K/L是Nand Flash模式。
5.要设置对应的Nand Flash的Clock的Source(源),
即Nand的Clock是从哪个Divider(AS3536有Periperal的Divider,即CCUP_DIV,0~15)送过来的,
此处设置为6,即Div0,
同时,要将此Source设置好,表示此Div的输入频率是从哪个地方来的,此处设置为PLL0,
而PLL0此处默认设置为264MHz。
根据需要的频率,设置对应的Div,比如是3,然后得到的频率就是264/(3+1)=66MHz.
以上所有要素都确保正确了,但是去调试运行,读取Nand的ID,都不正确,
说明了实际的Nand Flash没有正常工作。
因此,就开始了接下来的漫长的调试,
其中包括,在同事的帮助下,使用示波器去查看波形,
具体调试到的现象是:
Nand Flash的Pin的信号中,
片选,读信号,写信号,都工作正常,即片选信号为低,调试代码时,读操作和写操作,有对应的拉低信号;
而IO0~IO7的数据信号,ALE和CLE,都不正常,无论如何操作,都无信号变化。
在如上描述,再次去查看,确认所有设置是否正确后,结果仍是无法工作。
最后,求助负责硬件的同事,其看了之后,也觉得没有其他什么办法了,不过给了个提示,
可以去将,可以正常运行的,USB Promer中的和Nand相关的所有的寄存器配置都打印出来,
和现在不能正常运行的Uboot的Nand的那些寄存器值,想比较,看看有何区别,也许能找到问题所在。
此提示,的确非常有效,
经过添加代码,读取相关寄存器配置之后,
首先发现的是,关于Nand Flash的Clock的源,两者选择不同,
其次,在此调试过程中发现,Uboot中的Div0,其值不对,因为我已经设置进去的值是0x003004,
而打印出来的值却是0x0000001,明显不正常,
关于源的选择,Promer中选的DIV6,而Uboot中选择的是DIv0,
而且另外注意到,两者的GPIO的值也不同,然后
因此尝试把前者所有的正确的配置,
都在Uboot中添加代码,单独去在Uboot中设置一下,测试结果还是不正常。
所以,觉得应该可以排除是Clock方面的问题,
但是后来无意间想到,对于GPIO的值不同,去源码里面搜索一下,
看看在其他什么地方对这些值有改动了,因为是ccu_reset()和ccu_init()里面,
都已经将值设置好的了,不应该变化才对,而搜索源码得到的结果是,
结果是在板子初始化board_init()函数中,在ccu_reset()和ccu_init()之后,
还有另外3小段代码,对GPIO做了一些其他的动作,经调查,分别是:
(1)关闭了GPIO的I和K。
(2)打开了Storage Card的crd2和crd2H,即GPIO I和 K,即将I和K用于Storage Card模式。
(3)将GPIO的I和K对应位设置成硬件模式,现在才看出来,是给Storage Card用的。
刚开始由于没有完全看懂代码含义,只是注释掉(1)和(3),也还是不能正常工作的。
只有把这段代码都去掉,而后的关于Nand Flash硬件初始化中的那些相关设置,才能生效,
才能使Nand Flash正常工作。
也就是说,此处多余的代码,在没有用Nand Flash而只用Storage Card的时候,是正常的,
而此处要使用Nand Flash,这些代码就不能用了,否则就会关闭Nand Flash所要用到的GPIO的I,K,
因而导致这两个GPIO无法使用,所以后面的将其设置为Nand模式,也是无效的,因为本身就是关闭的了。
此时,也才注意到,上面的对应的IO0~IO7以及ALE和CLE,这些pin,Schematic图上,也正是对应着GPIO的I和K,
也就是,由于多余代码关闭了GPIOI和GPIOK,导致这些硬件上的引脚失效,因此硬件无法正常工作。
而在此时,又才注意到,原来之前的,我对于调整Nand Flash,而对Nand的clock的source的Divider调节具体的div的值,
完全是徒劳的,因为是完全看错了,把CCUV的div误以为是CCUP的div,因为再如何调节,也是无用的。
而之前一直默认的是CCUP的div0的值是0x00000001,表示是从Boot为Source,Clock是默认的24M,
而Nand Flash的Clock设置成24M,也是无法正常工作的。
综上所述,自己的错误,对代码没有完全理解,思路不开阔->没想到可以去将不不正常的设置和正常的去比较,这样就可以发现问题了,
而造成了无法独立解决问题。
【经验及教训】
1.以后要尽量直至不再犯低级的,看错代码的错误。
此次的错误,主要由于不够细心,部分因为CCU里面,以前一直只有一套Divider的,
没想到AS3536有CCUP和CCUV两套Divider,结果没注意,看错了。
2.思路要开阔,不要局限于单个程序,单个工程,要把所有相关的,能联想到的东西,都要考虑进去。
毕竟,拿正常可以使用的那些寄存器的配置,和工作不正常的相比,是有机会想到的解决问题的一种办法,
即使不能解决,也会给予很多有效的提示的。
3.对于软件代码和硬件的逻辑,还是要多看资料,多思考,加深理解。不懂,就多问懂的人。
关于如何让Nand Flash正常工作的初始化条件,也是随着逐步了解,才真正清楚的。
4.把问题的现象都有条理地整理好,以方便思考问题,解决问题。
在看了Schematic图后,注意把见到的ALE,CLE,IO0~IO7无效的现象,
整理出来写好,同时注意其就是对应着GPIO I和 GPIO K,那么很可能,是可以想到问题可能是
GPIO I和K的问题,然后去搜索代码,就容易找到那些多余的代码,找到问题所在了。
所以,以后,出了问题,把所有的现象一条条列好,然后自己观察其中联系,容易找到问题原因。
转载请注明:在路上 » 【经验与教训】Uboot的Nand Flash工作不正常的解决过程