Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198075
  • 博文数量: 28
  • 博客积分: 197
  • 博客等级: 入伍新兵
  • 技术积分: 291
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-18 14:10
文章分类

全部博文(28)

文章存档

2013年(11)

2012年(17)

分类: 嵌入式

2012-04-18 14:22:57

    由于NandFlash硬件升级比较快,公司去年一直在使用三星的K9GAG08U0D,现在MLC NandFlash 升级到了第二代,K9GAG08U0D 很快就会处在停产的状态,未雨绸缪,公司选型了K9GAG08U0E 来替代原有的NandFlash芯片。起初。本以为把新Nandflash ID信息增加到Uboot 和 Linux内核的NandFlash ID 列表文件中即可,也就是Uboot 和Linux源码中的nand_ids.c 文件中,但是仔细看了 K9GAG08U0E 的DataSheet,发现自己的想法错了。

下面记录了NandFlash更换时面临的几个问题,及解决方法:

第一个问题:ID 冲突

  K9GAG08U0E 的 Product ID与 K9GAG08U0D 的Product ID 是相同的,都是 0xd5,而在Uboot 代码和Linux内核代码中,是根据ID信息来获取或者计算NandFlash的页大小和块大小这些关键信息的。

 现在这两款的 Flash ID相同,而Page,OOB ,Block大小都是不同的。 K9GAG08U0D  Page,OOB,Block 关键参数:




 


而K9GAG08U0E 的 Page,OOB,Block  关键参数:




可见他们是不同的,U0E 每页大小是U0D的两倍。

针对相同ID的两款不同Flash是怎样区分的呢?仔细看DataSheet,发现了可以快速区分两种设备的方法:


U0D Page=4K,U0D Page=8K,我们只需判断Read第四个字节的第0位和第1位即可。

下面列出关键代码段:


     //这里必须有下面两行代码,因为U0E的DataSheet要求系统上电后第一条指令必须是NAND_CMD_RESET,而U0D没有这要求,如果不发送这条指令是无法读取到NandFlash的任何信息的,因为这个问题查找了很长时间,在这里提醒给大家。

     // K9GAG08U0E must add below codes     

       {
          s3c_nand_hwcontrol(0, NAND_CMD_RESET, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
          s3c_nand_device_ready(0);
        }


        s3c_nand_hwcontrol(0, NAND_CMD_READID, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
        s3c_nand_hwcontrol(0, 0x00, NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE);
        s3c_nand_hwcontrol(0, 0x00, NAND_NCE | NAND_ALE);
        s3c_nand_hwcontrol(0, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);


        s3c_nand_device_ready(0);
       tmp = readb(nand->IO_ADDR_R); /* Maf. ID */

      //  printf("Manufactor ID:%x\n",tmp);
       tmp = dev_id = readb(nand->IO_ADDR_R); /* Device ID */


        //printf("dev_id ID:%x \n",dev_id);
     for (i = 0; nand_flash_ids[i].name != NULL; i++) 

     {
        if (tmp == nand_flash_ids[i].id) {
        type = &nand_flash_ids[i];
       break;
    }

      nand->cellinfo = readb(nand->IO_ADDR_R);/* 3rd byte */
     tmp = readb(nand->IO_ADDR_R);/* 4th byte */

     int childType=tmp & 0x03; //Page size
     //  printf("dev_id=%x,childType=%x \n",dev_id,childType);

    if(dev_id == 0xd5 && childType==0x01) //U0D

    {   

    }else  if(dev_id == 0xd5 && childType==0x02) //U0E

   {


    }

这样针对不同的NandFlash做不同的初始化了,以上代码来自uboot1.1.6/cpu/s3c64xx/nand.c 文件中的void board_nand_init(struct nand_chip *nand) 函数。

阅读(4846) | 评论(3) | 转发(3) |
给主人留下些什么吧!~~

MicrochipEmbed2012-05-14 14:09:51

yuemin3: 6410和U0E是不兼容的,校验算法得软件算。
另外oob缓冲区在kernel源码中定义得也不够大.....
yuemin3 朋友能不能留下联系方式,可以共同深入探讨。

MicrochipEmbed2012-05-14 14:07:56

校验算法如果用软件计算那么工作效率会很低的,oob缓冲区不需要足够的大,能容得下校验数据即可。
K9GAG08U0E适合1KBytes/12 bit 硬件ECC校验,而6410 最大支持 512 Bytes/8 bit 硬件ECC校验,如果是工业级别产品,个人建议还是在6410芯片上使用K9GAG08U0D 2G Nandflash,采用(512 Bytes/8 bit) 硬件ECC校验算法.

yuemin32012-05-03 10:57:56

6410和U0E是不兼容的,校验算法得软件算。
另外oob缓冲区在kernel源码中定义得也不够大