📄 fmd_lb.cpp
字号:
// Disable the chip
NF_nFCE_H();
return bRet;
}
BOOL NAND_LB_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
BOOL bRet = TRUE;
int NewSpareAddr = NAND_PAGE_SIZE;
int NewSectorAddr = sectorAddr;
DWORD SECCBuf1;
// Chip enable
NF_nFCE_L();
NF_CLEAR_RB();
// Write the command
// First, let's point to the spare area
NF_CMD(CMD_WRITE);
// Write the address
NF_ADDR((NewSpareAddr)&0xff);
NF_ADDR((NewSpareAddr>>8)&0xff);
NF_ADDR((NewSectorAddr)&0xff);
NF_ADDR((NewSectorAddr>>8)&0xff);
if(g_bNeedExtAddr)
{
NF_ADDR((NewSectorAddr>>16)&0xff);
}
// Initialize MECC module
NF_RSTECC();
NF_MECC_UnLock();
// Now let's write the SectorInfo data
// Write the first reserved field (DWORD)
NF_WRDATA_BYTE(pInfo->bBadBlock);
NF_WRDATA_WORD(pInfo->dwReserved1);
NF_WRDATA_BYTE(pInfo->bOEMReserved);
NF_MECC_Lock();
SECCBuf1 = NF_RDMECC0();
NF_WRDATA_BYTE(pInfo->wReserved2&0xff);
NF_WRDATA_BYTE((pInfo->wReserved2>>8)&0xff);
// Issue the write complete command
NF_CMD(CMD_RDI);
// Set Address to access SECC1 in Spare area
NF_ADDR((NewSpareAddr+NAND_SECC1_OFFSET)&0xff);
NF_ADDR(((NewSpareAddr+NAND_SECC1_OFFSET)>>8)&0xff);
// Write SECC1
NF_WRDATA_WORD(SECCBuf1);
// Issue the write complete command
NF_CMD(CMD_WRITE2);
// Check ready bit
NF_DETECT_RB(); // Wait tR(max 12us)
if ( NF_RDSTAT & STATUS_ILLACC )
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page (Illegal Access) %d!\n"), sectorAddr));
g_pNFConReg->NFSTAT = STATUS_ILLACC; // Write 1 to clear.
bRet = FALSE;
}
else
{
// Check the status of program
NF_CMD(CMD_STATUS);
if( NF_RDDATA_BYTE() & STATUS_ERROR) {
RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page %d!\n"), sectorAddr));
bRet = FALSE;
}
}
NF_nFCE_H();
return bRet;
}
BOOL FMD_LB_EraseBlock(BLOCK_ID blockID)
{
BOOL bRet = TRUE;
DWORD dwPageID = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
RETAILMSG(FMD_ZONE_FUNCTION, (TEXT("FMD_LB_EraseBlock 0x%x \r\n"), blockID));
// Enable the chip
NF_nFCE_L(); // Select the flash chip.
NF_CLEAR_RB();
// Issue command
NF_CMD(CMD_ERASE);
// Set up address
NF_ADDR((dwPageID) & 0xff);
NF_ADDR((dwPageID >> 8) & 0xff);
if(g_bNeedExtAddr)
{
NF_ADDR((dwPageID >> 16) & 0xff);
}
// Complete erase operation
NF_CMD(CMD_ERASE2);
// Wait for ready bit
NF_DETECT_RB(); // Wait tR(max 12us)
if ( NF_RDSTAT & STATUS_ILLACC )
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("LB######## Error Erasing block (Illegal Access) %d!\n"), blockID));
g_pNFConReg->NFSTAT = STATUS_ILLACC; // Write 1 to clear.
bRet = FALSE;
}
else
{
// Check the status
NF_CMD(CMD_STATUS);
if( NF_RDDATA_BYTE() & STATUS_ERROR)
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("LB######## Error Erasing block %d!\n"), blockID));
bRet = FALSE;
}
}
NF_nFCE_H(); // Select the flash chip.
return bRet;
}
DWORD FMD_LB_GetBlockStatus(BLOCK_ID blockID)
{
SECTOR_ADDR sectorAddr = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
SectorInfo SI;
DWORD dwResult = 0;
RETAILMSG(FMD_ZONE_FUNCTION, (TEXT("FMD_LB_GetBlockStatus (0x%x)0x%x \r\n"), blockID, sectorAddr));
if(!FMD_LB_ReadSector(sectorAddr, NULL, &SI, 1))
{
if(NAND_LB_IsBlockBad(blockID))
{
return BLOCK_STATUS_BAD;
}
else
{
return BLOCK_STATUS_UNKNOWN;
}
}
if(!(SI.bOEMReserved & OEM_BLOCK_READONLY))
{
dwResult |= BLOCK_STATUS_READONLY;
}
if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
{
dwResult |= BLOCK_STATUS_RESERVED;
}
if(SI.bBadBlock != 0xFF)
{
dwResult |= BLOCK_STATUS_BAD;
}
return dwResult;
}
BOOL FMD_LB_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
BYTE bStatus = 0;
if(dwStatus & BLOCK_STATUS_BAD)
{
if(!NAND_LB_MarkBlockBad (blockID))
{
return FALSE;
}
}
// We don't currently support setting a block to read-only, so fail if request is
// for read-only and block is not currently read-only.
if(dwStatus & BLOCK_STATUS_READONLY)
{
if(!(FMD_LB_GetBlockStatus(blockID) & BLOCK_STATUS_READONLY))
{
return FALSE;
}
}
return TRUE;
}
BOOL NAND_LB_MarkBlockBad(BLOCK_ID blockID)
{
DWORD dwStartPage = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
BOOL bRet = TRUE;
RETAILMSG(FMD_ZONE_FUNCTION, (TEXT("NAND_LB_MarkBlockBad 0x%x \r\n"), dwStartPage));
// Enable chip
NF_nFCE_L();
NF_CLEAR_RB();
// Issue command
// We are dealing with spare area
NF_CMD(CMD_WRITE);
// Set up address
NF_ADDR((NAND_PAGE_SIZE+LB_POS_BADBLOCK)&0xff);
NF_ADDR(((NAND_PAGE_SIZE+LB_POS_BADBLOCK)>>8)&0xff);
NF_ADDR((dwStartPage) & 0xff);
NF_ADDR((dwStartPage >> 8) & 0xff);
if(g_bNeedExtAddr)
{
NF_ADDR((dwStartPage >> 16) & 0xff);
}
NF_WRDATA_BYTE(BADBLOCKMARK);
// Copmlete the write
NF_CMD(CMD_WRITE2);
// Wait for RB
NF_DETECT_RB(); // Wait tR(max 12us)
if ( NF_RDSTAT & STATUS_ILLACC )
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page (Illegal Access) %d!\n")));
g_pNFConReg->NFSTAT = STATUS_ILLACC; // Write 1 to clear.
bRet = FALSE;
}
else
{
// Check the status of program
NF_CMD(CMD_STATUS);
if( NF_RDDATA_BYTE() & STATUS_ERROR)
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page %d!\n")));
bRet = FALSE;
}
}
// Disable chip select
NF_nFCE_H();
return bRet;
}
BOOL NAND_LB_IsBlockBad(BLOCK_ID blockID)
{
DWORD dwPageID = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
BOOL bRet = FALSE;
BYTE bFlag;
// Enable the chip
NF_nFCE_L();
NF_CLEAR_RB();
// Issue the command
NF_CMD(CMD_READ);
// Set up address
NF_ADDR((NAND_PAGE_SIZE+LB_POS_BADBLOCK)&0xff);
NF_ADDR(((NAND_PAGE_SIZE+LB_POS_BADBLOCK)>>8)&0xff);
NF_ADDR((dwPageID) & 0xff);
NF_ADDR((dwPageID >> 8) & 0xff);
if(g_bNeedExtAddr)
{
NF_ADDR((dwPageID >> 16) & 0xff);
}
NF_CMD(CMD_READ3);
// Wait for Ready bit
NF_DETECT_RB(); // Wait tR(max 12us)
// Now get the byte we want
bFlag = (BYTE)NF_RDDATA_BYTE();
if(bFlag != 0xff)
{
RETAILMSG(FMD_ZONE_STATUS, (TEXT("FMDLB: IsBlockBad - Page #: 0x%x \r\n"), dwPageID));
bRet = TRUE;
}
// Disable the chip
NF_nFCE_H();
return bRet;
}
#ifdef _IROMBOOT_
BOOL FMD_LB_WriteSector_Steploader(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
DWORD i;
UINT16 nSectorLoop;
int NewDataAddr = 0;
int NewSectorAddr = startSectorAddr;
MECC8 t8MECC[4];
//Check Parameters.
if (!pSectorBuff && !pSectorInfoBuff)
{
return(FALSE);
}
if ( dwNumSectors > 1 )
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("######## FATAL ERROR => FMD::FMD_WriteSector->dwNumsectors is bigger than 1. \r\n")));
return FALSE;
}
g_pNFConReg->NFCONF = (g_pNFConReg->NFCONF & ~(1<<30)) | (1<<23) | (NAND_TACLS <<12) | (NAND_TWRPH0 <<8) | (NAND_TWRPH1 <<4);
g_pNFConReg->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9);
g_pNFConReg->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));
// Enable Chip
NF_nFCE_L();
// Issue command
NF_CMD(CMD_WRITE); //0x80
// Setup address to write Main data
NF_ADDR((NewDataAddr)&0xff); // 2bytes for column address
NF_ADDR((NewDataAddr>>8)&0xff);
NF_ADDR((NewSectorAddr)&0xff); // 3bytes for row address
NF_ADDR((NewSectorAddr>>8)&0xff);
// if(g_bNeedExtAddr)
{
NF_ADDR((NewSectorAddr>>16)&0xff);
}
// initialize variable.
for(i = 0; i < 4; i++) {
t8MECC[i].n8MECC0 = 0x0;
t8MECC[i].n8MECC1 = 0x0;
t8MECC[i].n8MECC2 = 0x0;
t8MECC[i].n8MECC3 = 0x0;
}
// Write each Sector in the Page. (4 Sector per Page, Loop 4 times.)
for (nSectorLoop = 0; nSectorLoop < SECTORS_PER_PAGE; nSectorLoop++)
{
// Initialize ECC register
NF_MECC_UnLock();
NF_RSTECC();
// Special case to handle un-aligned buffer pointer.
if( ((DWORD) (pSectorBuff+nSectorLoop*SECTOR_SIZE)) & 0x3)
{
// Write the data
WrPage512Unalign(pSectorBuff+nSectorLoop*SECTOR_SIZE);
}
else
{
WrPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);
}
NF_MECC_Lock();
while(!(g_pNFConReg->NFSTAT&(1<<7)));
g_pNFConReg->NFSTAT|=(1<<7);
// Read out the ECC value generated by HW
t8MECC[nSectorLoop].n8MECC0 = NF_8MECC0();
t8MECC[nSectorLoop].n8MECC1 = NF_8MECC1();
t8MECC[nSectorLoop].n8MECC2 = NF_8MECC2();
t8MECC[nSectorLoop].n8MECC3 = (NF_8MECC3() & 0xff);
}
for(nSectorLoop = 0; nSectorLoop < 4; nSectorLoop++)
{
NF_WRDATA_WORD(t8MECC[nSectorLoop].n8MECC0); // 4 byte n8MECC0
NF_WRDATA_WORD(t8MECC[nSectorLoop].n8MECC1); // 4 byte n8MECC1
NF_WRDATA_WORD(t8MECC[nSectorLoop].n8MECC2); // 4 byte n8MECC2
NF_WRDATA_BYTE((t8MECC[nSectorLoop].n8MECC3) & 0xff); // 1 byte n8MECC3
}
g_pNFConReg->NFSTAT |= (1<<4); //NF_CLEAR_RB
// Finish up the write operation
NF_CMD(CMD_WRITE2); // 0x10
NF_DETECT_RB(); // Wait tR(max 12us)
NF_CMD(CMD_STATUS); // Read status command
for(i=0;i<3;i++); //twhr=60ns
if(NF_RDDATA_BYTE() & STATUS_ERROR)
{
RETAILMSG(FMD_ZONE_ERROR, (TEXT("FMD_WriteSector() ######## Error Programming page %d!\n"), startSectorAddr));
// Disable the chip
NF_nFCE_H();
g_pNFConReg->NFCONF = (0<<23) | (NAND_TACLS <<12) | (NAND_TWRPH0 <<8) | (NAND_TWRPH1 <<4);
return FALSE;
}
else
{
NF_nFCE_H();
g_pNFConReg->NFCONF = (0<<23) | (NAND_TACLS <<12) | (NAND_TWRPH0 <<8) | (NAND_TWRPH1 <<4);
return TRUE;
}
}
#endif
BOOL RAW_LB_ReadSector(UINT32 startSectorAddr, LPBYTE pSectorBuff, LPBYTE pSectorInfoBuff)
{
UINT32 nPageAddr = startSectorAddr;
DWORD i;
UINT32 nRetEcc = 0;
UINT32 nSectorLoop;
UINT32 nColAddr = 0;
if (!pSectorBuff && !pSectorInfoBuff)
return(FALSE);
NF_nFCE_L();
NF_CLEAR_RB();
NF_CMD(CMD_READ); // Send read command.
NF_ADDR((nColAddr)&0xff);
NF_ADDR((nColAddr>>8)&0xff);
NF_ADDR((nPageAddr)&0xff);
NF_ADDR((nPageAddr>>8)&0xff);
if (g_bNeedExtAddr)
{
NF_ADDR((nPageAddr>>16)&0xff);
}
NF_CMD(CMD_READ3); // 2nd command
NF_DETECT_RB(); // Wait for command to complete.
for (nSectorLoop = 0; nSectorLoop < 4; nSectorLoop++)
{
if( ((DWORD) (pSectorBuff+nSectorLoop*SECTOR_SIZE)) & 0x3)
{
RdPage512Unalign(pSectorBuff+nSectorLoop*SECTOR_SIZE);
}
else
{
RdPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE); // Read page/sector data.
}
}
for(i=0; i<64; i++)
{
*pSectorInfoBuff = NF_RDDATA_BYTE(); // read and trash the data
pSectorInfoBuff+=1;
}
NF_nFCE_H();
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -