麻木了是什么意思:【转】我的nandflash读写源码,代码清晰

来源:百度文库 编辑:九乡新闻网 时间:2024/05/03 05:49:45

我的nandflash读写源码,代码清晰 (原创)

啥也不说了,偶工程中用的源码,奉献给大家参考,觉得不错的兄弟给帮忙推荐下:
代码整齐,使用了MLC3890的nandflash控制器,可以作为你了解nandflash的参考

//----------------------------------------
#defineNAND_CMD_READ_A          0x00  
#define NAND_CMD_READ_B         0x01
#define NAND_CMD_READ_C          0x50
#defineNAND_CMD_SIGNATURE       0x90
#define NAND_CMD_STATUS          0x70
//PageProgram
#define NAND_CMD_PAGE_PROG0      0x80
#defineNAND_CMD_PAGE_PROG1      0x10
//Copy Back Program
#defineNAND_CMD_COPY_PROG0      0x00
#define NAND_CMD_COPY_PROG1      0x8A
#defineNAND_CMD_COPY_PROG2      0x10
#define NAND_CMD_BLOCK_ERASE0    0x60
#defineNAND_CMD_BLOCK_ERASE1    0xD0
#define NAND_CMD_RESET           0xFF

//NandFlash Status
#define NAND_BIT_WP    0x80  // 0:Protected    1: notprotected
#define NAND_BIT_BUSY  0x60  // bit5,bit6  0:Busy   1:ready
#define NAND_BIT_ERR   0x01  // 1:Error   0:successful

#defineNAND_PAGESIZE       512
#define NAND_SPARESIZE      16
//__align(8)
volatileU8  _NandFlashBakBuffer[NAND_PAGESIZE+NAND_SPARESIZE+1];

#if   0
/*----------------------------------------------------------------*/
/*   NAND FLASH CONTROLLER REGISTERS : 0x00870194                  */
/*----------------------------------------------------------------*/

#define NANDBASE              MCU_NAND_CTRL_BASE
#defineMCU_REG_RW_NAND_CTRL        (*(volatile U32 *)(NANDBASE+0x00))
#defineMCU_REG_RW_NAND_CMD            (*(volatile U32 *)(NANDBASE+0x04))
#defineMCU_REG_RW_NAND_ADR            (*(volatile U32 *)(NANDBASE+0x08))
#defineMCU_REG_RW_NAND_DATA        (*(volatile U32 *)(NANDBASE+0x0C))
#defineMCU_REG_R_NAND_ECC            (*(volatile U32 *)(NANDBASE+0x10))
#defineMCU_REG_RW_NAND_CEBCTRL   (*(volatile U32 *)(NANDBASE+0x14))

#endif
// Enable Nand Controller :8-Bit slowest

#define NandCtrlEnable()            {MCU_REG_RW_PERI_CLKCON |= dMCU_CLK_ENABLE_NAND;\
                                     MCU_REG_RW_NAND_CTRL  = 0x8004FFFF; \
                                     MCU_REG_RW_NAND_CEBCTRL=0x02;}
#define NandWriteCmd(cmd)           {MCU_REG_RW_NAND_CMD  = (cmd) &0xFF;}
#defineNandWriteAddr(addr)         { MCU_REG_RW_NAND_ADR  = (addr)&0xFF;}
#defineNandWriteData(data)         { MCU_REG_RW_NAND_DATA = (data)&0xFF;}
#defineNandReadData(data)          { data = MCU_REG_RW_NAND_DATA & 0xFF;}



#defineNandCtrlIsBusy()    (MCU_REG_RW_NAND_CTRL&0x00040000) //BIT18
#defineNandWait()          Delay(10)

//========================================================
#defineNAND_CE_ACTIVE(x)    {                                \
                   MCU_REG_RW_PERI_CLKCON |= dMCU_CLK_ENABLE_NAND;    \
                   MCU_REG_RW_NAND_CEBCTRL =(x<<2)|(1<<1)|(0<<0);    \
                    }
#defineNAND_CE_INACTIVE(x)    {                                \
                   MCU_REG_RW_NAND_CEBCTRL =(x<<2)|(1<<1)|(1<<0);    \
                   MCU_REG_RW_PERI_CLKCON &= ~dMCU_CLK_ENABLE_NAND;\
                   }

#define pNand_Busy        BITMAP_MCU_GPIO_DATA0.bit13
#definepdNand_Busy       BITMAP_MCU_GPIO_MODE3.bit2
#definepoNand_Busy       BITMAP_MCU_GPIO_MODE3.bit3
#definepNand_Busy_In()   {pdNand_Busy=1; poNand_Busy=1;}


#define    pNand_Busy_OUT()    {MCU_REG_RW8_IOMODE3 =((MCU_REG_RW8_IOMODE3 & 0xF3)|(dMLCIO_OUTPUT_MODE<<2));}
#define   pNand_Busy_IN()        {MCU_REG_RW8_IOMODE3 = ((MCU_REG_RW8_IOMODE3& 0xF3)|(dMLCIO_INPUT_MODE<<2));}


voidNandFlashDrvInit(void)
{
    MCU_REG_RW_PERI_CLKCON |=dMCU_CLK_ENABLE_NAND;
    NandCtrlEnable();
   
   MCU_REG_RW8_IOMODE0 = ((MCU_REG_RW8_IOMODE0&0x03)
                         |(dMLCIO_OUTPUT_MODE<<2)    // GP01 : lcd reset
                         |(dMLCIO_ALTER_MODE<<4)    // GP02 : Nand_CS0
                         |(dMLCIO_ALTER_MODE<<6)); // GP03 : Nand_CS1
     
 MCU_REG_RW8_IOMODE1= (dMLCIO_ALTER_MODE<<0)    // GP04 
           |(dMLCIO_ALTER_MODE<<2)    // GP05 : Nand_ALE
           |(dMLCIO_ALTER_MODE<<4)    // GP06 : Nand_REN
           |(dMLCIO_ALTER_MODE<<6);  // GP07 : Nand_WEN                                                                         
}

voidNandFlashICReset(void)
{
    NandCtrlEnable();
    NandWait();
   NandWriteCmd(NAND_CMD_RESET);
}

void NandFlashEraseBlock (U32block_addr)
{
    U32 temp =0;
    U8 addr1;
    U8 addr2;
   U8 addr3;

    NandCtrlEnable();
    NAND_CE_ACTIVE(0);

   addr1 = (U8) (block_addr >> 9);
    addr2 = (U8) (block_addr>> 17);
    addr3 = (U8) (block_addr >> 25);  
    
   NandWriteCmd(NAND_CMD_BLOCK_ERASE0);
    NandWait();
   NandWriteAddr(addr1); 
    NandWait();
    NandWriteAddr(addr2); 
    NandWait();
    NandWriteAddr(addr3); 
    NandWait();
   NandWriteCmd(NAND_CMD_BLOCK_ERASE1);
   
#if 1
   pNand_Busy_IN();
    for(temp=0;temp<40;temp++);
   for(temp=0;temp<5000;temp++)
    {
        if(pNand_Busy)
           break;
    }
#endif

    do
    {
       NandWriteCmd(NAND_CMD_STATUS);
        NandReadData(temp);
   }while (NAND_BIT_BUSY != (temp & NAND_BIT_BUSY));      

   NAND_CE_INACTIVE(0);
}

U8 NandFlashGetIndex (U16 index)
{
   if(index>NAND_PAGESIZE)
        index = 0;

    return_NandFlashBakBuffer[index];
}

U8 NandFlashGetPage(U8* rdBuf)
{
   U16 index;
   
    for(index=0;index   {
        rdBuf[index] = _NandFlashBakBuffer[index];
    }
   return 0;
}

U8 NandFlashReadPage (U32 page_addr)
{
   U32 temp,idx;
    U8 addr0;
    U8 addr1;
    U8 addr2;
   U8 addr3;

    NandCtrlEnable();
    NAND_CE_ACTIVE(0);
 
   addr0 = (U8)  page_addr;
    addr1 = (U8) (page_addr >> 9);
   addr2 = (U8) (page_addr >> 17);
    addr3 = (U8) (page_addr>> 25);
   
    NandWriteCmd(NAND_CMD_READ_A);
   NandWait();
    NandWriteAddr(addr0);
    NandWait();        
   NandWriteAddr(addr1);
    NandWait();         
   NandWriteAddr(addr2);
    NandWait();        
   NandWriteAddr(addr3);          

    pNand_Busy_IN();
   for(temp=0;temp<40;temp++);
    for(temp=0;temp<5000;temp++)
   {
        if(pNand_Busy)
            break;
    }

   for (idx=0; idx    {
       NandReadData(temp);
        _NandFlashBakBuffer[idx] =(U8)(temp&0xFF);
    }

    NAND_CE_INACTIVE(0);
   return 0;
}

U8 NandFlashProgPage(U32 page_addr, U8* dataAddr)
{
   U8 *rp;
    U16 temp;
    U8 addr0;
    U8 addr1;
    U8addr2;
    U8 addr3;
  
    rp = (U8*)dataAddr;

   NandCtrlEnable();
    NAND_CE_ACTIVE(0);
    addr0 = (U8) page_addr;
    addr1 = (U8) (page_addr >> 9);
    addr2 =(U8) (page_addr >> 17);
    addr3 = (U8) (page_addr >>25);
   
    NandWriteCmd(NAND_CMD_READ_A);
    NandWait();
   NandWriteCmd(NAND_CMD_PAGE_PROG0);
    NandWait();
   NandWriteAddr(addr0);
    NandWait();         
   NandWriteAddr(addr1);
    NandWait();          
   NandWriteAddr(addr2);
    NandWait();         
   NandWriteAddr(addr3);

    for (temp=0; temp    {
        NandWriteData(*rp);
       NandWait();     
        rp++;
    }
   NandWriteCmd(NAND_CMD_PAGE_PROG1);  
 #if 1
    pNand_Busy_IN();
   for(temp=0;temp<40;temp++);
    for(temp=0;temp<5000;temp++)
   {
        if(pNand_Busy)
            break;
    }
#endif
   do
    {
        NandWriteCmd(NAND_CMD_STATUS);
       NandReadData(temp);
    }while (NAND_BIT_BUSY != (temp &NAND_BIT_BUSY));
   
    NAND_CE_INACTIVE(0);
    return 0;   
}

U16 NandGetSignature (void)
{
    U16 temp ;
   U16 sign =0;
   
    NandCtrlEnable();
    NAND_CE_ACTIVE(0);
   
    NandWriteCmd(NAND_CMD_SIGNATURE);
    NandWait();
   NandWriteAddr(0x00);
    NandWait();
    NandReadData(temp);   
   NandWait();
    sign = temp;
    NandReadData(temp);
    sign<<= 8;
    sign += temp;

    NAND_CE_INACTIVE(0);
   return sign;
}