ison

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  19 随笔 :: 0 文章 :: 0 评论 :: 0 Trackbacks

3NAND FLASH 的软件编写和调试

    NAND设备的软件调试一般分为以下几个步骤:设置相关寄存器、NAND 设备的初始化、NAND设备的识别、NAND设备的读擦写(带ECC校验 )

    NAND设备的操作都是需要通过命令来完成,不同厂家的命令稍有不同,以下一Samsung公司的K9F1208U0M命令表为例介绍NAND设备的软件编写。

点击看大图

2 K9F1208U0M Command Sets

1)      根据2410寄存器定义如下的命令宏

#define NF_CMD(cmd) {rNFCMD=cmd;}

#define NF_ADDR(addr)   {rNFADDR=addr;}

#define NF_nFCE_L() {rNFCONF&=~(1<<11);}

#define NF_nFCE_H() {rNFCONF|=(1<<11);}

#define NF_RSTECC() {rNFCONF|=(1<<12);}

#define NF_RDDATA()     (rNFDATA)

#define NF_WRDATA(data) {rNFDATA=data;}

#define NF_WAITRB()    {while(!(rNFSTAT&(1<<0)));}

        //wait tWB and check F_RNB pin.

2)      NAND 设备的初始化

static void NF_Init(void)                          //Flash 初始化

{

rNFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);                                            //设置NAND设备的相关寄存器

    // 1 1    1     1,   1      xxx, r xxx,   r xxx       

    // En 512B 4step ECCR nFCE="H" tACLS   tWRPH0   tWRPH1

   

    NF_Reset();

}

static void NF_Reset(void)                           //Flash重置

{

    int i;

    NF_nFCE_L();

    NF_CMD(0xFF);                      //reset command

    for(i=0;i<10;i++);                //tWB = 100ns

    NF_WAITRB();                        //wait 200~500us;

    NF_nFCE_H();

}

3)      NAND设备的识别                    //#define ID_K9F1208U0M 0xec76

static U16 NF_CheckId(void)                           //Id 辨别

{

    int i;

    U16 id;

   

    NF_nFCE_L();

    NF_CMD(0x90);

    NF_ADDR(0x0);

   

    for(i=0;i<10;i++);                  //wait tWB(100ns)

   

    id=NF_RDDATA()<<8;                 // Maker code(K9F1208U:0xec)

    id|=NF_RDDATA();                    // Devide code(K9F1208U:0x76)

   

    NF_nFCE_H();

    return id;

}

4)      NAND 的擦操作

static int NF_EraseBlock(U32 block)

{

    U32 blockPage=(block<<5);

    int i;

    NF_nFCE_L();

   

    NF_CMD(0x60[q1] );                          // Erase one block 1st command

    NF_ADDR(blockPage&0xff);                // Page number="0"

    NF_ADDR((blockPage>>8)&0xff);  

    NF_ADDR((blockPage>>16)&0xff);

    NF_CMD(0xd0[q2] );                           // Erase one blcok 2nd command

   

   for(i=0;i<10;i++);                       //wait tWB(100ns)//??????

    NF_WAITRB();                            // Wait tBERS max 3ms.

    NF_CMD(0x70);                           // Read status command

    if (NF_RDDATA()&0x1)                    // Erase error

    {  

        NF_nFCE_H();

    Uart_Printf("[ERASE_ERROR:block#=%d]\n",block);

        return 0;

    }

    else

    {

        NF_nFCE_H();

        return 1;

    }

}

5)      NAND 的读操作

static int NF_ReadPage(U32 block,U32 page,U8 *buffer)       //Flash

{

    int i;

    unsigned int blockPage;

    U8 ecc0,ecc1,ecc2;

    U8 *bufPt=buffer;

    U8 se[16];   

   

    page=page&0x1f;                                 //32

    blockPage=(block<<5)+page;                      //1Bolck包含32

    NF_RSTECC();                                    // Initialize ECC

   

    NF_nFCE_L();   

    NF_CMD(0x00);                                   // Read command

    NF_ADDR(0);                                     // Column = 0

    NF_ADDR(blockPage&0xff);                        //

    NF_ADDR((blockPage>>8)&0xff);                   // Block & Page num.

  NF_ADDR((blockPage>>16)&0xff);                 //

    for(i=0;i<10;i++);                              //wait tWB(100ns)

   

    NF_WAITRB();                                    // Wait tR(max 12us)

    for(i=0;i<512;i++)

    {

        *bufPt++=NF_RDDATA();                       // Read one page

}

/************************ECC校验***************************/

   ecc0=rNFECC0;                              //利用2410自带的硬件ECC校验

    ecc1=rNFECC1;

    ecc2=rNFECC2;

[q3]     for(i=0;i<16;i++)

    {

        se[i]=NF_RDDATA();                         // Read spare array

                                                    //读页内冗余的16B

    }

       NF_nFCE_H();   

    if(ecc0==se[0] && ecc1==se[1] && ecc2==se[2])   //未知使用哪一种软件规范?

    {                                               //比较数据结果是否正确

    Uart_Printf("[ECC OK:%x,%x,%x]\n",se[0],se[1],se[2]);

        return 1;

    }

    else

    {

    Uart_Printf("[ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n",

        se[0],se[1],se[2],ecc0,ecc1,ecc2);

        return 0;

    }      

}

6)      NAND 的写操作

static int NF_WritePage(U32 block,U32 page,U8 *buffer)             //Flash

{

    int i;

    U32 blockPage=(block<<5)+page;

    U8 *bufPt=buffer;

    NF_RSTECC();                                // Initialize ECC

   

    NF_nFCE_L();

    NF_CMD(0x0[q4] );                                //?????\\Read Mode 1

    NF_CMD(0x80);                               // Write 1st command,数据输入

    NF_ADDR(0);                                 // Column 0

    NF_ADDR(blockPage&0xff);       

    NF_ADDR((blockPage>>8)&0xff);               // Block & page num.

    NF_ADDR((blockPage>>16)&0xff);

    for(i=0;i<512;i++)

    {

    NF_WRDATA(*bufPt++);                    // Write one page to NFM from buffer

    }

   

    seBuf[0]=rNFECC0;

    seBuf[1]=rNFECC1;

    seBuf[2]=rNFECC2;

    seBuf[5]=0xff;                          // Marking good block

   

    for(i=0;i<16;i++)

    {

    NF_WRDATA(seBuf[i]);                    // Write spare array(ECC and Mark)

    }

[q5]

    NF_CMD(0x10);                           // Write 2nd command

   

    for(i=0;i<10;i++);                     //tWB = 100ns. ////??????

    NF_WAITRB();                            //wait tPROG 200~500us;

    NF_CMD(0x70);                           // Read status command  

   

    for(i=0;i<3;i++);                      //twhr=60ns

   

    if (NF_RDDATA()&0x1)                    // Page write error

    {  

        NF_nFCE_H();

    Uart_Printf("[PROGRAM_ERROR:block#=%d]\n",block);

    return 0;

    }

    else

    {

        NF_nFCE_H();

    #if (WRITEVERIFY==1)

    //return NF_VerifyPage(block,page,pPage);  

    #else

    return 1;

    #endif

    }

}

posted on 2008-09-20 22:14 ison 阅读(366) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。