📄 fmd.cpp
字号:
NF_CMD(CMD_WRITE2); // Send write confirm command.
NF_WAITRB(); // Wait for flash to complete command.
do
{
NF_CMD(CMD_STATUS);
Status = NF_RDDATA(); // Read command status.
}while(!(Status & STATUS_READY));
if (Status & STATUS_ERROR)
{
NF_nFCE_H(); // Deselect the flash chip.
SetKMode (bLastMode);
return(FALSE);
}
pSectorInfoBuff++;
}
else
{
NF_CMD(CMD_READ); // Send read command.
NF_WAITRB(); // Wait for flash to complete command.
NF_CMD(CMD_WRITE); // Send write command.
NF_ADDR(0); // Column = 0.
NF_ADDR(blockPage & 0xff); // Page address.
NF_ADDR((blockPage >> 8) & 0xff);
if (NEED_EXT_ADDR)
NF_ADDR((blockPage >> 16) & 0xff);
NF_WAITRB(); // Wait for flash to complete command.
// Special case to handle un-aligned buffer pointer.
NF_RSTECC();
NF_MECC_UnLock();
if( ((DWORD) pSectorBuff) & 0x3)
{
WrPage512Unalign (pSectorBuff);
}
else
{
WrPage512(pSectorBuff); // Write page/sector data.
}
NF_MECC_Lock();
// Write the SectorInfo data to the media.
//
if(pSectorInfoBuff)
{
WrPageInfo((PBYTE)pSectorInfoBuff);
pSectorInfoBuff++;
}
else // Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
{
BYTE TempInfo[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
WrPageInfo(TempInfo);
}
MECC = NF_RDMECC0();
NF_WRDATA((UCHAR)((MECC ) & 0xff));
NF_WRDATA((UCHAR)((MECC >> 8) & 0xff));
NF_WRDATA((UCHAR)((MECC >> 16) & 0xff));
NF_WRDATA((UCHAR)((MECC >> 24) & 0xff));
NF_CMD(CMD_WRITE2); // Send write confirm command.
NF_WAITRB(); // Wait for flash to complete command.
do
{
NF_CMD(CMD_STATUS);
Status = NF_RDDATA(); // Read command status.
}while(!(Status & STATUS_READY));
if (Status & STATUS_ERROR)
{
NF_nFCE_H(); // Deselect the flash chip.
SetKMode (bLastMode);
return(FALSE);
}
pSectorBuff += NAND_PAGE_SIZE;
}
++SectorAddr;
}
NF_nFCE_H(); // Deselect the flash chip.
SetKMode (bLastMode);
return(TRUE);
}
VOID FMD_PowerUp(VOID)
{
// Set up initial flash controller configuration.
//
s2440NAND->NFCONF = (TACLS << 12) | /* CLE & ALE = HCLK * (TACLS + 1) */
(TWRPH0 << 8) | /* TWRPH0 = HCLK * (TWRPH0 + 1) */
(TWRPH1 << 4);
s2440NAND->NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);
s2440NAND->NFSTAT = 0x4;
}
VOID FMD_PowerDown(VOID)
{
}
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
return(TRUE);
}
BOOL FMD_Deinit(PVOID hFMD)
{
return(TRUE);
}
/*
@func BOOL | FMD_GetInfo | Provides information on the NAND flash.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{
if (!pFlashInfo)
return(FALSE);
pFlashInfo->flashType = NAND;
pFlashInfo->wDataBytesPerSector = NAND_PAGE_SIZE;
pFlashInfo->dwNumBlocks = NAND_BLOCK_CNT;
pFlashInfo->wSectorsPerBlock = NAND_PAGE_CNT;
pFlashInfo->dwBytesPerBlock = (pFlashInfo->wSectorsPerBlock * pFlashInfo->wDataBytesPerSector);
return(TRUE);
}
#define VALIDADDR 0x05 // S3C2440aNAND
static BOOL IsBlockBad(BLOCK_ID blockID)
{
DWORD dwPageID = blockID << 5;
BOOL bRet = FALSE;
BYTE wFlag;
BOOL bLastMode = SetKMode(TRUE);
NF_nFCE_L(); // Select the flash chip.
NF_CLEAR_RB();
NF_CMD(CMD_RESET); // Send reset command.
NF_WAITRB(); // Wait for flash to complete command.
// Issue the command
NF_CMD(CMD_READ2);
// Set up address
NF_ADDR(VALIDADDR);
NF_ADDR((dwPageID) & 0xff);
NF_ADDR((dwPageID >> 8) & 0xff);
if (NEED_EXT_ADDR)
NF_ADDR((dwPageID >> 16) & 0xff);
NF_WAITRB(); // Wait for flash to complete command.
// Now get the byte we want
wFlag = (BYTE) NF_RDDATA();
if(wFlag != 0xff) {
bRet = TRUE;
}
// Disable the chip
NF_nFCE_H();
SetKMode (bLastMode);
return bRet;
}
/*
@func DWORD | FMD_GetBlockStatus | Returns the status of the specified block.
@rdesc Block status (see fmd.h).
@comm
@xref
*/
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
SECTOR_ADDR Sector = (blockID * NAND_PAGE_CNT);
SectorInfo SI;
DWORD dwResult = 0;
if (IsBlockBad(blockID))
return BLOCK_STATUS_BAD;
if (!FMD_ReadSector(Sector, NULL, &SI, 1))
return BLOCK_STATUS_UNKNOWN;
if (!(SI.bOEMReserved & OEM_BLOCK_READONLY))
dwResult |= BLOCK_STATUS_READONLY;
if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
dwResult |= BLOCK_STATUS_RESERVED;
return(dwResult);
}
/*
@func BOOL | MarkBlockBad | Marks the specified block as bad.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
static BOOL MarkBlockBad(BLOCK_ID blockID)
{
BYTE Status;
ULONG blockPage = (blockID * NAND_PAGE_CNT); // Convert block address to page address.
BOOL bLastMode = SetKMode(TRUE);
NF_nFCE_L(); // Select the flash chip.
NF_WAITRB(); // Wait for flash to complete command.
NF_CMD(CMD_RESET); // Send reset command.
NF_WAITRB(); // Wait for flash to complete command.
NF_CMD(CMD_READ2); // Send read confirm command.
NF_WAITRB(); // Wait for flash to complete command.
NF_CMD(CMD_WRITE); // Send write command.
NF_ADDR(VALIDADDR); // Column = 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] */
if (NEED_EXT_ADDR)
NF_ADDR((blockPage >> 16) & 0xff); /* For block number A[25] */
NF_WAITRB(); // Wait for flash to complete command.
NF_WRDATA((UCHAR)0); // Write bad block marker.
NF_CMD(CMD_WRITE2); // Send write confirm command.
NF_WAITRB(); // Wait for flash to complete command.
do
{
NF_CMD(CMD_STATUS);
Status = NF_RDDATA(); // Read command status.
}while(!(Status & STATUS_READY));
NF_nFCE_H(); // Deassert the flash chip.
SetKMode (bLastMode);
return((Status & STATUS_ERROR) ? FALSE : TRUE);
}
/*
@func BOOL | FMD_SetBlockStatus | Marks the block with the specified block status.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
if (dwStatus & BLOCK_STATUS_BAD)
{
if (!MarkBlockBad(blockID))
return(FALSE);
}
if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
SECTOR_ADDR Sector = blockID * NAND_PAGE_CNT;
SectorInfo SI;
if (!FMD_ReadSector(Sector, NULL, &SI, 1)) {
return FALSE;
}
if (dwStatus & BLOCK_STATUS_READONLY) {
SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
}
if (dwStatus & BLOCK_STATUS_RESERVED) {
SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
}
if (!FMD_WriteSector (Sector, NULL, &SI, 1)) {
return FALSE;
}
}
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -