OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3337|回复: 4

请教下,你们的nand flash 的历程能否移植到 16位的 nand flash上啊, ??

[复制链接]

260

主题

810

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1898
金钱
1898
注册时间
2012-10-28
在线时间
357 小时
发表于 2016-11-16 09:49:14 | 显示全部楼层 |阅读模式
2金钱


请教下,你们的 nand flash 的历程能否移植到 16位的 nand flash上啊, ??

如果可以,需要注意哪些东东啊 ????

最佳答案

查看完整内容[请看2#楼]

能,把底层驱动改好,其实就是数据的读写,如果数据读写正常的话应用层的代码基本都是一样的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2016-11-16 09:49:15 | 显示全部楼层
能,把底层驱动改好,其实就是数据的读写,如果数据读写正常的话应用层的代码基本都是一样的
回复

使用道具 举报

260

主题

810

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1898
金钱
1898
注册时间
2012-10-28
在线时间
357 小时
 楼主| 发表于 2016-11-16 16:51:26 | 显示全部楼层
本帖最后由 hpdell 于 2016-11-16 16:54 编辑
zuozhongkai 发表于 2016-11-16 10:19
能,把底层驱动改好,其实就是数据的读写,如果数据读写正常的话应用层的代码基本都是一样的

目前貌似改乱了啊,不改之前,还可以显示出好坏块,改成16位后,识别的都是错误的块,

u8 NAND_ReadPage(u32 PageNum,u16 ColNum,u8 *pBuffer,u16 NumByteToRead)
{
  u16 i=0;
  u8 res=0;
  u8 eccnum=0;
目前貌似改乱了啊,不改之前,还可以显示出好坏块,改成16位后,识别的都是错误的块,

u8 NAND_ReadPage(u32 PageNum,u16 ColNum,u8 *pBuffer,u16 NumByteToRead)
{
  u16 i=0;
  u8 res=0;
  u8 eccnum=0;                //需要计算的ECC个数,每NAND_ECC_SECTOR_SIZE字节计算一个ecc
  u8 eccstart=0;                //第一个ECC值所属的地址范围
  u8 errsta=0;
  u8 *p;

  *(vu8*)(NAND_ADDRESS|NAND_CMD) = NAND_AREA_A;

  //发送地址
  *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)ColNum;
  *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)(ColNum>>8);
  *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)PageNum;
  *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)(PageNum>>8);
  *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)(PageNum>>16);
  *(vu8*)(NAND_ADDRESS|NAND_CMD)  = NAND_AREA_TRUE1;
  //下面两行代码是等待R/B引脚变为低电平,其实主要起延时作用的,等待NAND操作R/B引脚。因为我们是通过
  //将STM32的NWAIT引脚(NAND的R/B引脚)配置为普通IO,代码中通过读取NWAIT引脚的电平来判断NAND是否准备
  //就绪的。这个也就是模拟的方法,所以在速度很快的时候有可能NAND还没来得及操作R/B引脚来表示NAND的忙
  //闲状态,结果我们就读取了R/B引脚,这个时候肯定会出错的,事实上确实是会出错!大家也可以将下面两行
  //代码换成延时函数,只不过这里我们为了效率所以没有用延时函数。
  res = NAND_WaitRB(0);                        //等待RB=0
  if(res)
  {
    #if  NAND_FLASH_DEBUG_SWITCH > 0U

    printf("NAND Wait 0 Error ?? \r\n");   
    #endif
    return NSTA_TIMEOUT;        //超时退出
  }

  //下面2行代码是真正判断NAND是否准备好的
  res = NAND_WaitRB(1);                        //等待RB=1
  if(res)
  {
    #if  NAND_FLASH_DEBUG_SWITCH > 0U

    printf("NAND Wait 1 Error ?? \r\n");   
    #endif  

    return NSTA_TIMEOUT;        //超时退出
  }

  if(NumByteToRead % NAND_ECC_SECTOR_SIZE)//不是NAND_ECC_SECTOR_SIZE的整数倍,不进行ECC校验
  {
    //读取NAND FLASH中的值
    for(i=0;i<NumByteToRead;i++)
    {
      *(vu8*)pBuffer++ = *(vu8*)NAND_ADDRESS;    //  我吧这个 vu8 改成 vu16, u8 *pBuffer 这个定义的也改成了u16类型,其他没有改动,另外就是我需要读取的数据量 / 2 ,
                                                                       // 结果就不对了,也不知道是不是我的硬件
                                                                       // 上有两个 引脚没有接电源,根据资料要求,16位的39脚接 vcc,48脚接gnd,搞硬件时忘记了接,芯片型号
                                                                       // MT29F4G16ABAEAWP     TSOP48 封装的
    }
  }
  else
  {
    eccnum    = NumByteToRead / NAND_ECC_SECTOR_SIZE;                        //得到ecc计算次数
    eccstart  = ColNum/NAND_ECC_SECTOR_SIZE;
    p         = pBuffer;
    for(res=0;res<eccnum;res++)
    {
      FMC_Bank3->PCR |= 1<<6;                                                //使能ECC校验
      for(i=0;i<NAND_ECC_SECTOR_SIZE;i++)                                //读取NAND_ECC_SECTOR_SIZE个数据
      {
        *(vu8*)pBuffer++ = *(vu8*)NAND_ADDRESS;
      }               
      while(!(FMC_Bank3->SR&(1<<6)));                                //等待FIFO空        
      nand_dev.ecc_hdbuf[res+eccstart] = FMC_Bank3->ECCR;//读取硬件计算后的ECC值
      FMC_Bank3->PCR &= ~(1<<6);                                                //禁止ECC校验
    }
    i = nand_dev.page_mainsize+0X10+eccstart*4;                        //从spare区的0X10位置开始读取之前存储的ecc值

    NAND_Delay(30);//等待tADL
    *(vu8*)(NAND_ADDRESS|NAND_CMD)  = 0X05;                                //随机读指令
    //发送地址
    *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)i;
    *(vu8*)(NAND_ADDRESS|NAND_ADDR) = (u8)(i>>8);
    *(vu8*)(NAND_ADDRESS|NAND_CMD)  = 0XE0;                                //开始读数据

    NAND_Delay(30);//等待tADL
    pBuffer  = (u8*)&nand_dev.ecc_rdbuf[eccstart];
    for(i=0; i < (4 * eccnum); i++)                                                                //读取保存的ECC值
    {
      *(vu8*)pBuffer++ = *(vu8*)NAND_ADDRESS;
    }                        
    for(i=0;i<eccnum;i++)                                                                //检验ECC
    {
      if(nand_dev.ecc_rdbuf[i+eccstart] != nand_dev.ecc_hdbuf[i+eccstart] )//不相等,需要校正
      {
        printf("err hd,rd:0x%x,0x%x\r\n",nand_dev.ecc_hdbuf[i+eccstart],nand_dev.ecc_rdbuf[i+eccstart]);
        printf("eccnum,eccstart:%d,%d\r\n",eccnum,eccstart);        
        printf("PageNum,ColNum:%d,%d\r\n",PageNum,ColNum);        
        res = NAND_ECC_Correction(p+NAND_ECC_SECTOR_SIZE*i,nand_dev.ecc_rdbuf[i+eccstart],nand_dev.ecc_hdbuf[i+eccstart]);//ECC校验
        if(res)
          errsta = NSTA_ECC2BITERR;                                //标记2BIT及以上ECC错误
        else
          errsta =  NSTA_ECC1BITERR;                                //标记1BIT ECC错误
      }
    }                 
  }
  if(NAND_WaitForReady(0x2FFFFFF) != NSTA_READY)
    errsta = NSTA_ERROR;        //失败

  return errsta;        //成功   
}

回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165538
金钱
165538
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-11-17 21:36:47 | 显示全部楼层
hpdell 发表于 2016-11-16 16:51
目前貌似改乱了啊,不改之前,还可以显示出好坏块,改成16位后,识别的都是错误的块,

u8 NAND_ReadPa ...

你底层驱动正常了没有?
不带坏款管理,标准的读写函数。,
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

260

主题

810

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1898
金钱
1898
注册时间
2012-10-28
在线时间
357 小时
 楼主| 发表于 2016-11-17 22:44:13 | 显示全部楼层
正点原子 发表于 2016-11-17 21:36
你底层驱动正常了没有?
不带坏款管理,标准的读写函数。,

我现在是吧 16bit的 nand flash 当成8位的来使用了,作为 8bit使用时貌似也没有什么问题,

如果作为16bit使用,在资料介绍里面没有找到如何开启16bit模式,貌似资料介绍的都是8bit读写的,还有 我配置数据宽度为16bit或者8bit都没有任何影响,也就是他都是按照8bit来进行读写的,

另外这个芯片 根据资料介绍 p39, p40, p34这三个引脚,如果是16bit的话,需要接电源,但是硬件只接了p34脚这一个已经到vcc上, p39(VCC), p40(GND)这两个引脚没有接,不知道是不是与这两个引脚
有关,他的引脚又那么密不好单独引线出来,所以现在就按照 8bit的操作拉倒了

,以后还是得搞8bit的好了



回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-15 16:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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