📄 fmd.cpp
字号:
// Special case to handle un-aligned buffer pointer.
if( ((DWORD) pSectorBuff) & 0x3)
{
WrPage512Unalign (pSectorBuff);
}
else
{
WrPage512(pSectorBuff); // Write page/sector data.
}
// 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);
}
pSectorBuff += NAND_PAGE_SIZE;
}
NF_CMD(CMD_WRITE2); // Send write confirm command.
NF_WAITRB(); // Wait for command to complete.
Status = NF_RDDATA();
if (Status & 1)
{
SetKMode (bLastMode);
// EdbgOutputDebugString("ERROR: FMD_WriteSector: failed sector write.\r\n");
return(FALSE);
}
++SectorAddr;
}
NF_nFCE_H(); // Deselect the flash chip.
SetKMode (bLastMode);
return(TRUE);
}
VOID FMD_PowerUp(VOID)
{
}
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);
}
static BOOL IsBlockBad(BLOCK_ID blockID)
{
BYTE Data;
SECTOR_ADDR blockPage = (blockID * NAND_PAGE_CNT);
BOOL bLastMode = SetKMode(TRUE);
NF_nFCE_L(); // Select the flash chip.
NF_CMD(CMD_RESET); // Send reset command.
NF_WAITRB(); // Wait for flash to complete command.
NF_CMD(CMD_READ2); // Send read confirm command.
NF_ADDR(0); // Column = 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] */
NF_WAITRB(); // Wait for flash to complete command.
// TODO
Data = NF_RDDATA(); // Read command status.
Data = NF_RDDATA(); // Read command status.
Data = NF_RDDATA(); // Read command status.
Data = NF_RDDATA(); // Read command status.
Data = NF_RDDATA(); // Read command status.
Data = NF_RDDATA(); // Read command status.
if(0xff != Data)
{
SetKMode (bLastMode);
return(TRUE);
}
NF_nFCE_H(); // Deassert the flash chip.
SetKMode (bLastMode);
return(FALSE);
}
/*
@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_CMD(CMD_RESET); // Send reset command.
NF_WAITRB(); // Wait for flash to complete command.
NF_CMD(CMD_READ2); // Send read confirm command.
NF_CMD(CMD_WRITE); // Send write command.
NF_ADDR(0); // Column = 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] */
// TODO
NF_WRDATA(0xFF); // Write bad block marker.
NF_WRDATA(0xFF); // Write bad block marker.
NF_WRDATA(0xFF); // Write bad block marker.
NF_WRDATA(0xFF); // Write bad block marker.
NF_WRDATA(0xFF); // Write bad block marker.
NF_WRDATA(0); // Write bad block marker.
NF_CMD(CMD_WRITE2); // Send write confirm command.
NF_WAITRB(); // Wait for flash to complete command.
Status = NF_RDDATA(); // Read command status.
NF_nFCE_H(); // Deassert the flash chip.
SetKMode (bLastMode);
return((Status & 1) ? 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 + -