📄 cmd_nand_mba24x0.c.svn-base
字号:
for(i=0; i < NAND_PAGE_SIZE ; i++) NF_WRDATA(*ptr++);#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 for(i=0; i < NAND_PAGE_SIZE ; i++) NF_WRDATA8(*ptr++);#endif#if CONFIG_S3C2410 seBuf[0] = NFECC0; seBuf[1] = NFECC1; seBuf[2] = NFECC2; seBuf[5] = 0xff; // Marking good block // Write spare array(ECC and Mark) for(i=0;i<16;i++) NF_WRDATA(seBuf[i]);#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 NF_MECC_Lock(); mecc = NFMECC0; seBuf[0] = (u8)(mecc & 0xff); seBuf[1] = (u8)((mecc>>8) & 0xff); seBuf[2] = (u8)((mecc>>16) & 0xff); seBuf[3] = (u8)((mecc>>24) & 0xff); seBuf[5] = 0xff; NF_SECC_UnLock(); for(i=0;i<3;i++){ NF_WRDATA8(seBuf[i]); } NF_SECC_Lock(); secc = NFSECC; seBuf[8] = (u8)(secc & 0xff); seBuf[9] = (u8)((secc>>8) & 0xff); for(i=3;i<16;i++){ NF_WRDATA8(seBuf[i]); }#endif NF_CLEAR_RB(); NF_CMD(NAND_CMD_PAGEPROG); // Write 2nd command for(i=0; i<10 ;i++); NF_DETECT_RB(); NF_CMD(NAND_CMD_STATUS); // Read status command for(i=0;i<3;i++); //twhr=60ns #if CONFIG_S3C2410 if (NF_RDDATA() & 0x1){#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 if(NF_RDDATA8() & 0x1){#endif NF_nFCE_H();// printf("[PROGRAM_ERROR:block#=%d]\n",block); NF_MarkBadBlock(block); return 0; // page write ERROR } else { NF_nFCE_H();// page write SUCCESS return 1; }}int NF_Read(u8 *dst_addr, u8 *start_nand_addr, u32 size){ u32 s_blk_num, s_pg_num; u32 e_blk_num, e_pg_num; u8 * buf = dst_addr; int i, j; if(((u32)start_nand_addr<0) || ((u32)start_nand_addr>=nand_mem_size)){ printf("target_addr must be within the range of 0x0 ~ 0x%x\n", nand_mem_size-1); return -1; } if(((u32)dst_addr<CFG_MEMTEST_START) || ((u32)dst_addr>=CFG_MEMTEST_END)){ printf("destination_memory_addr must be within the range of 0x%x ~ 0x%x\n", CFG_MEMTEST_START, CFG_MEMTEST_END); return -1; } s_blk_num = (u32)start_nand_addr / (u32)NAND_BLOCK_SIZE; s_pg_num = ((u32)start_nand_addr&(NAND_BLOCK_SIZE -1)) / (u32)NAND_PAGE_SIZE; e_blk_num = ((size / (u32)NAND_BLOCK_SIZE)) + s_blk_num; e_pg_num = ((size&(NAND_BLOCK_SIZE-1)) / (u32)NAND_PAGE_SIZE) + s_pg_num; printf("Read start point : block[%d] page[%d] size = 0x%x\n", s_blk_num, s_pg_num, size); printf("Reading data ... "); for(i=s_blk_num; i<=e_blk_num; i++){ if(NF_IsBadBlock(i) == 1){ printf("\nBlock[%d] is bad block. Read next block\n",i); e_blk_num++; printf("Reading data ... "); continue; } if((i==s_blk_num) && (s_pg_num != 0)){ for(j=s_pg_num; j<NAND_PAGES_IN_BLOCK; j++){ NF_ReadPage(i, j, buf); spin_wheel(); buf += NAND_PAGE_SIZE; } }else if((i==e_blk_num) && (e_pg_num != 0)){ for(j=0; j<e_pg_num; j++){ NF_ReadPage(i, j, buf); spin_wheel(); buf += NAND_PAGE_SIZE; } }else if((i==e_blk_num) && (e_pg_num == 0)){ break; }else{ NF_ReadBlock(buf, i); buf += NAND_BLOCK_SIZE; } } printf("\nRead compelete(0x%x): from 0x%x(%d) NAND flash to 0x%x SDRAM\n", size, start_nand_addr, s_blk_num, (u32)dst_addr); return 0; }int NF_ReadBlock(u8 *dst_addr, u32 blk_num){ char *buf = dst_addr; char page_buf[NAND_PAGE_SIZE]; int i, j; // read block for (i = 0; i < NAND_PAGES_IN_BLOCK; i++) { NF_ReadPage(blk_num, i, (char *)page_buf); for(j = 0; j < NAND_PAGE_SIZE; j++) *buf++ = page_buf[j]; spin_wheel(); } LED_blink(RD_STATUS); return 0;}int NF_ReadPage(u32 block, u32 page, u8 *buffer){ int i; unsigned int blockPage = (block * NAND_PAGES_IN_BLOCK) + (page & 0x1f);#if CONFIG_MBA2410 unsigned char ecc0, ecc1, ecc2, se[16];#endif unsigned char *bufPt = buffer; NF_RSTECC();#if CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 NF_MECC_UnLock();#endif NF_nFCE_L(); NF_CLEAR_RB(); NF_CMD(NAND_CMD_READ0); // 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++); NF_DETECT_RB();#if CONFIG_S3C2410 for(i=0;i<512;i++) *bufPt++ = NF_RDDATA(); // Read one page#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 for(i=0;i<512;i++) *bufPt++ = NF_RDDATA8();// Read one page#endif#if CONFIG_S3C2410 //error check ecc0 = NFECC0; ecc1 = NFECC1; ecc2 = NFECC2; for(i=0;i<16;i++) se[i]=NF_RDDATA(); // Read spare array#endif NF_nFCE_H();#if CONFIG_S3C2410 if( (ecc0==se[0]) && (ecc1==se[1]) && (ecc2==se[2]) ) {// printf("[ECC OK:%x,%x,%x]\n", se[0], se[1], se[2]); }else{ printf("[ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n", se[0], se[1], se[2], ecc0, ecc1, ecc2); return -1; }#endif return 0;}/*static int NF_WriteOob(u32 block,u32 page,u8 *buffer, int yaffs_option){ int i; u32 blockPage = (block * NAND_PAGES_IN_BLOCK) + page;#ifdef S3C24X0_16BIT_NAND u16 *ptr16=buffer;#else u8 *ptr8 = buffer; u8 oobBuf[NAND_OOB_SIZE]; for (i=0; i<NAND_OOB_SIZE; i++) { oobBuf[i] = (*ptr8++); } if ( yaffs_option == NF_USE_MTD_ECC ) { oobBuf[ 8] = 0xFF; oobBuf[ 9] = 0xFF; oobBuf[10] = 0xFF; oobBuf[13] = 0xFF; oobBuf[14] = 0xFF; oobBuf[15] = 0xFF; }#endif NF_nFCE_L(); NFCMD = NAND_CMD_READOOB; NFCMD = NAND_CMD_SEQIN; NFADDR= 0; NFADDR= blockPage & 0xff; NFADDR= (blockPage>>8) & 0xff;#ifdef NAND_3_ADDR_CYCLE // Nothing#else NFADDR=((blockPage>>16)&0xff);#endif#ifdef S3C24X0_16BIT_NAND for(i=0; i < NAND_OOB_SIZE/2 ; i++){ NFDATA16 = *ptr16++; }#else for(i=0; i < NAND_OOB_SIZE ; i++) { NFDATA8 = oobBuf[i]; }#endif NFCMD = NAND_CMD_PAGEPROG; for(i=0; i<10 ;i++); NF_DETECT_RB(); NFCMD = NAND_CMD_STATUS; for(i=0; i<3; i++); if (NFDATA8 & 0x1) { NF_nFCE_H(); printf("*****************************************"); printf("\r"); } else { NF_nFCE_H(); } return 1;}*/int NF_EraseBlock(u32 block){ u32 blockPage = block * NAND_PAGES_IN_BLOCK; int i; if(NF_IsBadBlock(block)) return 0; NF_nFCE_L(); NF_CLEAR_RB(); NF_CMD(NAND_CMD_ERASE1); // Erase one block 1st command NF_ADDR(blockPage & 0xff); NF_ADDR((blockPage >> 8) & 0xff); NF_ADDR((blockPage >> 16) & 0xff); NF_CMD(NAND_CMD_ERASE2); // Erase one blcok 2nd command for(i=0;i<10;i++); NF_DETECT_RB(); NF_CMD(NAND_CMD_STATUS); // Read status command#if CONFIG_S3C2410 if(NF_RDDATA() & 0x1){#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 if(NF_RDDATA8() & 0x1){#endif NF_nFCE_H(); NF_MarkBadBlock(block); return 0; //erase ERROR }else{ NF_nFCE_H(); return 1; //erase SUCCESS }}int NF_MarkBadBlock(u32 block){ int i; u32 blockPage = block * NAND_PAGES_IN_BLOCK; seBuf[0]=0xff; seBuf[1]=0xff; seBuf[2]=0xff; seBuf[5]=0x44; NF_nFCE_L(); NF_CMD(NAND_CMD_READOOB); NF_CMD(NAND_CMD_SEQIN); 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); //#if CONFIG_S3C2410 for(i=0 ;i < NAND_OOB_SIZE ;i++) NF_WRDATA(seBuf[i]);// Write spare array#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 for(i=0 ;i < NAND_OOB_SIZE ;i++) NF_WRDATA8(seBuf[i]);// Write spare array#endif NF_CMD(NAND_CMD_PAGEPROG); // Write 2nd command for(i=0;i<10;i++); NF_DETECT_RB(); NF_CMD(NAND_CMD_STATUS); for(i=0;i<3;i++); //twhr=60ns#if CONFIG_S3C2410 if(NF_RDDATA() & 0x1){#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 if(NF_RDDATA8() & 0x1){#endif NF_nFCE_H();// printf("[MARK_BADBLOCK:block number = %4d]\n", block); }else{ NF_nFCE_H(); }// printf("[block #%d is marked as a bad block]\n",block); return 1;}/*static int NF_CheckBadNande(u32 block){ int i; unsigned int blockPage; u16 data; blockPage = block * NAND_PAGES_IN_BLOCK; NF_RSTECC(); NF_nFCE_L(); NF_CLEAR_RB(); NF_CMD(NAND_CMD_READOOB); // NF_ADDR((NAND_PAGE_SIZE + 0) & 0xf); NF_ADDR(0); 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] for(i=0;i<10;i++); // dummy check me NF_DETECT_RB(); for (i = 0 ; i < NAND_PAGE_SIZE; i++){ data = NF_RDDATA(); if ( data != 0xff ) break; } NF_nFCE_H(); if (i != NAND_PAGE_SIZE) { printf("[block %d is bad block(%x)]\n",block,data); }}*/int NF_IsBadBlock(u32 block){ int i, blockPage; u8 data; blockPage = block * NAND_PAGES_IN_BLOCK; NF_nFCE_L(); NF_CLEAR_RB(); NF_CMD(NAND_CMD_READOOB); 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] for(i=0;i<10;i++); NF_DETECT_RB();#if CONFIG_S3C2410 data = NF_RDDATA();#elif CONFIG_S3C2440 || CONFIG_S3C2443 //added by maddy220109 data = NF_RDDATA8();#endif NF_nFCE_H(); if(data != 0xff) return 1; //bad block else return 0; //good block}u16 NF_CheckId(void){ int i; u16 id = 0; NF_nFCE_L(); NF_CMD(NAND_CMD_READID); NF_ADDR(0x0); for(i=0;i<10;i++); //wait tWB(100ns)#if CONFIG_S3C2410 id = NF_RDDATA()<<8; id |= NF_RDDATA();#elif (CONFIG_S3C2440 || CONFIG_S3C2443) //added by maddy220109 id = NF_RDDATA8()<<8; id |= NF_RDDATA8();#endif NF_nFCE_H(); printf("Manufacture ID [0x%x], ", id>>8); printf("Device ID [0x%x]\n", id & 0xff); return id;}void NF_Reset(void){ int i; NF_nFCE_L(); NF_CLEAR_RB(); NF_CMD(NAND_CMD_RESET); for(i=0;i<10;i++); NF_nFCE_H();}void NF_Init(void){#if CONFIG_S3C2410 NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); // [15] NAND flash controller Enable/Disable : 1 - enble // [12] Initialize ECC decoder/encoder : 1 - initialize ECC(support only 512B) // [11] NAND flash memory chip enable : 1 - NAND flash nFCE = H(inative) // (After auto-boot, nFCE is inactive) // [10:8] CLE & ALE duration setting value(0~7) : Duration = HCLK * (TACLS + 1) // [6:4] TWRPH0 duration setting value(0~7) : Duration = HCLK * (TWRPH0 + 1) // [2:0] TWRPH1 duration setting value(0~7) : Duration = HCLK * (TWRPH1 + 1)#elif CONFIG_S3C2440 NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0); // TACLS [14:12] CLE&ALE duration = HCLK*TACLS. // TWRPH0 [10:8] TWRPH0 duration = HCLK*(TWRPH0+1) // TWRPH1 [6:4] TWRPH1 duration = HCLK*(TWRPH1+1) // AdvFlash(R) [3] Advanced NAND, 0:256/512, 1:1024/2048 // PageSize(R) [2] NAND memory page size // when [3]==0, 0:256, 1:512 bytes/page. // when [3]==1, 0:1024, 1:2048 bytes/page. // AddrCycle(R) [1] NAND flash addr size // when [3]==0, 0:3-addr, 1:4-addr. // when [3]==1, 0:4-addr, 1:5-addr. // BusWidth(R/W) [0] NAND bus width. 0:8-bit, 1:16-bit. NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0); // Lock-tight [13] 0:Disable lock, 1:Enable lock. // Soft Lock [12] 0:Disable lock, 1:Enable lock. // EnablillegalAcINT[10] Illegal access interupt control. 0:Disable, 1:Enable // EnbRnBINT [9] RnB interrupt. 0:Disable, 1:Enable // RnB_TrandMode[8] RnB transition detection config. 0:Low to High, 1:High to Low // SpareECCLock [6] 0:Unlock, 1:Lock // MainECCLock [5] 0:Unlock, 1:Lock // InitECC(W) [4] 1:Init ECC decoder/encoder. // Reg_nCE [1] 0:nFCE=0, 1:nFCE=1. // NANDC Enable [0] operating mode. 0:Disable, 1:Enable.#elif CONFIG_S3C2443 NFCONF = (1<<31)|(1<<24)|(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0); // NANDBoot [31] Shows NAND Boot or not, 0:Disable NANDBoot, 1:Enable NANDBoot // ECCTYPE [24] ECC Type Selection, 0:SLC(1-bit Correction), 1:MLC(4-bit Correction) // TACLS [14:12] CLE&ALE duration = HCLK*TACLS. // TWRPH0 [10:8] TWRPH0 duration = HCLK*(TWRPH0+1) // TWRPH1 [6:4] TWRPH1 duration = HCLK*(TWRPH1+1) // AdvFlash(R) [3] Advanced NAND, 0:256/512, 1:1024/2048 // PageSize(R) [2] NAND memory page size // when [3]==0, 0:256, 1:512 bytes/page. // when [3]==1, 0:1024, 1:2048 bytes/page. // AddrCycle(R) [1] NAND flash addr size // when [3]==0, 0:3-addr, 1:4-addr. // when [3]==1, 0:4-addr, 1:5-addr. // BusWidth(R/W) [0] NAND bus width. 0:8-bit, 1:16-bit. NFCONT = (0<<17)|(0<<16)|(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0); // Lock-tight [17] 0:Disable lock, 1:Enable lock. // Soft Lock [16] 0:Disable lock, 1:Enable lock. // EnbECCEncINT [13] ECC encoding completion interrupt contro 0:Disable 1:Enable // EnbECCDecINT [12] ECC Decoding completion interrupt contro 0:Disable 1:Enable // EnablillegalAcINT[10] Illegal access interupt control. 0:Disable, 1:Enable // EnbRnBINT [9] RnB interrupt. 0:Disable, 1:Enable // RnB_TrandMode[8] RnB transition detection config. 0:Low to High, 1:High to Low // SpareECCLock [6] 0:Unlock, 1:Lock // MainECCLock [7] 0:Unlock, 1:Lock // InitMECC(W) [5] 1:Init Main ECC decoder/encoder. // InitSECC(W) [4] 1:Init Spare ECC decoder/encoder. // Reg_nCE [1] 0:nFCE=0, 1:nFCE=1. // NANDC Enable [0] operating mode. 0:Disable, 1:Enable.#endif NF_Reset();}void LED_blink(int status){ u32 led_stt; if(status == WR_STATUS) NAND_LED ^= MBA2440_LED1; else NAND_LED ^= MBA2440_LED2; return;}#endif // (CONFIG_COMMANDS & CFG_CMD_NAND)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -