static int NAND_ReadPage(unsigned long block,unsigned long page,unsigned char *buffer) //?Flash { int i; unsigned int blockPage; unsigned volatile short *NFCONF; unsigned volatile short *NFCMD; unsigned volatile short *NFSTAT; unsigned volatile short *NFADDR; unsigned volatile short *NFDATA; NFCONF=(unsigned short *)0x4e000000; NFCMD=(unsigned short *)0x4e000004; NFSTAT=(unsigned short *)0x4e000010; NFDATA=(unsigned short *)0x4e00000C; NFADDR=(unsigned short *)0x4e000008; page=page&0x1f; blockPage=(block<<5)+page; //1Bolck¥]§t32page //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++) { *buffer++=NF_RDDATA(); // Read one page } NF_nFCE_H(); }
static int NF_ReadPage(U32 block,U32 page,U8 *buffer,U8 *spareBuf) { int i; unsigned int blockPage; U8 *bufPt=buffer; page=page&0x1f; blockPage=(block<<5)+page; 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); // Delay(1); //wait tWB(100ns)/////?????? NF_WAITRB(); // Wait tR(max 12us) for(i=0;i<(512);i++) { *bufPt++=NF_RDDATA(); // Read one page } if(spareBuf!=NULL) { for(i=0;i<16;i++) spareBuf[i]=NF_RDDATA(); // Read spare array } NF_nFCE_H(); return 1; }
static int NF_IsBadBlock(U32 block) { unsigned int blockPage; U8 data; blockPage=(block<<5); // For 2'nd cycle I/O[7:5] NF_nFCE_L(); NF_CMD(0x50); // Spare array read command NF_ADDR(517&0xf); // Read the mark of bad block in spare array(M addr=5) NF_ADDR(blockPage&0xff); // The mark of bad block is in 0 page NF_ADDR((blockPage>>8)&0xff); // For block number A[24:17] NF_ADDR((blockPage>>16)&0xff); // For block number A[25] Delay(1); // wait tWB(100ns) NF_WAITRB(); // Wait tR(max 12us) data=NF_RDDATA(); NF_nFCE_H(); if(data!=0xff) { printf("[block %d:bad block(%x)]\n",block,data); return 1; } else { printf("."); return 0; } }
static int NAND_WritePage(unsigned long block,unsigned long page,unsigned char *buffer) //?Flash { int i; unsigned long blockPage=(block<<5)+page; //NF_RSTECC(); // Initialize ECC unsigned volatile short *NFCONF; unsigned volatile short *NFCMD; unsigned volatile short *NFSTAT; unsigned volatile short *NFADDR; unsigned volatile short *NFDATA; NFCONF=(unsigned short *)0x4e000000; NFCMD=(unsigned short *)0x4e000004; NFSTAT=(unsigned short *)0x4e000010; NFDATA=(unsigned short *)0x4e00000C; NFADDR=(unsigned short *)0x4e000008; NF_nFCE_L(); NF_CMD(0x0); //?????\\Read Mode 1 NF_CMD(0x80); // Write 1st command,?Õu?¤J 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(*buffer++); // Write one page to NFM from buffer } #if 0 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) #endif 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) { NF_nFCE_H(); return 0; }//error } else { NF_nFCE_H(); return 1; } }
static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf) { int i; U32 blockPage=(block<<5)+page; U8 *bufPt=buffer; NF_nFCE_L(); NF_CMD(0x0); 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 } if(spareBuf!=NULL) { for(i=0;i<16;i++) { NF_WRDATA(spareBuf[i]); // Write spare array(ECC and Mark) } } NF_CMD(0x10); // Write 2nd command Delay(1); //tWB = 100ns. NF_WAITRB(); //wait tPROG 200~500us; NF_CMD(0x70); // Read status command Delay(1); //twhr=60ns if (NF_RDDATA()&0x1) // Page write error { NF_nFCE_H(); printf("[PROGRAM_ERROR:block#=%d]\n",block); NF_MarkBadBlock(block); return 0; } else { NF_nFCE_H(); #if (WRITEVERIFY==1) //return NF_VerifyPage(block,page,pPage); #else return 1; #endif } }
static void NF_Reset(void) { NF_nFCE_L(); NF_CMD(0xFF); //reset command Delay(1); //tWB = 100ns. NF_WAITRB(); //wait 200~500us; NF_nFCE_H(); }
static int NF_MarkBadBlock(U32 block) { int i; U32 blockPage=(block<<5); seBuf[0]=0xff; seBuf[1]=0xff; seBuf[2]=0xff; seBuf[5]=0x44; // Bad blcok mark=0 NF_nFCE_L(); NF_CMD(0x50); NF_CMD(0x80); // Write 1st command NF_ADDR(0x0); // The mark of bad block is NF_ADDR(blockPage&0xff); // marked 5th spare array NF_ADDR((blockPage>>8)&0xff); // in the 1st page. NF_ADDR((blockPage>>16)&0xff); for(i=0;i<16;i++) { NF_WRDATA(seBuf[i]); // Write spare array } NF_CMD(0x10); // Write 2nd command Delay(1); //tWB = 100ns. NF_WAITRB(); // Wait tPROG(200~500us) NF_CMD(0x70); Delay(1); //twhr=60ns// if (NF_RDDATA()&0x1) // Spare arrray write error { NF_nFCE_H(); printf("[Program error is occurred but ignored]\n"); } else { NF_nFCE_H(); } printf("[block #%d is marked as a bad block]\n",block); return 1; }
void enable_nand() { unsigned volatile short *NFCONF; unsigned volatile short *NFCMD; unsigned volatile short *NFSTAT; unsigned int i; NFCONF=(unsigned short *)0x4e000000; NFCMD=(unsigned short *)0x4e000004; NFSTAT=(unsigned short *)0x4e000010; //*NFCONF=(1<<15|1<<14|1<<13|1<<12|TACLS<<8|TWRPH0<<4|TWRPH1); /*Setup NFCONF */ *NFCONF=0xf842; NF_nFCE_L(); /*enable nand chip */ *NFCMD=(unsigned char )RESET; NF_WAITRB(); NF_nFCE_H(); /*disable nand chip */ }
static int NF_EraseBlock(U32 block) { U32 blockPage=(block<<5); #if BAD_CHECK if(NF_IsBadBlock(block) && block!=0) //block #0 can't be bad block for NAND boot return 0; #endif NF_nFCE_L(); NF_CMD(0x60); // 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); // Erase one blcok 2nd command Delay(1); //wait tWB(100ns) NF_WAITRB(); // Wait tBERS max 3ms. NF_CMD(0x70); // Read status command if (NF_RDDATA()&0x1) // Erase error { NF_nFCE_H(); printf("[ERASE_ERROR:block#=%d]\n",block); NF_MarkBadBlock(block); return 0; } else { NF_nFCE_H(); return 1; } }