5622|10

75

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求助NandFlash写驱动的问题 [复制链接]

能读进去,写却怎么也写不进去
使用的芯片是S3c2440+k9f1208
哪位帮我好好看看吧!

代码如下

  1. /* NAND Flash registers 2440*/
  2. #define NFCONF    (*(volatile unsigned int *)0x4e000000)
  3. #define NFCONT    (*(volatile unsigned int *)0x4e000004)
  4. #define NFCMD    (*(volatile unsigned char *)0x4e000008)
  5. #define NFADDR    (*(volatile unsigned char *)0x4e00000c)
  6. #define NFDATA    (*(volatile unsigned char *)0x4e000010)
  7. #define NFSTAT    (*(volatile unsigned char *)0x4e000020)
  8. #define NFMECC0        (*(volatile unsigned *)0x4E00002C)
  9. #define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))
  10. #define NAND_CHIP_DISABLE (NFCONT |= (1<<1))
  11. #define NAND_CLEAR_RB (NFSTAT |= (1<<2))
  12. #define NAND_DETECT_RB { while(! (NFSTAT&(1<<0)) );}
  13. /* 在第一次实用NAND Flash前,复位一下NAND Flash */
  14. #define BUSY 1
  15. #define        EnNandFlash()        (NFCONT |= 1)
  16. #define        DsNandFlash()        (NFCONT &= ~1)
  17. #define        NFChipEn()                (NFCONT &= ~(1<<1))
  18. #define        NFChipDs()                (NFCONT |= (1<<1))
  19. #define        InitEcc()                (NFCONT |= (1<<4))
  20. #define        MEccUnlock()        (NFCONT &= ~(1<<5))
  21. #define        MEccLock()                (NFCONT |= (1<<5))
  22. #define        SEccUnlock()        (NFCONT &= ~(1<<6))
  23. #define        SEccLock()                (NFCONT |= (1<<6))

  24. #define        WrNFDat8(dat)        (NFDATA = (dat))
  25. #define        WrNFDat32(dat)        (NFDATA = (dat))
  26. #define        RdNFDat8()                (NFDATA)        //byte access
  27. #define        RdNFDat32()                (NFDATA)        //word access

  28. #define        WrNFCmd(cmd)        (NFCMD = (cmd))
  29. #define        WrNFAddr(addr)        (NFADDR = (addr))
  30. #define        WrNFDat(dat)        WrNFDat8(dat)
  31. #define        RdNFDat()                RdNFDat8()        //for 8 bit nand flash, use byte access

  32. #define        RdNFMEcc()                (NFMECC0)        //for 8 bit nand flash, only use NFMECC0
  33. #define        RdNFSEcc()                (NFSECC)        //for 8 bit nand flash, only use low 16 bits

  34. #define        RdNFStat()                (NFSTAT)
  35. #define        NFIsBusy()                (!(NFSTAT&1))
  36. #define        NFIsReady()                (NFSTAT&1)
  37. #define        READCMD0        0
  38. #define        READCMD1        1
  39. #define        READCMD2        0x50
  40. #define        ERASECMD0        0x60
  41. #define        ERASECMD1        0xd0
  42. #define        PROGCMD0        0x80
  43. #define        PROGCMD1        0x10
  44. #define        QUERYCMD        0x70
  45. #define        RdIDCMD                0x9
  46. #define BUSY 1


  47. #define NAND_SECTOR_SIZE 512
  48. #define NAND_BLOCK_MASK  (NAND_SECTOR_SIZE - 1)

  49. /*
  50. inline void wait_idle(void)
  51. {
  52.     while(!(NFSTAT & BUSY));
  53.     NFSTAT |= BUSY;
  54. }
  55. */


  56. void reset_nand(void)
  57. {
  58. //int i=0;
  59. // NFCONF &= ~0x800;
  60. //     for(; i<10; i++);

  61. NFCONF = 0x1400;
  62. NFCONT = 0x73;

  63. NAND_CHIP_ENABLE;

  64. NFCMD = 0xff; //reset command

  65. while(!(NFSTAT & BUSY));
  66.     NFSTAT |= BUSY;
  67. }

  68. /* 初始化NAND Flash */

  69. void init_nand(void)
  70. {

  71. NFCONT = 0x73;
  72. NAND_CHIP_DISABLE;
  73. reset_nand();
  74. }



  75. static unsigned int WaitNFBusy(void)        // R/B 未接好?
  76. {
  77.         unsigned char stat;
  78.        
  79.         WrNFCmd(QUERYCMD);
  80.         do {
  81.                 stat = RdNFDat();
  82.                 //Uart_Printf("%x\n", stat);
  83.         }while(!(stat&0x40));
  84.         WrNFCmd(READCMD0);
  85.         return stat&1;
  86. }
  87. /* low level nand read function */
  88. int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
  89. {
  90.     int i, j;

  91.     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
  92.         return -1; /* invalid alignment */
  93.     }

  94.     NAND_CHIP_ENABLE;

  95.     for(i=start_addr; i < (start_addr + size);) {
  96.         /* READ0 */
  97.         NAND_CLEAR_RB;
  98.         NFCMD = 0;

  99.         /* Write Address */
  100.         NFADDR = i & 0xff;
  101.         NFADDR = (i >> 9) & 0xff;
  102.         NFADDR = (i >> 17) & 0xff;
  103.         NFADDR = (i >> 25) & 0xff;

  104.         NAND_DETECT_RB;

  105.         for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
  106.             *buf = (NFDATA & 0xff);
  107.             buf++;
  108.         }
  109.     }
  110.     NAND_CHIP_DISABLE;
  111.     return 0;
  112. }

  113. #if 1
  114. int nand_write_ll(unsigned char *buf, unsigned long start_addr, int size)
  115. {
  116.         unsigned long i, j , k, mecc;
  117.         unsigned char stat, tmp[7];
  118.        
  119.         k = size/512;
  120.         for( i= 0; i
  121.         {

  122.         NFChipEn();
  123.         WrNFCmd(PROGCMD0);
  124.         NFADDR = start_addr & 0xff;
  125.         NFADDR = (start_addr >> 9) & 0xff;
  126.         NFADDR = (start_addr >> 17) & 0xff;
  127.         NFADDR = (start_addr >> 25) & 0xff;
  128. //        WrNFAddr(start_addr>>16);
  129.         InitEcc();        //reset mecc and secc
  130.         MEccUnlock();
  131.         for(j=0; j<512; j++, start_addr++){
  132.                 WrNFDat(buf[i*512 + j]);
  133.                 uart_printf("%x ", buf[i*512 + j]);
  134.         }
  135.         MEccLock();
  136.        
  137.         mecc = RdNFMEcc();
  138.                
  139.         tmp[0] = mecc&0xff;
  140.            tmp[1] = (mecc>>8)&0xff;
  141.            tmp[2] = (mecc>>16)&0xff;
  142.             tmp[3] = (mecc>>24)&0xff;
  143.             tmp[5] = 0xff;        //mark good block
  144.    
  145.            SEccUnlock();
  146.         WrNFDat(tmp[0]);
  147.         WrNFDat(tmp[1]);
  148.         WrNFDat(tmp[2]);
  149.         WrNFDat(tmp[3]);
  150.         SEccLock();
  151.         WrNFDat(tmp[4]);
  152.         WrNFDat(tmp[5]);
  153.            
  154.         WrNFCmd(PROGCMD1);
  155.         stat = WaitNFBusy();
  156.         NFChipDs();
  157.         }

  158.         return 0;
  159. }

  160. #endif

  161. #if 0
  162. int nand_write_ll(unsigned char *buf, unsigned long start_addr, int size)
  163. {
  164.         int i, j,k,n;

  165.         if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
  166.         return -1; /* invalid alignment */
  167.         }
  168.         j = (start_addr>>11);
  169.         k = (size/NAND_SECTOR_SIZE);

  170.         NAND_CHIP_ENABLE;

  171.         for(i =j; i
  172.         {
  173.                 NAND_CLEAR_RB;
  174.                 NFCMD = 0x80;

  175.                 /* Write Address */
  176.                 NFADDR = 0x00;
  177.                 NFADDR = 0x00;
  178.                 NFADDR = (i) & 0xff;
  179.                 NFADDR = (i >> 8) & 0xff;
  180.                 NFADDR = (i >> 16) & 0xff;

  181.                 for(n=0; n < NAND_SECTOR_SIZE; n++)
  182.                 {
  183.                 NFDATA= 0x50;
  184.                 buf++;
  185.                 }
  186.                 for(#define NFCONF    (*(volatile unsigned int *)0x4e000000n=0; n<64; n++)
  187.                 {
  188.                         NFDATA=0xff;
  189.                 }
  190.                 NFCMD=0x10;
  191.                 NAND_DETECT_RB;

  192.                 NFCMD =0x70;
  193.                 for(n=0;n<10;n++);
  194.                         if(NFDATA&0x01)
  195.                                 return -1;
  196.         }
  197.         NAND_CHIP_DISABLE;
  198.         return 0;
  199. }
  200. #endif

  201. void copy_myself(void)
  202. {
  203.         unsigned char *buf = ((unsigned char *)0x33f00000);
  204.         unsigned long start_addr = 0;
  205.         int size = 0x20000;
  206.        
  207.         reset_nand();
  208.         init_nand();
  209.         nand_read_ll(buf,start_addr,size);
  210.        
  211. }

复制代码

最新回复

学习了  详情 回复 发表于 2010-1-5 16:01
点赞 关注

回复
举报

59

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
建议楼主 把对应的硬件原理图贴出来,这样大家先帮你确认下 硬件的链接是否存在问题;

 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
看下硬件原理图,还有看看写命令时序对不对
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

4
 
板子又不是我焊的,我这是三星的成品,硬件不会出问题的啊
对时序这块我不懂
~~
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

5
 
如果对时序不懂就找三星的源代码参考一下。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

6
 
我的可以搞啊,S3C2410的板子,nand也是k9f1208
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

7
 
别的不说你写的时候第一步就错了。你k9f1208上面写的是什么?
要写先擦除。擦除是一块为单位,而写的时候,你要以页为单位。
1、先写一个擦除源码

  1. int NF_EraseBlock(unsigned int block)
  2. {
  3.        unsigned int blockPage;
  4.        unsigned char data;
  5.       
  6.        blockPage=(block<<5);
  7.        NF_nFCE_L();
  8.        NF_CMD(NAND_CMD_ERASE1);                        //发出擦除命令
  9.        NF_ADDR(blockPage&0xff);
  10.        NF_ADDR((blockPage>>8)&0xff);
  11.        NF_ADDR((blockPage>>16) & 0xff);
  12.        NF_CMD(NAND_CMD_ERASE2);                        //确认并开始擦除
  13.        NF_WAITRB();                                    //等待状态查询命令
  14.       
  15.        NF_CMD(NAND_CMD_STATUS);                        //发出状态查询命令
  16.        data=NF_RDDATA();
  17.        NF_nFCE_H();
  18.        return !(data & 1);                             //data=0:擦除成功 data=1:擦除失败
  19. }
复制代码

2、写的时候你必须以页为单位进行,这是芯片编程的需要。你的有效数据写完之后,还要把最后的16位校验位要写上,这个你可以参照芯片文档,也可以写入0xFF。
需要额外说明的是,
1、读写时序你不用对我们搞软件的可以不予理会,那个是写给做硬件的人看的,你只要命令字正确,时序就对了。
2、你读的时候,也没对齐,我没试过,不过感觉你读出来的数据可能不是你要的。读的时候分了前半页和后半页。如果你从127个字节后读,你的命令字应是NFCMD = 1;
还有什么不明白的可以联系我,嘿嘿,我这个模块记忆很深的。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

8
 
路过,以后有时间再看。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

9
 
学习了
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

10
 
这样问问题太过分了,首先,这里大多数会用nandflash的人可能都没用过这款芯片,你至少要贴个datasheet时序上来看看,还有,你说你能读,你连写都写不进去,怎么读出来的,怎么判断读出来的对不对,回楼上,很多nandflash芯片自己内部有擦除功能,只要调用写,内部会先擦除,所以有时候并不一定要软件擦除再写。
 
 
 

回复

45

帖子

0

TA的资源

一粒金砂(初级)

11
 
学习了
 
 
 

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

开源项目 更多>>
    随便看看
    查找数据手册?

    EEWorld Datasheet 技术支持

    相关文章 更多>>
    关闭
    站长推荐上一条 1/10 下一条

     
    EEWorld订阅号

     
    EEWorld服务号

     
    汽车开发圈

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表