⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 三星ARM9系列CPU S3C2440A的WINCE 5.0下的BSP
💻 C
字号:
#include <windows.h>
#include "s2440addr.h"
#include "option.h"

#define NF_CMD(cmd)	    {rNFCMD=cmd;}
#define NF_ADDR(addr)	  {rNFADDR=addr;}	

#if 1		// for S3C2440aNAND
//  For flash chip that is bigger than 32 MB, we need to have 4 step address
#define NEED_EXT_ADDR               1

#define NF_nFCE_L()	        {rNFCONT &= ~(1 << 1);}
#define NF_nFCE_H()	        {rNFCONT |=  (1 << 1);}
#define NF_RSTECC()	        {rNFCONT |=  (1 << 4);}

#define NF_MECC_UnLock()	{rNFCONT &= ~(1<<5);}
#define NF_MECC_Lock()		{rNFCONT |= (1<<5);}

#define NF_CLEAR_RB()		{rNFSTAT |=  (1 << 2);}
#define NF_DETECT_RB()		{while(!(rNFSTAT&(1<<2)));}
#define NF_WAITRB()         {while (!(rNFSTAT & (1 << 2)));} 

#else

#define NF_nFCE_L()	    {rNFCONT&=~(1<<1);}
#define NF_nFCE_H()	    {rNFCONT|=(1<<1);}
#define NF_RSTECC()	    {rNFCONT|=(1<<4);}
#define NF_WAITRB()     {while(!(rNFSTAT&(1<<0)));} 

#endif

#define NF_RDDATA() 	   (rNFDATA)
#define NF_RDDATA32() 	   (rNFDATA32)
#define NF_WRDATA(data) 	{rNFDATA=data;}

#define NF_RDMECC0()			(rNFMECC0)
#define NF_RDMECC1()			(rNFMECC1)

#define NF_RDMECCD0()			(rNFMECCD0)
#define NF_RDMECCD1()			(rNFMECCD1)

#define NF_WRMECCD0(data)			{rNFMECCD0 = (data);}
#define NF_WRMECCD1(data)			{rNFMECCD1 = (data);}


#define ID_K9S1208V0M	  0xec76

// HCLK=133Mhz
#define TACLS		0 
#define TWRPH0		5
#define TWRPH1		3

BOOL bLARGEBLOCK;

void __RdPage512(BYTE *bufPt); 

int NF_ReadID()
{
	UINT8 pMID;
	UINT8 pDID;
    UINT32  nCnt;
    UINT32  nBAddr, nRet;
    UINT16  nBuff;
    UINT8   n4thcycle;
	int i;

	bLARGEBLOCK = FALSE;
    n4thcycle = nBuff = 0;

    NF_nFCE_L();    
	NF_CLEAR_RB();
    NF_CMD  (0x90);	// read id command
    NF_ADDR (0x00);
	for ( i = 0; i < 100; i++ );

    /* tREA is necessary to Get a MID. */
    for (nCnt = 0; nCnt < 5; nCnt++)
    {
        pMID = (BYTE) NF_RDDATA();
        if (0xEC == pMID)
            break;
    }

    pDID = (BYTE) NF_RDDATA();
    
    nBuff     = (BYTE) NF_RDDATA();
    n4thcycle = (BYTE) NF_RDDATA();
    NF_nFCE_H();

    if (pMID != (UINT8)0xEC)
        nRet = FALSE;
    else
        nRet = TRUE;

	if (pDID >= 0xA0)
	{
		bLARGEBLOCK = TRUE;
	}

    return (nRet);
}


int NF_ReadPage(UINT32 block,UINT32 page,UINT8 *buffer)
{
    volatile int i;
    register UINT8 * bufPt=buffer;
    unsigned int blockPage;
	ULONG MECC;
	int NewDataAddr;

	if ( bLARGEBLOCK == TRUE )
	{
		blockPage = (block<<6) + page/4;
		NewDataAddr = 512*(page%4);
		NF_RSTECC();    // Initialize ECC
		NF_MECC_UnLock();
    
		NF_nFCE_L();    
		NF_CMD(0x00);   // Read command

		NF_ADDR((NewDataAddr)&0xff);
		NF_ADDR(((NewDataAddr)>>8)&0xff);
		NF_ADDR(blockPage&0xff);	    //
		NF_ADDR((blockPage>>8)&0xff);   // Block & Page num.
	    if (LB_NEED_EXT_ADDR) {
		NF_ADDR((blockPage>>16)&0xff);   // Block & Page num.
	    }
	}
	else
	{
		//blockPage = (block<<5) + page;
		blockPage = (block<<8) + page;    //c ksk 20060228
		NewDataAddr=0;
		NF_RSTECC();    // Initialize ECC
		NF_MECC_UnLock();
    
		NF_nFCE_L();    
		NF_CMD(0x00);   // Read command

		NF_ADDR((NewDataAddr)&0xff);
		NF_ADDR(blockPage&0xff);	    //
		NF_ADDR((blockPage>>8)&0xff);   // Block & Page num.
	    if (SB_NEED_EXT_ADDR) {
		NF_ADDR((blockPage>>16)&0xff);   // Block & Page num.
	    }
	}

	NF_CLEAR_RB();
	NF_CMD(0x30);
	NF_DETECT_RB();

    __RdPage512(bufPt);
	NF_MECC_Lock();

	// no ecc check
	return 1;

	MECC = NF_RDDATA32();
	MECC = NF_RDDATA32();
	    
    MECC = NF_RDDATA32();
    NF_WRMECCD0( ((MECC&0xff00    )<<8) |  (MECC&0xff    )      );
    NF_WRMECCD1( ((MECC&0xff000000)>>8) | ((MECC&0xff0000)>>16) );
    NF_nFCE_H();    

	if(rNFESTAT0 & 0x3)
	{
		Uart_SendString("ECC ERROR block");
		Uart_SendDWORD(block,0);
		Uart_SendString("page");
		Uart_SendDWORD(page,1);
		return 0;
	}
	else
		return 1;

}


void NF_Reset(void)
{
    volatile 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();
}


void NF_Init(void)
{

    rNFCONF = (TACLS  <<  12) | /* CLE & ALE = HCLK * (TACLS  + 1)   */
                          (TWRPH0 <<  8) | /* TWRPH0    = HCLK * (TWRPH0 + 1)   */
                          (TWRPH1 <<  4) |
						  (0<<0);

    rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);
	rNFSTAT = 0x4;
    NF_Reset();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -