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 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_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 U16 NF_CheckId(void) { U16 id; NF_nFCE_L(); NF_CMD(0x90); NF_ADDR(0x0); Delay(1); //wait tWB(100ns) id=NF_RDDATA()<<8; // Maker code(K9S1208V:0xec) id|=NF_RDDATA(); // Devide code(K9S1208V:0x76) NF_nFCE_H(); return id; }
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 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 __low_nand_read_page(unsigned int page_addr,unsigned char *to) { U32 i; char nfstatus; unsigned int *pto = (unsigned int *)to; // printk("read page addr :%.8x \r\n",page_addr); // __low_nand_reset(); // Enable the chip NF_nFCE_L(); NF_CLEAR_RB(); // Issue Read command NF_CMD(CMD_READ); // Set up address NF_ADDR(page_addr & 0xff); NF_ADDR((page_addr >> 8) & 0x0f); NF_ADDR((page_addr >> 12) & 0xff); NF_ADDR((page_addr >> 20) & 0xff); NF_ADDR((page_addr >> 28) & 0x01); NF_CMD(CMD_READ2); NF_DETECT_RB(); // wait tR(max 12us) for (i = 0; i < (NAND_PAGE_SIZE+64) >> 2;++i) { *((unsigned*)pto++) = NF_RDDATA(); } // for (i = 0; i < NAND_PAGE_SIZE ;++i) // { // to[i] = NF_RDDATA8(); // } NF_nFCE_H(); }
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; } }