📄 nand.cpp
字号:
OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks));
while (dwNumBlocks--)
{
// If the block is marked bad, skip to next block. Note that the assumption in our error checking
// is that any truely bad block will be marked either by the factory during production or will be marked
// during the erase and write verification phases. If anything other than a bad block fails ECC correction
// in this routine, it's fatal.
OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));
if (g_ImageType == IMAGE_TYPE_LOADER)
{
FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1);
// Stepldr & Eboot image in nand flash
// block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 ))
{
++dwBlock;
++dwNumBlocks; // Compensate for fact that we didn't write any blocks.
continue;
}
if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
}
if (!FMD_EraseBlock(dwBlock))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
return FALSE;
}
if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf,g_ImageType))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
++dwBlock;
pbBuffer += g_FlashInfo.dwBytesPerBlock;
}
if (g_ImageType == IMAGE_TYPE_LOADER)
{
g_pTOC->id[0].dwLoadAddress = dwImageStart;
g_pTOC->id[0].dwJumpAddress = 0;
g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
}
OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n")));
return TRUE;
}
/*
int CorrectECC8Data(unsigned char *pEncodingBaseAddr)
{
unsigned int i,uErrorByte[9];
unsigned char uErrorBit[9];
unsigned int uErrorType;
uErrorType = (s2450NAND->NF8ECCERR0>>25)&0xf;// Searching Error Type //How many Error bits does exist?
uErrorByte[1] = s2450NAND->NF8ECCERR0&0x3ff;// Searching Error Byte //Where is the error byte?
uErrorByte[2] = (s2450NAND->NF8ECCERR0>>15)&0x3ff;
uErrorByte[3] = (s2450NAND->NF8ECCERR1)&0x3ff;
uErrorByte[4] = (s2450NAND->NF8ECCERR1>>11)&0x3ff;
uErrorByte[5] = (s2450NAND->NF8ECCERR1>>22)&0x3ff;
uErrorByte[6] = (s2450NAND->NF8ECCERR2)&0x3ff;
uErrorByte[7] = (s2450NAND->NF8ECCERR2>>11)&0x3ff;
uErrorByte[8] = (s2450NAND->NF8ECCERR2>>22)&0x3ff;
uErrorBit[1] = s2450NAND->NFMLC8BITPT0&0xff;// Searching Error Bit //Where is the error bit?
uErrorBit[2] = (s2450NAND->NFMLC8BITPT0>>8)&0xff;
uErrorBit[3] = (s2450NAND->NFMLC8BITPT0>>16)&0xff;
uErrorBit[4] = (s2450NAND->NFMLC8BITPT0>>24)&0xff;
uErrorBit[5] = s2450NAND->NFMLC8BITPT1&0xff;
uErrorBit[6] = (s2450NAND->NFMLC8BITPT1>>8)&0xff;
uErrorBit[7] = (s2450NAND->NFMLC8BITPT1>>16)&0xff;
uErrorBit[8] = (s2450NAND->NFMLC8BITPT1>>24)&0xff;
if(uErrorType == 0x0)
{
RETAILMSG(1, (TEXT("++++++++++ ECC No ERROR +++++++++++\r\n")));
return 0;
}
if(uErrorType == 0x9)
{
RETAILMSG(1, (TEXT("++++++++++ ECC Uncorrectable ERROR +++++++++++\r\n")));
return 1;
}
for(i=1;i<=uErrorType ;i++)
{
if(uErrorByte[i] < 512)
pEncodingBaseAddr[uErrorByte[i]]^=uErrorBit[i];
else
{;}
}
RETAILMSG(1, (TEXT("++++++++++ ECC correctable ERROR +++++++++++\r\n")));
return 0;
}
*/
BOOL FMD_LB_WriteSector_Steploader(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors, int mode)
{
DWORD i;
UINT16 nSectorLoop;
volatile DWORD wrdata;
int NewSpareAddr = 0x0;
int NewDataAddr = 0;
int NewSectorAddr = startSectorAddr;
MECC8 t8MECC[4];
//Check Parameters.
if (!pSectorBuff && !pSectorInfoBuff)
{
return(FALSE);
}
if ( dwNumSectors > 1 )
{
RETAILMSG(1, (TEXT("######## FATAL ERROR => FMD::FMD_WriteSector->dwNumsectors is bigger than 1. \r\n")));
return FALSE;
}
BOOL bLastMode = SetKMode(TRUE); // dummy function.
s2450NAND->NFCONF = (s2450NAND->NFCONF & ~(1<<30)) | (1<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
s2450NAND->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9);
s2450NAND->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));
// Enable Chip
NF_nFCE_L(); // NFCONT狼 [1]甫 0栏肺 努府绢 ... Force nFCE to low
// 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);
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
for(i=0; i<SECTOR_SIZE/sizeof(DWORD); i++)
{
wrdata = (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+0];
wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+1]<<8;
wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+2]<<16;
wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+3]<<24;
NF_WRDATA_WORD(wrdata);
}
}
else
{
WrPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);
}
NF_MECC_Lock();
while(!(s2450NAND->NFSTAT&(1<<7))) ;
s2450NAND->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);
/* //Debug Code :: Print Write Data
RETAILMSG(1, (TEXT("\r\n===================WRITE DATA=====================")));
for(i=0;i<512;i++)
{
if(i%16 == 0)
RETAILMSG(1, (TEXT("\r\n")));
RETAILMSG(1, (TEXT(" 0x%x "),*(pSectorBuff+(nSectorLoop*SECTOR_SIZE) + i)));
}
RETAILMSG(1, (TEXT("\r\n===================================================\r\n")));
RETAILMSG(1, (TEXT("FMD_LB_WriteSector_Steploader() : Sdata : 0x%x, 0x%x, 0x%x, 0x%x\r\n")
, t8MECC[nSectorLoop].n8MECC0
, t8MECC[nSectorLoop].n8MECC1
, t8MECC[nSectorLoop].n8MECC2
, t8MECC[nSectorLoop].n8MECC3));
*/
}
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
}
s2450NAND->NFSTAT |= (1<<4); //NF_CLEAR_RB
// Finish up the write operation
NF_CMD(CMD_WRITE2); // 0x10
// Wait for RB. 促 结龙 锭 鳖瘤 扁促赴促.
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(1, (TEXT("FMD_WriteSector() ######## Error Programming page %d!\n"), startSectorAddr));
// Disable the chip
NF_nFCE_H();
s2450NAND->NFCONF = (0<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
SetKMode(bLastMode); // Dummy function.
return FALSE;
}
else
{
NF_nFCE_H();
s2450NAND->NFCONF = (0<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
SetKMode(bLastMode); // Dummy function.
return TRUE;
}
/*
//============ Start of READ TEST CODE ============//
DWORD SpareDataDummy0;
DWORD SpareDataDummy1;
DWORD SpareDataDummy2;
DWORD SpareDataDummy3;
DWORD dwOffset;
DWORD dwCnt;
DWORD dwSpareAddress = 2048; //include Bad block
UINT8 tempdata[2048];
unsigned char uSctCnt = 4;
BOOL bRet = TRUE;
s2450NAND->NFCONF = ( s2450NAND->NFCONF&~(0x3<<23) ) |(2<<30)|(1<<23)|(0x7<<12)|(0x7<<8)|(0x7<<4);
s2450NAND->NFCONT = ( s2450NAND->NFCONT&~(0x1<<18) ) |(0<<18)|(0<<11)|(0<<10)|(0<<9)|(1<<6)|(1<<0); // Init NFCONT
s2450NAND->NFSTAT|= ((1<<6)|(1<<5)|(1<<4));
// NAND RESET
NF_nFCE_L();
NF_CMD(0xff);
NF_nFCE_H();
NF_MECC_Lock(); // Main ECC Lock
NF_nFCE_L();
s2450NAND->NFSTAT |= (1<<4); // RnB Clear
NF_CMD(CMD_READ);
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);
NF_ADDR((NewSectorAddr>>16)&0xff);
NF_CMD(CMD_READ3);
NF_DETECT_RB();
s2450NAND->NFSTAT |= (1<<4); // RnB Clear
//READ Spare ECC Data
for(dwCnt = 0; dwCnt < uSctCnt; dwCnt++)
{
NF_MECC_Lock(); // Main ECC Lock
s2450NAND->NFSTAT |= (1<<4); // RnB Clear
if(!dwCnt)
{
NF_CMD(CMD_READ);
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);
NF_ADDR((NewSectorAddr>>16)&0xff);
NF_CMD(CMD_READ3);
NF_DETECT_RB();
s2450NAND->NFSTAT |= (1<<4); // RnB Clear
}
else
{
dwOffset = dwCnt * 512;
NF_CMD(0x05);
NF_ADDR(dwOffset&0xFF);
NF_ADDR((dwOffset>>8)&0xFF);
NF_CMD(0xE0);
}
NF_MECC_UnLock(); // Main ECC Unlock
NF_RSTECC(); // Initialize ECC
//read 512byte
RdPage512(tempdata + 512*dwCnt);
dwOffset = 2048 + (dwCnt * 13);
NF_CMD(0x05);
NF_ADDR(dwOffset&0xFF);
NF_ADDR((dwOffset>>8)&0xFF);
NF_CMD(0xE0);
//read Spare ECC Data
SpareDataDummy0 = NF_RDDATA_WORD();
SpareDataDummy1 = NF_RDDATA_WORD();
SpareDataDummy2 = NF_RDDATA_WORD();
SpareDataDummy3 = NF_RDDATA_BYTE();
NF_MECC_Lock(); // Main ECC Lock
while(!(s2450NAND->NFSTAT&(1<<6))); // Check decoding done
s2450NAND->NFSTAT = s2450NAND->NFSTAT | (1<<6); // Decoding done Clear
while( s2450NAND->NF8ECCERR0 & (unsigned int)(1<<31) ) ; // 8bit ECC Decoding Busy Check.
if(CorrectECC8Data((tempdata + 512*dwCnt)))
{
return FALSE;
}
// Debug Code : Print Read Data
RETAILMSG(1, (TEXT("\r\n===================READ DATA=====================")));
for(i=0;i<512;i++)
{
if(i%16 == 0)
RETAILMSG(1, (TEXT("\r\n")));
RETAILMSG(1, (TEXT(" 0x%x "),*(tempdata+(dwCnt*SECTOR_SIZE) + i)));
}
RETAILMSG(1, (TEXT("\r\n===================================================\r\n")));
RETAILMSG(1, (TEXT("FMD_LB_WriteSector_Steploader() : Sdata : 0x%x, 0x%x, 0x%x, 0x%x\r\n")
, SpareDataDummy0
, SpareDataDummy1
, SpareDataDummy2
, SpareDataDummy3));
}
NF_nFCE_H();
s2450NAND->NFCONF = (0<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
SetKMode(bLastMode); // Dummy function.
return TRUE;
//============ End of READ TEST CODE ============//
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -