hpdell 发表于 2016-11-16 16:56:16

nand flash 8bit 改成 16bit 读写出错 ??

目前貌似改乱了啊,不改之前,还可以显示出好坏块,改成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)
{
    #ifNAND_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)
{
    #ifNAND_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 = 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;
    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 != nand_dev.ecc_hdbuf )//不相等,需要校正
      {
      printf("err hd,rd:0x%x,0x%x\r\n",nand_dev.ecc_hdbuf,nand_dev.ecc_rdbuf);
      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,nand_dev.ecc_hdbuf);//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;      //成功   
}

xhzheng 发表于 2016-11-16 17:08:24

参数定义均修改为u16进行定义吧;

hpdell 发表于 2016-11-16 17:17:26

本帖最后由 hpdell 于 2016-11-16 17:18 编辑

xhzheng 发表于 2016-11-16 17:08
参数定义均修改为u16进行定义吧;
u8 NAND_ReadPage(u32 PageNum,u16 ColNum,u8 *pBuffer,u16 NumByteToRead)   // 这个上面的 u8 *pBuffer 也改成了16


//读取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 封装的
    }

xhzheng 发表于 2016-11-17 08:12:15

hpdell 发表于 2016-11-16 17:17
u8 NAND_ReadPage(u32 PageNum,u16 ColNum,u8 *pBuffer,u16 NumByteToRead)   // 这个上面的 u8 *pBuffer...

确保读取RFID正确后,在进行其他功能开发;

hpdell 发表于 2016-11-17 10:27:57

xhzheng 发表于 2016-11-17 08:12
确保读取RFID正确后,在进行其他功能开发;

我现在是当成8位来使用的,没有使用16bit,而且我的nand flash配置 也是8bit的,我在资料里面没有找到16bit读写的指令,也没有看到关于16bit的一些操作说明,目前使用 8bit 操作效果杠杠的,

xhzheng 发表于 2016-11-17 10:32:18

hpdell 发表于 2016-11-17 10:27
我现在是当成8位来使用的,没有使用16bit,而且我的nand flash配置 也是8bit的,我在资料里面没有找到16b ...

厉害厉害;

hpdell 发表于 2016-11-18 09:06:04

xhzheng 发表于 2016-11-17 10:32
厉害厉害;

惭愧惭愧呀,目前貌似读写块不能够超过512,不知道是怎么个情况 ??
页: [1]
查看完整版本: nand flash 8bit 改成 16bit 读写出错 ??