野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14744|回复: 16

简要分析RT1052操作NandFlash

[复制链接]
发表于 2018-7-10 23:16:31 | 显示全部楼层 |阅读模式
因为自己的板子需要用到nandflash,官方的板子是没有nandflash的,所以SDK里边,SEMC那里只有亲娘生的SDRAM才有历程,后娘养的nandflash是没有人疼爱的。
以前用STM32的芯片或者NXP自己的芯片,操作nandflash其实都是把nandflash当做外挂的比较讨人厌烦的SRAM来操作的,自己算好行列数据,一次次地发送给nandflash,第一次发C0,第二次发C1,第三次发ROW0,第四次发ROW1,第五次发ROW2,然后就开始不断地从8位数据口拿数据。
NXP的工程师,估计是看不惯别人这么欺骗nandflash,所以,在RT那里开辟了一个叫做IP命令以及AXI命令操作的方式来操作将上述的命令序列整合起来,让SEMC模块来和nandflash沟通,不需要代码一行行地去计算欺骗nandflash了。
抛砖引石头,和大家分享一下使用IP方式读取nandflash  的芯片ID。
在此感谢大神  @caiday 的帮助。
一步步来:1.初始化;2.使用IP指令;3.得到数据;
1.初始化
这部分初始化,就使用火哥SDK里边提供的nandflash的初始化,不过caiday讲,
    /* Configure NAND FLASH. */
    nandconfig.cePinMux = kSEMC_MUXCSX0;
    nandconfig.axiAddress = 0x9e000000;
    nandconfig.axiMemsize_kbytes = 128 * 1024*2; /*  W29N01GV PageSize*PageCountEachBlck*Blocks=2048*64*1024=128M B */

    nandconfig.ipgAddress = 0x9e000000;
    nandconfig.ipgMemsize_kbytes = 128 * 1024*2; /*  W29N01GV PageSize*PageCountEachBlck*Blocks=2048*64*1024=128M B */

这里要将大小翻倍,我仍旧想不明白,希望大家解答。
2.使用IP指令
1.png
手册上,49.4.5有讲,想要使用IP 命令,必须尊徐4个步骤;
uint32_t NAND_ReadID(void)
{
        uint16_t ipCmd;
        __IO uint32_t data;
        status_t result = kStatus_Success;
        uint8_t deviceid[5];
        uint32_t id;  

        SEMC_ConfigureIPCommand(SEMC, 1);
        ipCmd = SEMC_BuildNandIPCommand(NAND_READID, kSEMC_NANDAM_ColumnCA0, kSEMC_NANDCM_CommandAddress);

        result = SEMC_SendIPCommand(SEMC, kSEMC_MemType_NAND, NAND_ADDRESS, ipCmd, 0, NULL);
       
        result = SEMC_IPCommandNandRead(SEMC, NAND_ADDRESS, deviceid, 5);
       
  id=*(unsigned long *)deviceid;
    return id;
}

4行核心代码代表了4个步骤;
1.SEMC_ConfigureIPCommand(SEMC, 1);   配置指令操作的数据长度;
2.ipCmd = SEMC_BuildNandIPCommand(NAND_READID, kSEMC_NANDAM_ColumnCA0, kSEMC_NANDCM_CommandAddress);   这个其实只是组装一个命令而已,不涉及任何的操作。
3.result = SEMC_SendIPCommand(SEMC, kSEMC_MemType_NAND, NAND_ADDRESS, ipCmd, 0, NULL);   关键的地方来了,这一行代码,会将读取nandflash的ID的命令通过数据总线传送出去(除了数据还有别的吗?有啊,有读写信号。上图)
2.png
图小的话,我管不着,大家将就着看,实在看不清楚的,找别的资料再看看。
4.result = SEMC_IPCommandNandRead(SEMC, NAND_ADDRESS, deviceid, 5);   这行代码会读取5个字节的数据,传说中的5个字节的ID(真的就这么简单地到来了吗?没错,真的就这么简单地就到来了!上图,没图说个叼!)
3.png
大家没看错,能够发出数据变化,让总线有波动的其实就两个函数,这两个函数组装,就会对应了nandflash数据手册上的波形。
4.png
完了吗?好像完了,数据都读出来了,你还想怎么样?能不能再深入一点?那我们深入一点?
能深入的地方,我也只能再把SEMC_IPCommandNandRead这个函数展开了
status_t SEMC_IPCommandNandRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes)
{
    assert(data);

    status_t result = kStatus_Success;
    uint8_t dataSize = base->NANDCR0 & SEMC_NANDCR0_PS_MASK;
    uint16_t ipCmd;
    uint32_t tempData = 0;

    /* Configure IP command data size. */
    SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX);
    /* Read command built */
    ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Read);

    while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX)
    {
        result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, (uint32_t *)data);
        if (result != kStatus_Success)
        {
            break;
        }

        data += SEMC_IPCOMMANDDATASIZEBYTEMAX;
        size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX;
    }

    if ((result == kStatus_Success) && size_bytes)
    {
        SEMC_ConfigureIPCommand(base, size_bytes);
        result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, &tempData);

        while (size_bytes)
        {
            *(data + size_bytes) = (tempData >> (SEMC_BYTE_NUMBIT * (size_bytes - 1))) & 0xFFU;
            size_bytes--;
        }
    }

    SEMC_ConfigureIPCommand(base, dataSize);
    return result;
}


各位,前后对比一下,又回到了之前一开始的地方,
1.设置命令操作长度
2.组装命令
3.调用SEMC_SendIPCommand
4.完事。
再讲就啰嗦了。
有必要的话,调试读写操作的时候,再更新一波。
回复

使用道具 举报

发表于 2018-7-11 08:35:58 | 显示全部楼层
主要是校验方面不知道怎么处理
回复 支持 反对

使用道具 举报

发表于 2018-7-11 16:22:15 | 显示全部楼层
这个是好的,忘记更新到网盘了 SEMC—扩展外部NAND.rar (1.5 MB, 下载次数: 138)


回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-11 19:59:25 | 显示全部楼层
fire 发表于 2018-7-11 16:22
这个是好的,忘记更新到网盘了

火哥威武
回复 支持 反对

使用道具 举报

发表于 2018-7-11 22:27:33 | 显示全部楼层
关于你的大小翻倍的疑问解答如下:

NAND芯片里每个Page都含有一个OOB区域用于存放bad block、ecc等数据,所以如果你想访问OOB,那么必须在配置SEMC时将column地址配多1bit,因此NAND size看起来大了一倍。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-12 08:44:39 | 显示全部楼层
Henjay724 发表于 2018-7-11 22:27
关于你的大小翻倍的疑问解答如下:

NAND芯片里每个Page都含有一个OOB区域用于存放bad block、ecc等数据 ...

这样就理解了。谢谢你的回答。
回复 支持 反对

使用道具 举报

发表于 2018-12-28 19:55:04 | 显示全部楼层

和sdram一起工作,闪屏吗?
我这边遇到了闪屏问题,semc上接了sdram和nandflash,nandflash在读写的时候,闪屏
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-29 19:17:34 | 显示全部楼层
jxh 发表于 2018-12-28 19:55
和sdram一起工作,闪屏吗?
我这边遇到了闪屏问题,semc上接了sdram和nandflash,nandflash在读写的时候 ...

闪,闪成狗!
你拿示波器测一下操作SDRAM的时候的电源波形吧,特别是那个1.1V。还有,你也测一下SDRAM和LCD的数据线的波形,你会发现振铃效应特别明显。讲人话就是:信号完整性出问题了。
回复 支持 反对

使用道具 举报

发表于 2018-12-29 22:45:04 | 显示全部楼层
吕布-单片机 发表于 2018-12-29 19:17
闪,闪成狗!
你拿示波器测一下操作SDRAM的时候的电源波形吧,特别是那个1.1V。还有,你也测一下SDRAM和L ...

原先个人理解是冲突了,nandflash和sdram公用总线,这个还没有用示波器测试过,这2天确认下
另勘误手册上提到,我们的方式是IP的,应该是没有这个bug
Description:
When SEMC NAND memory region is Normal type, non-cacheable, cacheable write-through, or
writeback, non-allocate, and not hit, CM7 AXI writes to the region could program incorrect data
to the NAND memory.
Projected Impact:
CPU cannot perform AXI write to SEMC NAND memory when it is the Normal memory type.
Workarounds:
1. Set SEMC NAND memory region to Device type or Strongly-ordered type in MPU, and CPU
only perform 32-bit write to SEMC NAND memory region or;
2. Use eDMA to perform 64-bit AXI write to SEMC NAND memory region or;
3. Use IP command to program SEMC NAND memory.
Proposed Solution:
No fix scheduled
Software Status:
Software workaround is not in SDK.
回复 支持 反对

使用道具 举报

发表于 2018-12-29 22:47:37 | 显示全部楼层
吕布-单片机 发表于 2018-12-29 19:17
闪,闪成狗!
你拿示波器测一下操作SDRAM的时候的电源波形吧,特别是那个1.1V。还有,你也测一下SDRAM和L ...

这个目前打算解决的啊?
我准备换spi flash了,
回复 支持 反对

使用道具 举报

发表于 2019-1-1 10:22:14 | 显示全部楼层
上传了lcd上正常和nand操作时候的波形,

正常的波形

正常的波形

不正常的波形

不正常的波形
回复 支持 反对

使用道具 举报

发表于 2019-1-1 10:23:40 | 显示全部楼层
吕布-单片机 发表于 2018-12-29 19:17
闪,闪成狗!
你拿示波器测一下操作SDRAM的时候的电源波形吧,特别是那个1.1V。还有,你也测一下SDRAM和L ...

上传了波形,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-2 20:25:37 | 显示全部楼层
jxh 发表于 2019-1-1 10:23
上传了波形,

哈哈,你都自己回答了你的问题了。
我一开始就和你说了,要你查示波器波形,看信号振铃。
专业属于叫做信号完整性,所谓的信号完整性,就是这个信号是不是完整的,多了或者少了,都不叫完整。现在出现的这个是信号过冲了,就是不完整。
我是觉得是信号完整性问题。不过也可能是我理解错了(但是现象确实很像那么回事)
有人说,显示屏出现闪烁,是总线带宽占用导致的(当你操作NANDFLASH的时候,LCD模块也想要占用SEMC从SDRAM扣数据以及把扣到的数据放到RGB那里去,如果这个时候,nandflash对数据不放手,那么LCD就拿不到数据了),但是我并不认同总线占用。
我再经验之谈给你提个建议:你拿示波器,在显示屏那边测H、V、DE信号。
预测的现象:如果你的屏幕是拦腰截断式地闪烁的,应该是V信号受到了那些尖峰的影响。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-2 20:33:46 | 显示全部楼层
jxh 发表于 2019-1-1 10:23
上传了波形,

我之前搞这个,搞得我都快要吐血了,一操作SDRAM,LCD就闪成狗,拿火哥的板子搞就是没有问题。后面那示波器一个个测信号。
不知道你的板子是自己画的还是买火哥的。
跟spi flash 半毛钱关系没有,你就是把代码放到内部ram也是这个吊样。
我问周立功FAE,一句回复:信号干扰问题。完了,完啦?我就一句买买提。
我查了一些信号完整性的资料。听说,把管脚的边沿设置成慢速的,也许能解决问题。
不要问我怎么解决的,我要是告诉你,我换芯片了,你估计也会有这想法。
打一波广告,我已经换成STM32H7了。
所有的启动代码,下载方式,加密方式,都在片上的128K上自己做,全程无痛。
回复 支持 反对

使用道具 举报

发表于 2019-1-2 21:10:19 | 显示全部楼层
吕布-单片机 发表于 2019-1-2 20:25
哈哈,你都自己回答了你的问题了。
我一开始就和你说了,要你查示波器波形,看信号振铃。
专业属于叫做 ...

非常感谢!!
吐血中。。。。。之前还算熟悉st的芯片,第一次使用nxp的;

环境就是野火的开发板,咋感觉是总线占用的问题,但数据线的波形确实也变得不同了,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-2 21:39:10 | 显示全部楼层
jxh 发表于 2019-1-2 21:10
非常感谢!!
吐血中。。。。。之前还算熟悉st的芯片,第一次使用nxp的;

听我的。
你的示波器也是4通道的,把LCD的H   V   DE信号接上去,检测操作nandfalsh的时候,这几个信号的波形,你就恍然大悟:哦,原来他妈的不是总线占用的问题!
你会检测到LCD的H信号,会有不规则的,不正常的信号变动,但是又不是低电平,可能只是跌到了2V左右的信号。
但是,LCD就是这么敏感,它是边沿触发型的,它就是觉得那已经是一个有效的H信号了。
回复 支持 反对

使用道具 举报

发表于 2019-1-2 22:37:55 | 显示全部楼层
吕布-单片机 发表于 2019-1-2 21:39
听我的。
你的示波器也是4通道的,把LCD的H   V   DE信号接上去,检测操作nandfalsh的时候,这几个信号 ...

   非常感谢!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-22 21:01 , Processed in 0.037228 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表