www.pudn.com > S3C2440_uCos-II.rar > nand.c


 
//void Uart0_Printf(char *fmt,...); 
 
 
#define __REGb(x)	(*(volatile unsigned char *)(x)) 
#define __REGi(x)	(*(volatile unsigned int *)(x)) 
#define NF_BASE		0x4e000000 
#define NFCONF		__REGi(NF_BASE + 0x0) 
#define NFCONT		__REGi(NF_BASE + 0x4) 
#define NFCMD		__REGb(NF_BASE + 0x8) 
#define NFADDR		__REGb(NF_BASE + 0xC) 
#define NFDATA		__REGb(NF_BASE + 0x10) 
#define NFSTAT		__REGb(NF_BASE + 0x20) 
 
#define NAND_CHIP_ENABLE  (NFCONT &= ~(1<<1)) 
#define NAND_CHIP_DISABLE (NFCONT |=  (1<<1)) 
#define NAND_CLEAR_RB	  (NFSTAT |=  (1<<2)) 
#define NAND_DETECT_RB	  { while(! (NFSTAT&(1<<2)) );} 
 
#define NAND_CMD_READ0		0 
#define NAND_CMD_READOOB	0x50 
 
#define BUSY 4 
static  
void wait_idle(void) { 
    int i; 
 
    for(i=0; i<100; i++); 
    while(!(NFSTAT & BUSY)) 
      for(i=0; i<100; i++); 
 
    NFSTAT |= BUSY; 
} 
 
#define NAND_SECTOR_SIZE	512 
#define NAND_SECTOR_MASK		(NAND_SECTOR_SIZE - 1) 
#define NAND_BLOCK_SIZE         (32*NAND_SECTOR_SIZE) 
#define NAND_BLOCK_MASK         (NAND_BLOCK_SIZE - 1) 
 
/* low level nand read function */ 
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) 
{ 
    int i; 
    unsigned long addr, baddr; 
 
    if ((start_addr & NAND_BLOCK_MASK)/* || (size & NAND_SECTOR_MASK)*/) { 
        return -1;	/* invalid alignment */ 
    } 
 
    /* chip Enable */ 
    NAND_CHIP_ENABLE; 
    for(i=0; i<100; i++); 
 
    for(baddr=start_addr&~NAND_BLOCK_MASK; size>0; baddr+=NAND_BLOCK_SIZE) { 
 
        /* READOOB */ 
        NAND_CLEAR_RB; 
        NFCMD = NAND_CMD_READOOB; 
           
        /* Write Address */ 
		NFADDR = (5) & 0xff; 
		NFADDR = (baddr >> 9) & 0xff; 
		NFADDR = (baddr >> 17) & 0xff; 
		NFADDR = (baddr >> 25) & 0xff; 
		 
		NAND_DETECT_RB 
		if ((NFDATA & 0xff)!= 0xff) { 
		    //Uart0_Printf ("bad block at %d\r\n",baddr>>14); 
		    continue;   //bad block 
		} 
           
        for(addr=0; addr0); size-=NAND_SECTOR_SIZE,addr+=NAND_SECTOR_SIZE) { 
          /* READ0 */ 
          NAND_CLEAR_RB; 
          NFCMD = 0; 
     
           
          /* Write Address */ 
    		NFADDR = (baddr+addr) & 0xff; 
    		NFADDR = ((baddr+addr) >> 9) & 0xff; 
    		NFADDR = ((baddr+addr) >> 17) & 0xff; 
    		NFADDR = ((baddr+addr) >> 25) & 0xff; 
     
          NAND_DETECT_RB 
     
          for(i=0; i < NAND_SECTOR_SIZE; i++) { 
    	    *buf = (NFDATA & 0xff); 
    	    buf++; 
          } 
        } 
    } 
 
    /* chip Disable */ 
    NAND_CHIP_DISABLE; 
 
    return 0; 
}