📄 fmd.cpp
字号:
exit:
//----- 3. Put the Flash back into READ ARRAY mode -----
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
SetWriteProtect(TRUE);
SetKMode(bLastMode);
#if flash_debug
RETAILMSG(1, (TEXT("FMD_WriteSector: over %x \r\n"),fRet ));
#endif
return fRet;
}
//****************************************************************************
// DelayuS
//****************************************************************************
// Delays a certian number of microseconds.
//
//
static void DelayInuSec(ULONG ulMicroSec)
{
LARGE_INTEGER liStart, liCurrent;
BOOL b;
b = QueryPerformanceCounter(&liStart);
ASSERT(b);
do
{
Sleep(0);
b = QueryPerformanceCounter(&liCurrent);
ASSERT(b);
} while((liStart.QuadPart + (LONGLONG)ulMicroSec) >=liCurrent.QuadPart);
}
#if have_buffer_write
DWORD DoBufferedWrite(volatile ULONG ulBlockAddress,
volatile SECTOR_ADDR physicalSectorAddr,
PUCHAR pBuffer,
USHORT NumWriteBytes)
{
DWORD k = 0;
ULONG ulCount,ulCount1=0;
DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
DWORD dwWordCount = (NumWriteBytes / dwBusWidth);
PULONG pLongBuffer = (PULONG)pBuffer;
PUSHORT pShortBuffer = (PUSHORT)pBuffer;
volatile PUSHORT pusDest16;
pusDest16= (PUSHORT)physicalSectorAddr;
SetBlockLock((ulBlockAddress-g_FMDInfo.BaseAddress)/g_FMDInfo.BlockSize, 1, FALSE);
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
for(k = 0 ; k < dwWordCount ; k += 1)
{
//RETAILMSG(1, (TEXT("DoWordWrite: write over 0 \r\n")));
if (g_bPairedFlash)
{
//WRITE_ULONG (physicalSectorAddr + k, 0x400040);
//WRITE_ULONG (physicalSectorAddr + k, *pLongBuffer++);
//DelayInuSec(10);
//WRITE_ULONG (physicalSectorAddr + k, *(physicalSectorAddr+k));
//DelayInuSec(1);
*((ULONG *)physicalSectorAddr+(ulCount1>>2)) = 0x00400040;
//DelayInuSec(100);
//ulCount = 0;
//WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
//while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
//{
// DelayInuSec(1);
// if ( ulCount++ == 1000 )
// {
// RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 0\r\n")));
// return 0;
// }
//}
//WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
*((ULONG *)physicalSectorAddr+(ulCount1>>2)) = *(pLongBuffer+(ulCount1>>2));
/*
ulCount = 0;
while((*pLongBuffer)!=(*((PULONG)physicalSectorAddr + k) ) )
{
DelayInuSec(1);
if ( ulCount++ == 1000000 )
{
RETAILMSG(1, (TEXT("DoWordWrite: Timed out writing buffered data 1\r\n")));
return 0;
}
}
*/
}
else
{
//*((USHORT *)physicalSectorAddr+(ulCount1>>1)) = 0x0040;
//*((USHORT *)physicalSectorAddr+(ulCount1>>1)) = *(pShortBuffer+(ulCount1>>1));
pusDest16[ulCount1>>1] = 0x0040;
pusDest16[ulCount1>>1] = pShortBuffer[ulCount1>>1];
}
//DelayInuSec(100);
//RETAILMSG(1, (TEXT("DoWordWrite: write over 1 \r\n")));
ulCount = 0;
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 1\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
//RETAILMSG(1, (TEXT("DoWordWrite: write over 2 \r\n")));
if (g_bPairedFlash)
{
ulCount1 += sizeof(ULONG);
}
else
{
ulCount1 += sizeof(USHORT);
}
}
//RETAILMSG(1, (TEXT("DoWordWrite: write over\r\n")));
//DelayInuSec(10);
//
//
//
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
ulCount1 =0;
for(k = 0 ; k < dwWordCount ; k += 1)
{
if (g_bPairedFlash)
{
/*
if(*((ULONG *)physicalSectorAddr+(ulCount1>>2)) != *(pLongBuffer+(ulCount1>>2)))
{
RETAILMSG(1, (TEXT("DoWordWrite: mismath add=%x value=%x shoud-value %x\r\n"),
physicalSectorAddr + k,
((ULONG *)physicalSectorAddr + k),
*pLongBuffer));
}
ulCount1 += sizeof(ULONG);
*/
//DelayInuSec(100);
if( *((ULONG *)physicalSectorAddr + k)!=*(pLongBuffer+k) )
{
RETAILMSG(1, (TEXT("DoWordWrite: mismath add=%x value= %x should value=%x\r\n"), physicalSectorAddr + k,*((ULONG *)physicalSectorAddr + k), *(pLongBuffer+k) ));
}
}
else
{
if( pusDest16[ulCount1>>1] !=pShortBuffer[ulCount1>>1])
{
RETAILMSG(1, (TEXT("DoWordWrite: mismath add=%x value=%x shoud-value %x\r\n"),
physicalSectorAddr + k,
pusDest16[ulCount1>>1] ,
pShortBuffer[ulCount1>>1] ));
}
ulCount1 += sizeof(USHORT);
}
}
return NumWriteBytes;
}
#else
DWORD DoBufferedWrite(volatile ULONG ulBlockAddress,
volatile SECTOR_ADDR physicalSectorAddr,
PUCHAR pBuffer,
USHORT NumWriteBytes)
{
DWORD k = 0;
DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
ULONG ulCount;
// Let the flash know the size of the buffer we plan to send (note that this is a 0-based word count and we simulatenously
// write it to both flash parts (upper and lower).
DWORD dwWordCount = (NumWriteBytes / dwBusWidth) - 1;
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
WRITE_COMMAND(ulBlockAddress, BUFFER_WRITE_CMD);
// DelayInuSec(1000);
ulCount = 0;
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 0\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
// RETAILMSG(1, (TEXT("DoBufferedWrite: dwWordCount = %d should 15 \r\n"), dwWordCount));
if (g_bPairedFlash)
{
PULONG pLongBuffer = (PULONG)pBuffer;
WRITE_ULONG (ulBlockAddress, (dwWordCount << 16) | dwWordCount);
for(k = 0 ; k < NumWriteBytes ; k += dwBusWidth)
{
WRITE_ULONG (physicalSectorAddr + k, *pLongBuffer++);
ulCount = 0;
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 1\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
}
}
else
{
PUSHORT pShortBuffer = (PUSHORT)pBuffer;
WRITE_USHORT (ulBlockAddress, (USHORT)dwWordCount);
for(k = 0 ; k < NumWriteBytes ; k += dwBusWidth)
{
WRITE_USHORT (physicalSectorAddr + k, *pShortBuffer++);
ulCount = 0;
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 2\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
}
}
// Now program the buffer into flash...
//
WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
// DelayInuSec(100);
ulCount = 0;
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 3\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
return NumWriteBytes;
}
#endif
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_GetBlockStatus()
Description: Returns the status of a block. For read-only blocks, checks the sector
info data for the first sector of the block. Block is always good, so no need to check.
Returns: Block status.
------------------------------------------------------------------------------*/
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
SECTOR_ADDR Sector = blockID * g_FMDInfo.SectorsPerBlock;
SectorInfo SI;
DWORD dwResult = 0;
#if flash_debug
RETAILMSG(1, (TEXT("FMD_GetBlockStatus: id =%x ).\r\n"), blockID));
#endif
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;
#if flash_debug
RETAILMSG(1, (TEXT("FMD_GetBlockStatus: over. %x\r\n"),dwResult ));
#endif
return dwResult;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_SetBlockStatus()
Description: Sets the status of a block.
Returns: TRUE if no errors in setting.
------------------------------------------------------------------------------*/
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
#if flash_debug
RETAILMSG(1, (TEXT("FMD_SetBlockStatus: id =%x status =%x).\r\n"), blockID,dwStatus));
#endif
if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
SECTOR_ADDR Sector = blockID * g_FMDInfo.SectorsPerBlock;
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;
}
}
#if flash_debug
RETAILMSG(1, (TEXT("FMD_SetBlockStatus over: id =%x status =%x).\r\n"), blockID,dwStatus));
#endif
return TRUE;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_EraseBlock()
Description: Erases the specified Flash block.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
volatile ULONG ulBlockAddress = 0;
ULONG ulStatus = 0;
BOOL bLastMode = SetKMode(TRUE);
int i,j;
#if flash_debug
RETAILMSG(1, (TEXT("FMD_EraseBlock: id =%x ).\r\n"), blockID));
#endif
// Determine the address for the specified block.
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)
{
if(SetBlockLock(blockID, 1, FALSE)==FALSE)
{
RETAILMSG(1, (TEXT("IntelFlashClearLockBits: id =%x ).\r\n"), blockID));
return FALSE;
}
SetWriteProtect(FALSE);
// Issue erase and confirm command.
// Note: eventually this should be changed to issue mass block erases, then loop to
// verify each completes.
WRITE_COMMAND(ulBlockAddress, BLOCK_ERASE_CMD);
WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
do
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -