📄 fmd.cpp
字号:
//RETAILMSG(1,(TEXT("11 ECCBuf[%d]=0x%x\r\n"),i,ECCBuf[i]));
}
// Copmare with the ECC generated from the HW
if(ECCBuf[0] != ECCBufN[0] ||
ECCBuf[1] != ECCBufN[1] ||
ECCBuf[2] != ECCBufN[2] ||
ECCBuf[3] != ECCBufN[3])
{
RETAILMSG(1,(TEXT("FMD_ReadSector1G08 ECC Error,page %d parameters\r\n"), startSectorAddr));
RETAILMSG(1,(TEXT("FMD_ReadSector1G08 ECCBuf %x %x %x %x\r\n"),ECCBuf[0], ECCBuf[1],ECCBuf[2],ECCBuf[3]));
RETAILMSG(1,(TEXT("FMD_ReadSector1G08 ECCBufN %x %x %x %x\r\n"),ECCBufN[0], ECCBufN[1],ECCBufN[2],ECCBufN[3]));
//changed by yangrui for hardware ECC 20080416
// Copmare with the ECC generated from the HW
WRITE_REGISTER_ULONG(&s2440NAND->rNFMECCD0, (DWORD)((DWORD)(ECCBuf[1]<<16) | (DWORD)(ECCBuf[0]&0xff)));
WRITE_REGISTER_ULONG(&s2440NAND->rNFMECCD1, (DWORD)((DWORD)(ECCBuf[3]<<16) | (DWORD)(ECCBuf[2]&0xff)));
// Now try to correct them
ecc_state = READ_REGISTER_ULONG(&s2440NAND->rNFESTAT0);
RETAILMSG(1, (TEXT("FMD_ReadSector1G08: ecc_state=0x%x(page %d)\r\n"),(ecc_state & 0x3),startSectorAddr));
//The S3C2440 has the ECC status register,we can use it to corret the false.
if(((ecc_state & 0x3) == 0x2) || ((ecc_state & 0x3) == 0x3))
{
RETAILMSG(1, (TEXT("FMD_ReadSector1G08: Unable to correct the ECC error - Page #: %d\r\n"),startSectorAddr));
if((startSectorAddr >= (Register_Start_Block*NAND_PAGE_CNT)) && (startSectorAddr <= (Register_End_Block*NAND_PAGE_CNT)))
{
RETAILMSG(1, (TEXT("Page #: %d is Hive Register Block!!\r\n"),startSectorAddr));
}
else
{
NF_nFCE_H(); //changed by yangrui 20080620
bRet = FALSE;
}
}
else if((ecc_state & 0x3) == 0x1)
{
bitLocation = ((ecc_state >> 4) & (0x7));
byteLocation = ((ecc_state >> 7) & (0x7FF));
if(pSectorBuff[byteLocation] & (0x01 << bitLocation))
{
pSectorBuff[byteLocation] &= ~(0x01 << bitLocation); // 0->1 error, set bit to 0
}
else
{
pSectorBuff[byteLocation] |= (0x01 << bitLocation); // 1->0 error, set bit to 1
}
}
//changed 20080416 end
// Now try to correct them
//if(!ECC_CorrectData2048(pSectorBuff, ECCBuf, ECCBufN))
//{
//RETAILMSG(1,(TEXT("NandFlash FMD_ReadSector fatal ECC Error\r\n")));
//}//end if(!ECC_CorrectData2048(pSectorBuff, ECCBuf, ECCBufN))
}//end if(ECCBuf[0] != ECCBufN[0] ||
}//end if (pSectorBuff)
NF_nFCE_H(); // Deselect the flash chip.
RELEASEMUTEX(); //Relase when last!
return bRet;
}
/*
@func BOOL | FMD_EraseBlock | Erases the specified flash block.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_EraseBlock1G08(BLOCK_ID blockID)
{
BYTE Status;
ULONG blockPage = (blockID * NAND_PAGE_CNT); // Convert block address to page address.
GRABMUTEX(); //we should MUTEX first
NF_nFCE_L(); // Select the flash chip.
NF_WAITRnB();
NF_CLEAR_RB();
NF_CMD(CMD_ERASE); // Send block erase command.
// Address 2-cycle
NF_ADDR((blockPage)&0xff); // Page number=0
NF_ADDR((blockPage>>8)&0xff);
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_CMD(CMD_ERASE2); // Send block erase confirm command.
//NF_WAITRB(); // Wait for flash to complete command.
NF_DETECT_RB();
// Check the status
NF_CMD(CMD_STATUS);
Status = NF_RDDATA(); // Read command status.
NF_nFCE_H(); // Deselect the flash chip.
RELEASEMUTEX(); //Relase when last!
return((Status & 1) ? FALSE : TRUE);
}
/*
@func BOOL | FMD_WriteSector | Writes the specified data to the specified NAND flash sector/page.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_WriteSector1G08(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
BYTE Status;
ULONG SectorAddr = (ULONG)startSectorAddr;
DWORD i;
BOOL bRet = TRUE;
//20080228 ADD 2048 BYTE ECC
DWORD dwECCVal;
BYTE ECCBuf[4];
//20080228 BY YQX
if((!pSectorBuff && !pSectorInfoBuff) || dwNumSectors != 1)
{
RETAILMSG(1, (TEXT("Invalid parameters!\n")));
return FALSE;
}
GRABMUTEX(); //we should MUTEX first
NF_nFCE_L(); // Select the flash chip.
NF_WAITRnB();
//delete at 20080919
// NF_CLEAR_RB();
// NF_CMD(CMD_RESET); // Send reset command.
// for(i=0;i<10;i++);
// NF_DETECT_RB();
//delete at 20080919
ULONG blockPage = SectorAddr;//(((SectorAddr / NAND_PAGE_CNT) * NAND_PAGE_CNT) | (SectorAddr % NAND_PAGE_CNT));
if (!pSectorBuff)
{
NF_CLEAR_RB();
NF_CMD(CMD_WRITE); // Write 1st command
NF_ADDR((2048+0)&0xff); // Column (A[7:0]) = 0
NF_ADDR(((2048+0)>>8)&0xff); // A[11:8]
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_WRDATA( (pSectorInfoBuff->bBadBlock) );
// Write the first reserved field (DWORD)
NF_DATA_W4(pSectorInfoBuff->dwReserved1);
// Write OEM reserved flag
NF_WRDATA( (pSectorInfoBuff->bOEMReserved) );
// Write the second reserved field
NF_WRDATA( (pSectorInfoBuff->wReserved2 >> 8) & 0xff );
NF_WRDATA( (pSectorInfoBuff->wReserved2) & 0xff );
pSectorInfoBuff++;
}
else
{
//20080228 add 2048 ecc
NF_RSTECC(); // Initialize ECC.
NF_MECC_UnLock();
//20080228 by yqx
// NF_CMD(CMD_READ); // Send read command.
NF_CLEAR_RB();
NF_CMD(CMD_WRITE); // Write 1st command
NF_ADDR(0); // Column (A[7:0]) = 0
NF_ADDR(0); // A[11:8]
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
if( ((DWORD) pSectorBuff) & 0x3)
{
// Write the data
WrPage2048Unalign (pSectorBuff,(PULONG)&s2440NAND->rNFDATA);
}
else
{
#if (TRANS_MODE == C_LANG)
WrPage2048(pSectorBuff,(PULONG)&s2440NAND->rNFDATA); // Write page/sector data.
#elif (TRANS_MODE == DMA)
memcpy( pVirDMAbuf, pSectorBuff, 2048 );
// Nand to memory dma setting
s2440INT->rSRCPND=BIT_DMA0; // Init DMA src pending.
s2440DMAregs->rDISRC0=(unsigned)pPhyDMAbuffer; // Nand flash data register
s2440DMAregs->rDISRCC0=(0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
s2440DMAregs->rDIDST0=NFDATA; // Nand flash data register
s2440DMAregs->rDIDSTC0=(0<<1) | (1<<0); //arc=AHB,src_addr=fix
s2440DMAregs->rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(2048/4);
//Handshake,AHB,interrupt,(no-burst),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
s2440DMAregs->rDMASKTRIG0=(1<<1)|(1<<0);
while(!((s2440INT->rSRCPND) & BIT_DMA0)); // Wait until Dma transfer is done.
s2440INT->rSRCPND=BIT_DMA0;
#endif
}
// Read out the ECC value generated by HW
NF_MECC_Lock();
dwECCVal = NF_ECC();
if(pSectorInfoBuff)
{
// Write the bad block flag
NF_WRDATA( (pSectorInfoBuff->bBadBlock) );
// Write the first reserved field (DWORD)
NF_DATA_W4(pSectorInfoBuff->dwReserved1);
// Write OEM reserved flag
NF_WRDATA( (pSectorInfoBuff->bOEMReserved) );
// Write the second reserved field
NF_WRDATA( (pSectorInfoBuff->wReserved2 >> 8) & 0xff );
NF_WRDATA( (pSectorInfoBuff->wReserved2) & 0xff );
}
else
{
// Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
//we often erase block when write data to this sector, so write 0xff will not overlay the former data.
for(i=0; i<sizeof(SectorInfo); i++)
{
NF_WRDATA(0xff);
}
}
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector startSectorAddr %d\r\n"),startSectorAddr));
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECC %x\r\n"),dwECCVal));
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECCD0 %x\r\n"),dwECCD0));
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECCD1 %x\r\n"),dwECCD1));
// ECC stuff should be here
ECCBuf[0] = (BYTE) ((dwECCVal) & 0xff);
ECCBuf[1] = (BYTE) ((dwECCVal >> 8) & 0xff);
ECCBuf[2] = (BYTE) ((dwECCVal >> 16) & 0xff);
ECCBuf[3] = (BYTE) ((dwECCVal >> 24) & 0xff);
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECCBuf %x %x %x %x\r\n"),ECCBuf[3],ECCBuf[2],ECCBuf[1],ECCBuf[0]));
// Write the ECC value to the flash
for(i=0; i<4; i++)
{
NF_WRDATA(ECCBuf[i]);
}
pSectorBuff += NAND_PAGE_SIZE;
}//end else psectorbuff
NF_CLEAR_RB();
NF_CMD(CMD_WRITE2); // Send write confirm command.
// Wait for RB
NF_DETECT_RB(); // Wait tR(max 12us)
// Check the status
NF_CMD(CMD_STATUS);
Status = NF_RDDATA();
if (Status & 1)
{
NF_nFCE_H(); // Deselect the flash chip.
RETAILMSG(1,(TEXT("ERROR: FMD_WriteSector: failed sector write.\r\n")));
bRet = FALSE;
}
NF_nFCE_H(); // Deselect the flash chip.
RELEASEMUTEX(); //Relase when last!
return bRet;
}
static BOOL IsBlockBad1G08(BLOCK_ID blockID)
{
BYTE Data1,Data2;
BOOL bRet = FALSE;
SECTOR_ADDR blockPage = (blockID * NAND_PAGE_CNT);
GRABMUTEX(); //we should MUTEX first
NF_nFCE_L();
NF_WAITRnB();
NF_CLEAR_RB();
NF_CMD(0x00); // Read command
NF_ADDR((2048+0)&0xff);
NF_ADDR(((2048+0)>>8)&0xff);
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_CLEAR_RB();
NF_CMD(0x30); // 2'nd command
NF_DETECT_RB();
Data1=NF_RDDATA();
blockPage++; //in K9F1G08 Datasheet,you should check 1st and 2nd page in this block
NF_CLEAR_RB();
NF_CMD(0x00); // Read command
NF_ADDR((2048+0)&0xff);
NF_ADDR(((2048+0)>>8)&0xff);
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_CLEAR_RB();
NF_CMD(0x30); // 2'nd command
NF_DETECT_RB();
Data2=NF_RDDATA();
if((0xff != Data1) || (0xff != Data2))
{
RETAILMSG(1,(TEXT("IsBlockBad(%d): TRUE\r\n"),blockID));
bRet = TRUE;
}
NF_nFCE_H(); // Deassert the flash chip.
RELEASEMUTEX();
return bRet;
}
static BOOL MarkBlockBad1G08(BLOCK_ID blockID)
{
BYTE Status;
ULONG blockPage = (blockID * NAND_PAGE_CNT); // Convert block address to page address.
GRABMUTEX(); //we should MUTEX first
NF_nFCE_L(); // Select the flash chip.
NF_WAITRnB();
NF_CLEAR_RB();
NF_CMD(0x80); // Write 1st command
NF_ADDR((2048+0)&0xff); // 2060 = 0x080c
NF_ADDR(((2048+0)>>8)&0xff); // A[10:8]
NF_ADDR((blockPage)&0xff); // A[11;18]
NF_ADDR((blockPage>>8)&0xff); // A[26:19]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_WRDATA(0); // Write Bad block information
NF_CLEAR_RB();
NF_CMD(CMD_WRITE2); // Send write confirm command.
// Wait for RB
NF_DETECT_RB(); // Wait tR(max 12us)
// Get the status
NF_CMD(CMD_STATUS);
Status = NF_RDDATA(); // Read command status.
NF_nFCE_H(); // Deassert the flash chip.
RELEASEMUTEX();
return((Status & 1) ? FALSE : TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -