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 } }
char __low_nand_write_page(unsigned int page_addr,unsigned char *from) { U32 i; char nfstatus; unsigned int *pfrom = (unsigned int *)from;//2440的NFADDR寄存器是32位的 // printk("write 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_WRITE1); // 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_WRDATA(0xffffffff); // NF_WRDATA(0xffffffff); // NF_WRDATA(0xffffffff); // NF_WRDATA(0xffffffff); for(i = 0;i < (NAND_PAGE_SIZE+64) >> 2;++i) { NF_WRDATA( *((unsigned*)pfrom++)); } NF_CMD(CMD_WRITE2); NF_DETECT_RB(); // wait tR(max 12us) NF_CMD(CMD_STATUS); return (NF_RDDATA8() & 0x01); // nfstatus = NF_RDDATA8(); // NF_nFCE_H(); // printk("nand status:%x\r\n",nfstatus); }
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; }