📄 fmd.cpp
字号:
total Flash block size by the number of bytes per sector and the number
bytes for the sector metadata.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{
pFlashInfo->flashType = NOR;
pFlashInfo->dwNumBlocks = g_FMDInfo.TotalFlashBlocks;
pFlashInfo->dwBytesPerBlock = g_FMDInfo.BlockSize;
pFlashInfo->wDataBytesPerSector = SECTOR_SIZE;
pFlashInfo->wSectorsPerBlock = g_FMDInfo.SectorsPerBlock;
return(TRUE);
}
/*
@func BOOLEAN | UnlockBlock | Unlocks the specified flash block.
@rdesc TRUE returned on success, FALSE on failure.
@comm
@xref
*/
BOOLEAN SetBlockLock(BLOCK_ID blockID, ULONG NumBlocks, BOOL bLock)
{
ULONG ulStatus = 0;
volatile ULONG ulBlockAddress = 0;
BOOL bLastMode = SetKMode(TRUE);
int j;
#if 0
#if 1//flash_debug
RETAILMSG(1, (TEXT("SetBlockLock ID =%x num=%x).\r\n"),blockID,NumBlocks));
#endif
SetWriteProtect(FALSE);
while (NumBlocks--)
{
// Compute the block address.
ulBlockAddress = g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);
if(GetEraseFlashSectorIndex(ulBlockAddress-g_FMDInfo.ChipBaseAddress)==FALSE)
{
RETAILMSG(1, (TEXT("ERASE Block error,not aligned\r\n")));
return FALSE;
}
if(g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize)
{
// Clear the status register.
//WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
// Set or Clear the block lock bit and confirm.
WRITE_COMMAND(ulBlockAddress, BLOCK_LOCK_CMD);
if (bLock)
{
WRITE_COMMAND(ulBlockAddress, BLOCK_SETLOCK_CMD);
}
else
{
WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
}
// Wait for status...
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
do
{
//WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
}
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK));
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
// TODO
}
else
{
for(j = g_FMDInfo.gdwCurEraseBlock; j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++)
{
// Clear the status register.
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
// Set or Clear the block lock bit and confirm.
WRITE_COMMAND(ulBlockAddress, BLOCK_LOCK_CMD);
if (bLock)
{
WRITE_COMMAND(ulBlockAddress, BLOCK_SETLOCK_CMD);
}
else
{
WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
}
// Wait for status...
do
{
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
}
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK));
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
}
}
++blockID;
}
SetWriteProtect(TRUE);
SetKMode(bLastMode);
#if 1//flash_debug
RETAILMSG(1, (TEXT("SetBlockLock --over ID =%x num=%x).\r\n"),blockID,NumBlocks));
#endif
return(TRUE);
#endif
#ifdef flash_amd
return FALSE;
#endif
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_ReadSector()
Description: Reads the requested sector data and/or sector metadata from the
Flash media.
Notes: Notice that although each byte of a NOR Flash block is individually
addressable, the media is still logically broken up into sectors.
Thus, for each sector request, we must determine where this data
resides in the respective Flash block (see note above).
By default, the NOR Flash is configured in READ ARRAY MODE so there
is no need to set any control lines to access the media. The data
can just be read directly from the media (like RAM).
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
volatile SECTOR_ADDR physicalSectorAddr = 0;
volatile ULONG ulBlockAddress = 0;
BLOCK_ID blockID = 0;
DWORD i = 0;
int j;
BOOL bLastMode;
#if flash_debug
RETAILMSG(1, (TEXT("FMD_ReadSector: (startAdd =%x num=%x) sectot_addr=%x,sector_info %x.\r\n"),startSectorAddr,dwNumSectors,
pSectorBuff,pSectorInfoBuff));
#endif
//----- 1. Check the input parameters -----
// NOTE: The FAL insures that the starting sector address is in the allowable range.
if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
{
return(FALSE);
}
//----- 2. Process the read request(s)... -----
bLastMode = SetKMode(TRUE);
SetWriteProtect(FALSE);
for(i = startSectorAddr ; i < (startSectorAddr + dwNumSectors) ; i++)
{
//----- Determine the block this physical sector resides in -----
blockID = (i / g_FMDInfo.SectorsPerBlock);
//----- Compute the physical address for the requested -----
// Note we do this differently based on whether the caller wants us to read the sector information structure as well. Since we're
// dealing with a NOR flash which is XIP-able, one might want to use this function to read from an XIP region (i.e., no sector information
// structures in flash).
//
if (!g_bXIPMode)
physicalSectorAddr = g_FMDInfo.BaseAddress + i*(SECTOR_SIZE + sizeof(SectorInfo)) + (blockID * g_FMDInfo.UnusedBytesPerBlock);
else
physicalSectorAddr = g_FMDInfo.BaseAddress + (i*SECTOR_SIZE);
ulBlockAddress = (ULONG)(physicalSectorAddr - (physicalSectorAddr % g_FMDInfo.BlockSize));
if(GetEraseFlashSectorIndex(ulBlockAddress-g_FMDInfo.ChipBaseAddress)==FALSE)
{
RETAILMSG(1, (TEXT("ERASE Block error,not aligned\r\n")));
return FALSE;
}
#if flash_debug
RETAILMSG(1, (TEXT("blockID=%x,physicalSectorAddr=%x,g_bXIPMode=%x,ulBlockAddress=%x,g_FMDInfo.gdwCurEraseRegion=%x,gdwCurEraseBlock=%x.\r\n"),
blockID,physicalSectorAddr,g_bXIPMode,ulBlockAddress,g_FMDInfo.gdwCurEraseRegion,g_FMDInfo.gdwCurEraseBlock));
#endif
if(g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize)
{
#if flash_debug
RETAILMSG(1, (TEXT("1 \r\n")));
#endif
#if 0
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
#endif
#ifdef flash_amd
WRITE_COMMAND(g_FMDInfo.ChipBaseAddress, AMD_RESET);
#endif
#if flash_debug
RETAILMSG(1, (TEXT("2 \r\n")));
#endif
//----- Read the necessary sector data -----
if(pSectorBuff)
{
memcpy(pSectorBuff, (CONST PVOID)physicalSectorAddr, SECTOR_SIZE);
pSectorBuff += SECTOR_SIZE;
}
#if flash_debug
RETAILMSG(1, (TEXT("3 \r\n")));
#endif
//----- Read the necessary SectorInfo data (metadata) -----
if(!g_bXIPMode && pSectorInfoBuff)
{
// The metadata bytes are read directly into the SectorInfo structure...
memcpy(pSectorInfoBuff, (CONST PVOID)(physicalSectorAddr+SECTOR_SIZE), sizeof(SectorInfo));
pSectorInfoBuff += sizeof(SectorInfo);
}
#if flash_debug
RETAILMSG(1, (TEXT("4 \r\n")));
#endif
#if flash_debug
RETAILMSG(1, (TEXT("read sector %x\r\n"),physicalSectorAddr,ulBlockAddress));
#endif
}
else
{
#if flash_debug
RETAILMSG(1, (TEXT("5 \r\n")));
#endif
for(j = g_FMDInfo.gdwCurEraseBlock; j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++)
{
#if 0
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
#endif
#ifdef flash_amd
WRITE_COMMAND(g_FMDInfo.ChipBaseAddress, AMD_RESET);
#endif
ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
#if flash_debug
RETAILMSG(1, (TEXT("6 \r\n")));
#endif
}
#if flash_debug
RETAILMSG(1, (TEXT("7 \r\n")));
#endif
//----- Read the necessary sector data -----
if(pSectorBuff)
{
memcpy(pSectorBuff, (CONST PVOID)physicalSectorAddr, SECTOR_SIZE);
pSectorBuff += SECTOR_SIZE;
}
#if flash_debug
RETAILMSG(1, (TEXT("8 \r\n")));
#endif
//----- Read the necessary SectorInfo data (metadata) -----
if(!g_bXIPMode && pSectorInfoBuff)
{
// The metadata bytes are read directly into the SectorInfo structure...
memcpy(pSectorInfoBuff, (CONST PVOID)(physicalSectorAddr+SECTOR_SIZE), sizeof(SectorInfo));
pSectorInfoBuff += sizeof(SectorInfo);
}
#if flash_debug
RETAILMSG(1, (TEXT("9 \r\n")));
#endif
}
}
SetWriteProtect(TRUE);
SetKMode(bLastMode);
#if flash_debug
RETAILMSG(1, (TEXT("FMD_ReadSector: over.\r\n") ));
#endif
return(TRUE);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_WriteSector()
Description: Writes the requested sector data and/or sector metadata to the
Flash media.
Notes: Notice that although each byte of a NOR Flash block is individually
addressable, the media is still logically broken up into sectors.
Thus, for each sector request, we must determine where to put the
data in each respective Flash block (see note above).
By default, the NOR Flash is configured in READ ARRAY MODE we need
to set some control lines to prepare for the WRITE operation.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
volatile SECTOR_ADDR physicalSectorAddr = 0;
BLOCK_ID blockID = 0;
DWORD i = 0;
DWORD j = 0;
DWORD k = 0;
volatile ULONG ulBlockAddress = 0;
BOOL bLastMode;
DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
LPBYTE pBuffer = pSectorBuff;
USHORT usBufferSize = g_bPairedFlash ? (1 << g_FMDInfo.Geometry.WriteBuffSize) * 2 : (1 << g_FMDInfo.Geometry.WriteBuffSize);
BOOL fRet = FALSE;
ULONG nResult = 0 ;
#if flash_debug
RETAILMSG(1, (TEXT("FMD_WriteSector: startAdd =%x num=%x) sector_add=%x sectorinfo_add=%x.\r\n"),startSectorAddr,dwNumSectors,
pSectorBuff,pSectorInfoBuff));
#endif
#ifdef READ_FROM_REGISTRY
BYTE cTempBuffer[SECTOR_SIZE];
#endif
//----- 1. Check the input parameters -----
// NOTE: The FAL insures that the starting sector address is in the allowable range.
if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
{
return(FALSE);
}
//----- 2. Process the write request(s)... -----
bLastMode = SetKMode(TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -