📄 amd.c
字号:
{
ulDataWritten = bIsPaired? *((volatile ULONG *)(ulProgramAddress)) :
*((volatile USHORT *)(ulProgramAddress));
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) != (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)))
{
ERRORMSG(ZONE_HAL_ERROR, (TEXT("Program failure: Poll cnt %d [0x%x] 0x%x : expect 0x%x\r\n"),
j, ulProgramAddress, ulDataWritten, ulDataToWrite)) ;
bSuccess = FALSE;
}
}
}
} // end poll for datum prog done
// Check for prog timeout.
if(!bDone && j == g_FlashProgInfo.ulMaxDatumProgTOFactor)
bSuccess = FALSE;
if(!bSuccess)
break;
// since the polling needs to occur on the last datum programmed
// to the buffer the math to advance the pointers
// for next datum is left until now
pulData = (ULONG *)((ULONG)pulData + dwBusWidth);
ulProgramAddress += dwBusWidth;
} // End prog datum loop
if(g_FlashProgInfo.bUnlockBypassSupport)
{
// Exit bypass mode
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_1_ADDR_RESET_BYPASS, CYCLE_1_DATA_RESET_BYPASS);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_2_ADDR_RESET_BYPASS, CYCLE_2_DATA_RESET_BYPASS);
}
}
// Use write buffer programming if at least 1 page of data to write
// and supported (write buffer size non zero).
// Refer to AMD's "Write buffer programming and page buffer read"
// application note for more details.
if(bSuccess && dwNumPages > 0)
{
// Find start sector address and size
ulFlashSectorAddr = pFlashDesc->FlashBase;
bDone = FALSE;
for(ulCurRegion = 0; !bDone && ulCurRegion < pFlashDesc->Geometry.NumEraseBlockRegions; ulCurRegion++)
{
// Get erase block size
ulSectorSize = bIsPaired?
2 * pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP :
pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP ;
ulNumRegionBlocks = (ULONG)(pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].NumIdentEraseBlocks + 1);
for(ulCurBlock = 0; !bDone && ulCurBlock < ulNumRegionBlocks; ulCurBlock++)
{
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("ulFlashSectorAddr 0x%x\r\n"), ulFlashSectorAddr));
if(ulProgramAddress >= ulFlashSectorAddr && ulProgramAddress < (ulFlashSectorAddr + ulSectorSize))
{
// Found sector, break
bDone = TRUE;
}
else
{
// Increment flash walk address
ulFlashSectorAddr += ulSectorSize;
}
}
}
// Program address may be middle of sector
ulSectorSize -= ulProgramAddress - ulFlashSectorAddr;
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Sector 0x%x Size 0x%x\r\n"),
ulFlashSectorAddr, ulSectorSize));
ulBufDatumSize = bIsPaired? (ulWriteBufferSize / sizeof(ULONG)) :
(ulWriteBufferSize / sizeof(USHORT));
for(i = 0; bSuccess && i < dwNumPages; i++)
{
bDone = FALSE;
#ifdef DEBUG
ulPageStart = ulProgramAddress;
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Page %d\r\n"), i));
for(j = 0; j < ulBufDatumSize; j++)
DEBUGMSG(1|ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x\r\n"),
(ulPageStart + j), bIsPaired? *((volatile ULONG *)(ulPageStart + j)) :
*((volatile USHORT *)(ulPageStart + j)) ));
#endif
ulDataToWrite = bIsPaired? *(ULONG *)pulData : *(USHORT *)pulData;
if(bIgnore0to1)
{
for(j = 0; j < (ulBufDatumSize); j++)
ulIgnoreBuffer[j] = bIsPaired? *((volatile ULONG *)ulProgramAddress + j): *((volatile USHORT *)ulProgramAddress + j);
ulDataToWrite &= ulIgnoreBuffer[0];
}
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_1_ADDR_UNLOCK_x16, CYCLE_1_DATA_UNLOCK);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_2_ADDR_UNLOCK_x16, CYCLE_2_DATA_UNLOCK) ;
WR_FLASH_REG_16(bIsPaired, ulProgramAddress, CYCLE_3_DATA_WR_BUFR);
WR_FLASH_REG_16(bIsPaired, ulProgramAddress, (ulBufDatumSize - 1));
WR_FLASH_16(bIsPaired, ulProgramAddress, ulDataToWrite);
for(j = 0; j < (ulBufDatumSize - 1); j++)
{
pulData = (ULONG *)((ULONG)pulData + dwBusWidth);
ulProgramAddress += dwBusWidth;
ulDataToWrite = bIsPaired? *(ULONG *)pulData : *(USHORT *)pulData;
if(bIgnore0to1)
ulDataToWrite &= ulIgnoreBuffer[j + 1];
WR_FLASH_16(bIsPaired, ulProgramAddress, ulDataToWrite);
}
WR_FLASH_REG_16(bIsPaired, ulFlashSectorAddr, CYCLE_1_DATA_WR_BUFR_PROGRAM);
#ifdef USE_OS_SERVICES
for(j = 0; bSuccess && !bDone && j < g_FlashProgInfo.ulMaxBufferProgTOFactor; j++)
{
StallExecution(g_FlashProgInfo.ulBufferProgTO_us);
#else
j = 0;
while(!bDone && bSuccess && j++ < CHECK_STATUS_TIMEOUT)
{
#endif
ulDataWritten = bIsPaired? *((volatile ULONG *)(ulProgramAddress)) :
*((volatile USHORT *)(ulProgramAddress));
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x : expect 0x%x\r\n"),
ulProgramAddress, ulDataWritten, ulDataToWrite));
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) == (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)))
{
if(ulDataWritten != ulDataToWrite)
{
ulDataWritten = bIsPaired? *((volatile ULONG *)(ulProgramAddress)) :
*((volatile USHORT *)(ulProgramAddress));
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x : expect 0x%x\r\n"),
ulProgramAddress, ulDataWritten, ulDataToWrite));
if(ulDataWritten == ulDataToWrite)
{
// page is programmed properly
bDone = TRUE;
}
else
{
// programming failure
ERRORMSG(ZONE_HAL_ERROR, (TEXT("program buffer failure [0x%x] 0x%x : expect 0x%x\r\n"),
ulProgramAddress, ulDataWritten, ulDataToWrite));
bSuccess = FALSE;
}
}
else
{
// page is programmed properly
bDone = TRUE;
}
}
else
{
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16)) == CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16))
{
ulDataWritten = bIsPaired? *((volatile ULONG *)(ulProgramAddress)) :
*((volatile USHORT *)(ulProgramAddress));
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) != (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)))
{
ERRORMSG(ZONE_HAL_ERROR, (TEXT("Program Buffer failure: Poll cnt %d [0x%x] 0x%x : expect 0x%x\r\n"),
j, ulProgramAddress, ulDataWritten, ulDataToWrite)) ;
bSuccess = FALSE;
}
}
else if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ1_X16)) == CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ1_X16))
{
ulDataWritten = bIsPaired? *((volatile ULONG *)(ulProgramAddress)) :
*((volatile USHORT *)(ulProgramAddress));
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) != (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)))
{
ERRORMSG(ZONE_HAL_ERROR, (TEXT("Program Buffer aborted: Poll cnt %d [0x%x] 0x%x : expect 0x%x\r\n"),
j, ulProgramAddress, ulDataWritten, ulDataToWrite)) ;
bSuccess = FALSE;
}
}
}
} // end page done poll
// Check for prog timeout.
#ifdef USE_OS_SERVICES
if(!bDone && j == g_FlashProgInfo.ulMaxBufferProgTOFactor)
#else
if(!bDone && j > CHECK_STATUS_TIMEOUT)
#endif
bSuccess = FALSE;
if(!bSuccess)
break;
if(bDone)
{
#ifdef DEBUG
for(j = 0; j < ulBufDatumSize; j++)
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x\r\n"),
(ulPageStart + j), bIsPaired? *((volatile ULONG *)(ulPageStart + j)) :
*((volatile USHORT *)(ulPageStart + j)) ));
#endif
// since the polling needs to occur on the last datum programmed
// to the buffer the math to advance the pointers
// for next page is left until now
ulLen -= ulWriteBufferSize;
pulData = (ULONG *)((ULONG)pulData + dwBusWidth);
ulProgramAddress += dwBusWidth;
ulSectorSize -= ulWriteBufferSize;
ulProgBytes += ulWriteBufferSize;
if(ulSectorSize == 0)
{
// Next sector
ulFlashSectorAddr = ulProgramAddress;
ulCurBlock++;
if(ulCurBlock >= ulNumRegionBlocks)
{
ulCurRegion++;
ulCurBlock = 0;
ulSectorSize = bIsPaired?
2 * pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP :
pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP ;
ulNumRegionBlocks = (ULONG)(pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].NumIdentEraseBlocks + 1);
}
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Sector 0x%x Size 0x%x\r\n"),
ulFlashSectorAddr, ulSectorSize));
}
}
} // end loop pages
}
// return to read array mode by issuing a soft reset
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_1_ADDR_RESET, CYCLE_1_DATA_RESET);
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("AMDx16_Program-\r\n")));
return bSuccess;
}
//-----------------------------------------------------------------------------
//
// Function: AMDx16_EraseSector
//
// Erases a sector of flash.
// For 16bit mode flash devices.
//
// Flash programming notes:
// During the embedded erase algorithm, DQ7 is 0. When the erase is complete
// the polling produces a 1 on DQ7. Just prior to the completion of an
// embedded erase operation, DQ7 may change asynchronousl with DQ6-DQ0 while
// output enable is asserted. In other words, the device will switch from
// providing status to providing data.
// **************************************************************************
//
// Parameters:
// pFlashDesc
// [in] pointer to NOR flash descriptor
//
// ulAddr
// [in] start address of sector to start erase
//
// Returns:
// FALSE on failure
//
//-----------------------------------------------------------------------------
BOOL AMDx16_EraseSector(NOR_FLASH_DESC *pFlashDesc, ULONG ulAddr)
{
ULONG ulFlashBase;
BOOL bIsPaired;
ULONG i;
ULONG ulDataWritten;
BOOL bDone;
volatile ULONG ulSectorAddress = ulAddr;
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("AMDx16_EraseSector+ 0x%x 0x%x\r\n"),
pFlashDesc, ulSectorAddress));
if(!pFlashDesc)
{
DEBUGMSG(ZONE_HAL_ERROR, (TEXT("AMDx16_EraseSector: null param\r\n")));
return FALSE;
}
ulFlashBase = pFlashDesc->FlashBase;
bIsPaired = pFlashDesc->PairedFlash;
bDone = FALSE;
// Issue erase sector command
// **************************
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_1_ADDR_UNLOCK_x16, CYCLE_1_DATA_UNLOCK);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_2_ADDR_UNLOCK_x16, CYCLE_2_DATA_UNLOCK);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_3_ADDR_CMD_x16, CYCLE_3_DATA_ERASE);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_4_ADDR_ERASE, CYCLE_4_DATA_ERASE);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_5_ADDR_ERASE, CYCLE_5_DATA_ERASE);
WR_FLASH_REG_INDEXED16(bIsPaired, ulSectorAddress, 0, CYCLE_6_DATA_SECTOR_ERASE);
#ifdef USE_OS_SERVICES
for(i = 0; i < g_FlashProgInfo.ulMaxSectorEraseTOFactor; i++)
{
Sleep(g_FlashProgInfo.ulSectorEraseTO_ms);
#else
// Wait for erase command to be accepted
i = 0;
while (i++ < CHECK_STATUS_TIMEOUT)
{
ulDataWritten = *((volatile USHORT *)(ulSectorAddress));
if (ulDataWritten & (1 << 3)) break;
}
i = 0;
while(!bDone && i++ < CHECK_STATUS_TIMEOUT)
{
#endif
ulDataWritten = bIsPaired? *((volatile ULONG *)(ulSectorAddress)) :
*((volatile USHORT *)(ulSectorAddress));
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x]->0x%x\r\n"),
ulSectorAddress, ulDataWritten));
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) == CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16))
{
// DQ7 on the high and low order devices is a 1,
// erase completed successfully.
// *********************************************
bDone = TRUE;
break;
}
else
{
// Test the device(s) to determine if a timeout has occurred.
// If the device was being erased (DQ7 -> 0) AND
// a timeout has occurred (DQ5 -> 1) then there is a failure.
// **********************************************************
if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16)) == CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16))
{
ERRORMSG(ZONE_HAL_ERROR, (TEXT("ERROR: Erase timeout Poll cnt %d - [0x%x] rd value[0]:0x%x\r\n"),
i, ulSectorAddress, ulDataWritten));
break;
}
}
}
// return to read array mode by issuing a soft reset
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_1_ADDR_RESET, CYCLE_1_DATA_RESET);
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("AMDx16_EraseSector-\r\n")));
return bDone;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -