×
单片机 > 单片机程序设计 > 详情

mini2440硬件篇之Nand Flash

发布时间:2020-06-06 发布时间:
|


1. 硬件原理

Nand Flash在对大容量的数据存储中发挥着重要的作用。相对于Nor Flash,它具有一些优势,但它的一个劣势是很容易产生坏块,因此在使用Nand Flash时,往往要利用校验算法发现坏块并标注出来,以便以后不再使用该坏块。Nand Flash没有地址或数据总线,如果是8位Nand Flash,那么它只有8个IO口,这8个IO口用于传输命令、地址和数据。Nand Flash主要以page(页)为单位进行读写,以block(块)为单位进行擦除。每一页中又分为main区和spare区,main区用于正常数据的存储,spare区用于存储一些附加信息,如块好坏的标记、块的逻辑地址、页内数据的ECC校验和等。

1.1. 坏块管理

由于NAND Flash的工艺不能保证NAND的Memory Array在其生命周期中保持性能的可靠,因此,在NAND的生产中及使用过程中会产生坏块。坏块的特性是:当编程/擦除这个块时,不能将某些位拉高,这会造成Page Program和Block Erase操作时的错误,相应地反映到Status Register的相应位。

(1)固有坏块,这是生产过程中产生的坏块,一般芯片原厂都会在出厂时都会将坏块第一个page的spare area的第6个bit标记为不等于0xff的值。

(2)使用坏块,这是在NAND Flash使用过程中,如果Block Erase或者Page Program错误,就可以简单地将这个块作为坏块来处理,这个时候需要把坏块标记起来。为了和固有坏块信息保持一致,将新发现的坏块的第一个page的spare area的第6个Bit标记为非0xff的值。

(3)坏块管理

根据上面的这些叙述,可以了解NAND Flash出厂时在spare area中已经反映出了坏块信息,因此,如果在擦除一个块之前,一定要先check一下spare area的第6个bit(512)或第1个bit(2k)是否是0xff,如果是就证明这是一个好块,可以擦除;如果是非0xff,那么就不能擦除。

当然,这样处理可能会犯一个错误―――“错杀伪坏块”,因为在芯片操作过程中可能由于电压不稳定等偶然因素会造成NAND操作的错误。但是,为了数据的可靠性及软件设计的简单化,我们就要奉行“蒋委员长”的“宁可错杀一千,也决不放过一个”的宗旨。

(4)需要对前面由于Page Program错误发现的坏块进行一下特别说明。如果在对一个块的某个page进行编程的时候发生了错误就要把这个块标记为坏块,首先就要把其他好的page里面的内容备份到另外一个空的好块里面,然后,把这个块标记为坏块。

当然,这可能会犯“错杀”之误,一个补救的办法,就是在进行完页备份之后,再将这个块擦除一遍,如果Block Erase发生错误,那就证明这个块是个真正的坏块,那就毫不犹豫地将它打个“戳”吧!

(2)可能有人会问,为什么要使用spare area的第六个bit作为坏块标记。这是NAND Flash生产商的默认约定。

 

2. 芯片手册

K9F2G08U0B

2.1. 特性

容量256MB

一页2k+64;一块128k+4k;

2.2. 引脚描述

见手册

2.3. 指令集

 

2.4. 读

 

2.5. 编程

 

2.6. 擦除

 

2.7. 读ID

 

 

3. mini2440电路图

4. S3C2440寄存器

4.1. 控制器特性

1、支持读/写/编程 NAND FLASH内存

2、系统复位后nand flash的前4k代码自动copy到内部sram,copy完  成后从sram启动,此时内部sram被映射为nGCS0。(当OM[1:0] = 00时使能NAND FLASH 启动模式)

3、支持硬件ECC校验

4、系统启动后内部ram可以用做其他的用途。


4.2. 操作Nand方法

1、设置nand flash配置寄存器NFCONF

2、向命令寄存器NFCMD写入操作命令

3、向地址寄存器NFADDR写入地址

4、读/写数据前要读取状态寄存器NFSTAT来判断nand flash是否处于忙状态。


4.3. ECC奇偶校验

S3C2440在读/写操作时,自动生成2048字节的奇偶校验码。

Nand Flash的页为2048B。在读写的时候每页会产生4个bit大小的ECC校验码。

28bit ECC校验码=22bit线校验码+6bit列校验码

ECC产生模块执行以下步骤:

1:当MCU写数据到NAND时,ECC产生模块生成ECC码。

2:当MCU从NAND读数据时,ECC产生模块生成ECC码同时用户程序将它与先前写入时产生的ECC码作比较。

在自动引导模式下,不进行ECC检测。因此,NAND FLASH的前4KB应确保不能有位错误(一般NAND FLASH厂家都确保)。

nand.h


  1. /******************************************************************* 

  2.  * Copyright (C),2011-2012, XXX. 

  3.  * FileName: nand.h  

  4.  * Author:HuangYinqing 

  5.  * Version:1.0 

  6.  * Date::2012-04-22 

  7.  * Description:nand flash驱动. 

  8.  * Function List: 

  9.  * History: 

  10.  ******************************************************************/  

  11.   

  12. #ifndef __NAND_H__  

  13. #define __NAND_H__  

  14.   

  15. /*nand flash调试等级*/  

  16. #define DBG_NAND_LEVEL      1  

  17.   

  18. /*nand flash信息*/  

  19. #define NAND_PAGE_SIZE      (2*1024)                //==1页2k  

  20. #define NAND_BLOCK_SIZE     (NAND_PAGE_SIZE*64)     //==1块128k  

  21. #define NAND_SIZE           (256*1024*1024)         //==容量256M  

  22.   

  23. /*操作命令*/  

  24. #define CMD_READ1                 0x00              //页读命令周期1  

  25. #define CMD_READ2                 0x30              //页读命令周期2  

  26. #define CMD_READID                0x90              //读ID命令  

  27. #define CMD_WRITE1                0x80              //页写命令周期1  

  28. #define CMD_WRITE2                0x10              //页写命令周期2  

  29. #define CMD_ERASE1                0x60              //块擦除命令周期1  

  30. #define CMD_ERASE2                0xd0              //块擦除命令周期2  

  31. #define CMD_STATUS                0x70              //读状态命令  

  32. #define CMD_RESET                 0xff              //复位  

  33. #define CMD_RANDOMREAD1           0x05              //随意读命令周期1  

  34. #define CMD_RANDOMREAD2           0xE0              //随意读命令周期2  

  35. #define CMD_RANDOMWRITE           0x85              //随意写命令  

  36.   

  37. /*NFCONF设置时序*/  

  38. #define TACLS   1  

  39. #define TWRPH0  2  

  40. #define TWRPH1  0  

  41.   

  42. /*NFCONT片选*/  

  43. #define NF_nFCE_L()                        {rNFCONT &= ~(1<<1); } //==打开片选  

  44. #define NF_nFCE_H()                        {rNFCONT |= (1<<1); }  //==关闭片选  

  45.   

  46. /*读写数据*/  

  47. #define NF_CMD(data)              {rNFCMD  = (data);}        //传输命令  

  48. #define NF_ADDR(addr)             {rNFADDR = (addr);}        //传输地址  

  49. #define NF_RDDATA()               (rNFDATA)                  //读32位数据  

  50. #define NF_RDDATA8()              (rNFDATA8)                 //读8位数据  

  51. #define NF_WRDATA(data)           {rNFDATA = (data);}         //写32位数据  

  52. #define NF_WRDATA8(data)          {rNFDATA8 = (data);}        //写8位数据  

  53.   

  54. /*NFSTAT的第0位可以用于判断nandflash是否在忙,第2位用于检测RnB引脚信号*/  

  55. #define NF_WAITRB()                {while(!(rNFSTAT&(1<<0)));}           //等待nandflash不忙  

  56. #define NF_CLEAR_RB()              {rNFSTAT |= (1<<2); }                 //清除RnB信号  

  57. #define NF_DETECT_RB()             {while(!(rNFSTAT&(1<<2)));}           //等待RnB信号变高,即不忙  

  58.   

  59. /*ECC*/  

  60. #define NF_RSTECC()                        {rNFCONT |= (1<<4); }         //复位ECC  

  61. #define NF_MECC_UnLock()                   {rNFCONT &= ~(1<<5); }      //解锁main区ECC  

  62. #define NF_MECC_Lock()                     {rNFCONT |= (1<<5); }         //锁定main区ECC  

  63. #define NF_SECC_UnLock()                   {rNFCONT &= ~(1<<6); }        //解锁spare区ECC  

  64. #define NF_SECC_Lock()                     {rNFCONT |= (1<<6); }         //锁定spare区ECC  

  65.   

  66. /*函数*/  

  67. void NandTest(void);  

  68. void NandInit(void);  

  69.   

  70. #endif   

nand.c



  1. /******************************************************************* 

  2.  * Copyright (C),2011-2012, XXX. 

  3.  * FileName: nand.h  

  4.  * Author:HuangYinqing 

  5.  * Version:1.0 

  6.  * Date::2012-04-22 

  7.  * Description:nand flash驱动. 

  8.  * Function List: 

  9.  * History: 

  10.  ******************************************************************/  

  11. #include "common.h"  

  12. #include "core.h"  

  13. #include "nand.h"  

  14.   

  15.   

  16. /******************************************************************** 

  17. 函数功能:nand flash初始化。 

  18. 入口参数:无。 

  19. 返    回:无。 

  20. 备    注:无。 

  21. ********************************************************************/   

  22. void NandInit(void)  

  23. {  

  24.     rGPACON = (rGPACON &~(0x3f<<17)) | (0x3f<<17);            //配置芯片引脚  

  25.       

  26.     /*TACLS=1、TWRPH0=2、TWRPH1=0,8位IO*/  

  27.     rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);  

  28.     /*非锁定,屏蔽nandflash中断,初始化ECC及不锁定main区和spare区ECC,使能nandflash片选及控制器*/  

  29.     rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);  

  30. }  

  31.   

  32.   

  33. /******************************************************************** 

  34. 函数功能:nand flash复位。 

  35. 入口参数:无。 

  36. 返    回:无。 

  37. 备    注:无。 

  38. ********************************************************************/   

  39. void NandReset(void)  

  40. {  

  41.     int i;  

  42.       

  43.     NF_nFCE_L();                            //打开nandflash片选  

  44.     NF_CLEAR_RB();                          //清除RnB信号  

  45.     for ( i=0; i<10; i++);  

  46.     NF_CMD(CMD_RESET);                      //写入复位命令  

  47.     NF_DETECT_RB();                         //等待RnB信号变高,即不忙  

  48.     NF_nFCE_H();                            //关闭nandflash片选  

  49. }  

  50.   

  51.   

  52. /******************************************************************** 

  53. 函数功能:nand flash读ID。 

  54. 入口参数:无。 

  55. 返    回:设备ID。 

  56. 备    注:无。 

  57. ********************************************************************/   

  58. char NandReadID(void)  

  59. {  

  60.     char pMID;  

  61.     char pDID;  

  62.     char cyc3, cyc4, cyc5;   

  63.       

  64.     NF_nFCE_L();                          //打开nandflash片选  

  65.     // NF_CLEAR_RB();                        //清RnB信号  

  66.     NF_CMD(CMD_READID);                  //读ID命令  

  67.     NF_ADDR(0x0);                         //写0x00地址  

  68.     // for ( i=0; i<10; i++);  

  69.       

  70.     //读五个周期的ID  

  71.     pMID = NF_RDDATA8();                   //厂商ID:0xEC  

  72.     pDID = NF_RDDATA8();                   //设备ID:0xDA  

  73.     cyc3 = NF_RDDATA8();                   //0x10  

  74.     cyc4 = NF_RDDATA8();                   //0x95  

  75.     cyc5 = NF_RDDATA8();                   //0x44  

  76.       

  77.     NF_nFCE_H();                              //关闭nandflash片选  

  78.   

  79.     DbgPrintX( DBG_NAND_LEVEL, "\rMID=%2x,DID=%2x,3r=%2x,4r=%2x,5r=%2x\n",pMID,pDID,cyc3,cyc4,cyc5);  

  80.   

  81.     return pDID;  

  82. }  

  83.   

  84.   

  85. /******************************************************************** 

  86. 函数功能:nand flash检查坏块。(大页2k) 

  87. 入口参数: 

  88.     ulBlockNum:待检查块索引 

  89. 返    回:1:坏块;0:好块。 

  90. 备    注:无。 

  91. ********************************************************************/   

  92. int NandIsBadBlockPage2048(U32 ulBlockNum)  

  93. {  

  94.     U32 ulPageNum;  

  95.     U8  bBadBlockFlag;  

  96.       

  97.     ulPageNum = ulBlockNum <

  98.       

  99.     NF_nFCE_L();  

  100.     NF_CLEAR_RB();  

  101.     NF_CMD(0x00);  

  102.     NF_ADDR(0);  

  103.     NF_ADDR((2048>>8)&0xff);  

  104.     NF_ADDR(ulPageNum&0xff);  

  105.     NF_ADDR((ulPageNum>>8)&0xff);  

  106.     NF_ADDR((ulPageNum>>16)&0xff);  

  107.     NF_CMD(0x30);          

  108.     NF_DETECT_RB();  

  109.   

  110.     bBadBlockFlag = NF_RDDATA8();  

  111.                

  112.     NF_nFCE_H();      

  113.   

  114.     return (bBadBlockFlag != 0xff);  

  115. }  

  116.   

  117.   

  118. /******************************************************************** 

  119. 函数功能:检查坏块。 

  120. 入口参数: 

  121.     ulBlockNum:待检查块索引; 

  122.     bIsLargerPage:1:大页;0:小页 

  123. 返    回:1:坏块;0:好块。 

  124. 备    注:无。 

  125. ********************************************************************/   

  126. int NandIsBadBlock(U32 ulBlockNum, U8 bIsLargePage)  

  127. {  

  128.     switch(bIsLargePage)   

  129.     {  

  130.         case 0:  

  131. //          return Nand_IsBadBlockPage512(ulBlockNum);  

  132.         case 1:  

  133.             return NandIsBadBlockPage2048(ulBlockNum);  

  134.     }  

  135.     return 0;  

  136. }  

  137.   

  138.   

  139.   

  140. /******************************************************************** 

  141. 函数功能:读nand flash一页数据。(大页2k) 

  142. 入口参数: 

  143.     ulPageNum:页索引 

  144.     pucBuffer:缓冲区 

  145. 返    回:成功:读取字节数 

  146. 备    注:无。 

  147. ********************************************************************/   

  148. U32 NandReadPage2048(U32 ulPageNum, U8 *pucBuffer)  

  149. {  

  150.     U32 i;  

  151.   

  152.     NF_nFCE_L();                   //打开nandflash片选  

  153.     NF_CLEAR_RB();                 //清RnB信号  

  154.       

  155.     NF_CMD(CMD_READ1);             //页读命令周期1  

  156.   

  157.     //写入5个地址周期  

  158.     NF_ADDR(0x00);                                        //列地址A0~A7  

  159.     NF_ADDR(0x00);                                        //列地址A8~A11  

  160.     NF_ADDR((ulPageNum) & 0xff);                         //行地址A12~A19  

  161.     NF_ADDR((ulPageNum >> 8) & 0xff);                  //行地址A20~A27  

  162.     NF_ADDR((ulPageNum >> 16) & 0xff);                     //行地址A28  

  163.       

  164.     NF_CMD(CMD_READ2);             //页读命令周期2  

  165.     NF_DETECT_RB();                //等待RnB信号变高,即不忙  

  166.       

  167.     //读取一页数据内容  

  168.     for (i = 0; i 

  169.     {  

  170.         *pucBuffer++ = NF_RDDATA8();  

  171.     }   

  172.       

  173.     NF_nFCE_H();                   //打开nandflash片选     

  174.     return i;  

  175. }  

  176.   

  177.   

  178. /******************************************************************** 

  179. 函数功能:读nand flash一页数据。 

  180. 入口参数: 

  181.     ulPageNum:页索引 

  182.     pucBuffer:缓冲区 

  183.     bIsLargerPage:1:大页;0:小页 

  184. 返    回:读取字节数。 

  185. 备    注:无。 

  186. ********************************************************************/   

  187. int NandReadPage(U32 ulPageNum, U8 *pucBuffer, U8 bIsLargePage)  

  188. {  

  189.     switch(bIsLargePage)   

  190.     {  

  191.         case 0:  

  192. //          return Nand_ReadSectorPage512(ulPageNum, buffer);  

  193.         case 1:  

  194.             return NandReadPage2048(ulPageNum, pucBuffer);  

  195.     }  

  196.     return 0;  

  197. }  

  198.   

  199.   

  200. /******************************************************************** 

  201. 函数功能:读nand flash数据。 

  202. 入口参数: 

  203.     ulAddr:从哪个地址读 

  204.     ulSize:要读取的字节数 

  205.     pucBuffer:缓冲区 

  206. 返    回:成功:读取字节数;其他:出错。 

  207. 备    注:无。 

  208. ********************************************************************/   

  209. int NandRead(U32 ulAddr, U32 ulSize, U8 *pucBuffer)  

  210. {  

  211.     int i, j;  

  212.   

  213.     /*检查参数*/  

  214.     if ( (ulAddr & (NAND_PAGE_SIZE-1)) || (ulSize & (NAND_PAGE_SIZE-1)) )  

  215.     {  

  216.         return ERR_PARAMETER;   /* invalid alignment */  

  217.     }  

  218.   

  219.     /*每次读一页*/  

  220.     for (i=ulAddr; i 

  221.     {  

  222.         if (i & (NAND_BLOCK_SIZE-1)== 0)  //==如果是块首,要检查坏块。  

  223.         {  

  224.             if ( NandIsBadBlock(i/NAND_BLOCK_SIZE, 1) )   

  225.             {  

  226.                 /* Bad block */  

  227.                 i += NAND_BLOCK_SIZE;  

  228.                 ulSize += NAND_BLOCK_SIZE;  

  229.                 continue;  

  230.             }  

  231.         }  

  232.           

  233.         j = NandReadPage(i/NAND_PAGE_SIZE, pucBuffer, 1);  

  234.         i += j;  

  235.         pucBuffer += j;  

  236.     }  

  237.   

  238.     return ERR_SUCCESS;  

  239. }  

  240.   

  241. /******************************************************************** 

  242. 函数功能:写nand flash一页数据。(大页) 

  243. 入口参数: 

  244.     ulPageNum:页索引 

  245.     pucBuffer:缓冲区 

  246. 返    回:成功:读取字节数 

  247. 备    注:无。 

  248. ********************************************************************/   

  249. U32 NandWritePage2048(U32 ulPageNum, U8 *pucBuffer)  

  250. {  

  251.     U32 i;  

  252.   

  253.     NF_nFCE_L();                   //打开nandflash片选  

  254.     NF_CLEAR_RB();                 //清RnB信号  

  255.       

  256.     NF_CMD(CMD_WRITE1);             //页读命令周期1  

  257.                                   //写入5个地址周期  

  258.     NF_ADDR(0x00);                                        //列地址A0~A7  

  259.     NF_ADDR(0x00);                                        //列地址A8~A11  

  260.     NF_ADDR((ulPageNum) & 0xff);                         //行地址A12~A19  

  261.     NF_ADDR((ulPageNum >> 8) & 0xff);                  //行地址A20~A27  

  262.     NF_ADDR((ulPageNum >> 16) & 0xff);                     //行地址A28  

  263.       

  264.     //读取一页数据内容  

  265.     for (i = 0; i 

  266.     {  

  267.           NF_WRDATA8(*pucBuffer++);  

  268.     }   

  269.       

  270.     NF_CMD(CMD_WRITE2);             //页读命令周期2  

  271.     udelay(200);  

  272.   

  273. #if 0  

  274.     NF_CMD(CMD_STATUS);                 //读状态命令  

  275.     //判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同  

  276.     do  

  277.     {  

  278.         stat = NF_RDDATA8();  

  279.     }while(!(stat&0x40));  

  280. #endif  

  281.   

  282.     NF_DETECT_RB();                //等待RnB信号变高,即不忙  

  283.   

  284.     NF_nFCE_H();                   //打开nandflash片选    

  285.        

  286.     return i;  

  287. }  

  288.   

  289.   

  290. /******************************************************************** 

  291. 函数功能:写nand flash一页数据。 

  292. 入口参数: 

  293.     ulPageNum:页索引 

  294.     pucBuffer:缓冲区 

  295.     bIsLargerPage:1:大页;0:小页 

  296. 返    回:读取字节数。 

  297. 备    注:无。 

  298. ********************************************************************/   

  299. int NandWritePage(U32 ulPageNum, U8 *pucBuffer, U8 bIsLargerPage)  

  300. {  

  301.     switch(bIsLargerPage)   

  302.     {  

  303.         case 0:  

  304. //          return Nand_ReadSectorPage512(ulPageNum, buffer);  

  305.         case 1:  

  306.             return NandWritePage2048(ulPageNum, pucBuffer);  

  307.     }  

  308.     return 0;  

  309. }  

  310.   

  311.   

  312. /******************************************************************** 

  313. 函数功能:写nand flash数据。 

  314. 入口参数: 

  315.     ulAddr:写到哪个地址 

  316.     ulSize:要写的字节数 

  317.     pucBuffer:缓冲区 

  318. 返    回:成功:编程字节数;其他:出错。 

  319. 备    注:无。 

  320. ********************************************************************/  

  321. int NandWrite(U32 ulAddr, U32 ulSize, U8 *pucBuffer)  

  322. {  

  323.     int i, j;  

  324.   

  325.     /*检查参数*/  

  326.     if ( (ulAddr & (NAND_PAGE_SIZE-1)) || (ulSize & (NAND_PAGE_SIZE-1)) )  

  327.     {  

  328.         return ERR_PARAMETER;   /* invalid alignment */  

  329.     }  

  330.   

  331.     /*每次写一页*/  

  332.     for (i=ulAddr; i 

  333.     {  

  334.         if (i & (NAND_BLOCK_SIZE-1)== 0)  //==如果是块首,要检查坏块。  

  335.         {  

  336.             if ( NandIsBadBlock(i/NAND_BLOCK_SIZE, 1) )   

  337.             {  

  338.                 /* Bad block */  

  339.                 i += NAND_BLOCK_SIZE;  

  340.                 ulSize += NAND_BLOCK_SIZE;  

  341.                 continue;  

  342.             }  

  343.         }  

  344.           

  345.         j = NandWritePage(i/NAND_PAGE_SIZE, pucBuffer, 1);  

  346.         i += j;  

  347.         pucBuffer += j;  

  348.     }  

  349.   

  350.     return ERR_SUCCESS;  

  351. }  

  352.   

  353.   

  354. /******************************************************************** 

  355. 函数功能:擦除nand flash数据。 

  356. 入口参数: 

  357.     ulBlock:块索引 

  358. 返    回:成功:0;其他:出错。 

  359. 备    注:无。 

  360. ********************************************************************/   

  361. int NandErase(U32 ulBlockNum)  

  362. {  

  363.     if( NandIsBadBlock(ulBlockNum, 1) )  

  364.     {  

  365.         return ERR_ERASE_NANDFLASH;  

  366.     }  

  367.   

  368.     NF_nFCE_L();                   //打开nandflash片选  

  369.     NF_CLEAR_RB();                 //清RnB信号  

  370.       

  371.     NF_CMD(CMD_ERASE1);             //页读命令周期1  

  372.   

  373.     NF_ADDR((ulBlockNum <<6 ) & 0xff);                         //行地址A12~A19  

  374.     NF_ADDR((ulBlockNum >> 2) & 0xff);                     //行地址A20~A27  

  375.     NF_ADDR((ulBlockNum >> 10) & 0xff);                    //行地址A28  

  376.           

  377.     NF_CMD(CMD_ERASE2);             //页读命令周期2  

  378.     udelay(200);  

  379.   

  380. #if 0  

  381.     NF_CMD(CMD_STATUS);                 //读状态命令  

  382.     //判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同  

  383.     do  

  384.     {  

  385.         stat = NF_RDDATA8();  

  386.     }while(!(stat&0x40));  

  387. #endif  

  388.   

  389.     NF_DETECT_RB();                //等待RnB信号变高,即不忙  

  390.   

  391.     NF_nFCE_H();                   //打开nandflash片选     

  392.     return ERR_SUCCESS;  

  393. }  

  394.   

  395.   

  396. /******************************************************************** 

  397. 函数功能:测试nand flash。 

  398. 入口参数:无。 

  399. 返    回:无。 

  400. 备    注:无。 

  401. ********************************************************************/   

  402. void NandTest(void)  

  403. {  

  404.     int ret;  

  405.     unsigned char data[4][1024];  

  406.   

  407.     memset(data, 0x86, 4*1024);  

  408.   

  409.     NandInit();  

  410.     NandReset();  

  411.     NandReadID();  

  412.   

  413.     ret = NandErase(2);  

  414.     if(ret != ERR_SUCCESS)  

  415.     {  

  416.         DbgPrintX( DBG_NAND_LEVEL, "\rnand erase err=%2x\n",ret);  

  417.         return;  

  418.     }  

  419.   

  420.     ret = NandWrite( 0x50000, 4*1024, (unsigned char *)data );  

  421.     if(ret != ERR_SUCCESS)  

  422.     {  

  423.         DbgPrintX( DBG_NAND_LEVEL, "\rnand write err=%2x\n",ret);  

  424.         return;  

  425.     }  

  426.   

  427.     ret = NandRead(0x50000, 4*1024, (unsigned char *)0x31000000);  

  428.     if(ret != ERR_SUCCESS)  

  429.     {  

  430.         DbgPrintX( DBG_NAND_LEVEL, "\rnand read err=%2x\n",ret);  

  431.         return;  

  432.     }  

  433.   

  434. }  




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈msp430f5529入门(2)----时钟配置.例程分析