首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

嵌入式系统中的FLASH(4)

嵌入式系统中的FLASH(4)

1)      根据2410寄存器定义如下的命令宏
#define NF_CMD(cmd) {rNFCMD=cmd;}
#define NF_ADDR(addr)   {rNFADDR=addr;}
#define NF_nFCE_L() {rNFCONF&=~(1
#define NF_nFCE_H() {rNFCONF|=(1
#define NF_RSTECC() {rNFCONF|=(1
#define NF_RDDATA()     (rNFDATA)
#define NF_WRDATA(data) {rNFDATA=data;}
#define NF_WAITRB()    {while(!(rNFSTAT&(1
        //wait tWB and check F_RNB pin.

2)      NAND 设备的初始化
static void NF_Init(void)                          //Flash 初始化
{
rNFCONF=(1                                            //设置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               //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                 //wait tWB(100ns)
   
    id=NF_RDDATA()                 // 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
    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                       //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                      //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                             //wait tWB(100ns)
   
    NF_WAITRB();                                    // Wait tR(max 12us)
    for(i=0;i
    {
        *bufPt++=NF_RDDATA();                       // Read one page
}
/************************ECC校验***************************/
   ecc0=rNFECC0;                              //利用2410自带的硬件ECC校验
    ecc1=rNFECC1;
    ecc2=rNFECC2;
[q3]
     for(i=0;i
    {
        se=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
    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
    {
    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
    {
    NF_WRDATA(seBuf);                    // Write spare array(ECC and Mark)
    }
[q5]

    NF_CMD(0x10);                           // Write 2nd command
   
    for(i=0;i                     //tWB = 100ns. ////??????
    NF_WAITRB();                            //wait tPROG 200~500us;
    NF_CMD(0x70);                           // Read status command   
   
    for(i=0;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
    }
}
继承事业,薪火相传
返回列表