flash.hpp
字号:
*(m_ptr+1) = *((DWORD*)(src)+1);
};
//
// Address manipulation operators
//
virtual DWORD operator [] (UINT offset)
{
return *(m_ptr+offset+offset);
};
};
/////////////////////////////////////////////////////////////////////
///+
template<class T> class CFlash
///
/// CFlash programming service class
///
{
private:
ADDRESS m_BaseAddress;
UINT m_NumberOfBlocks;
UINT m_SizeOfFlash;
ADDRESS* m_BlockEndTable;
FM_ERROR m_ErrCode;
// Assert flash memory operation error conidition
void FMAssertError( FM_ERROR err ) { m_ErrCode = err; };
// Check the error condition from status byte
BOOL CheckError(T*);
// Write a byte to the flash ROM
BOOL Write(T* pT, void* pSrc, BOOL blnIndicator=FALSE);
// Erase a data block (Bus is byte wide)
BOOL EraseBlock(T*);
// Get the block information of the flash chip
BOOL BlockInfo(T*, T*, T*);
public:
// Check if the supported flash chip is present
UINT Check(ADDRESS startAddr);
// Write a chunk of data into the flash ROM
BOOL WriteRegion(ADDRESS dest, ADDRESS src, UINT ulen);
// Erase a chunk of data in the flash ROM
BOOL EraseRegion(ADDRESS dest,UINT ulen);
// Show flash memory operation error coniditions
void ShowError();
};
/////////////////////////////////////////////////////////////////////
///+
template<class T> BOOL CFlash<T>::CheckError(T* pT)
///
/// Check the error condition from status byte
///
/// Return: TRUE - No error
/// FALSE - Error. Error code asserted
///
{
if ( !pT->IsError() ) return TRUE;
if ( pT->IsVppLowError() )
FMAssertError(Vpp_Low);
else if ( pT->IsProgramError() && pT->IsBlockEraseError() )
FMAssertError(Command_Sequence_Error);
else if ( pT->IsProgramError() )
FMAssertError(Program_Error);
else FMAssertError(Block_Erase_Error);
return FALSE;
}
/////////////////////////////////////////////////////////////////////
///+
template<class T> BOOL CFlash<T>::Write
(
T* pT,
void* pSrc,
BOOL blnIndicator
)
///
/// Write a unit of data into the flash ROM
///
/// Return: TRUE - Write operation is successful
/// FALSE - Error. Check error code for reason.
///
{
pT->IssueCommand(READ_ARRAY);
pT->IssueCommand(CLEAR_STATUS_REGISTER);
pT->IssueCommand(PROGRAM_SETUP);
pT->Copy(pSrc);
if (blnIndicator)
EdbgOutputDebugString(".");
startcount();
do {
pT->IssueCommand(READ_STATUS_REGISTER);
if ( pT->IsStateMachineReady() )
return CheckError(pT);
} while ( checkcount() < PROGRAM_TIMEOUT );
FMAssertError(Program_Timeout);
pT->IssueCommand(READ_ARRAY);
pT->IssueCommand(READ_ARRAY);
return FALSE;
}
/////////////////////////////////////////////////////////////////////
///+
template<class T> BOOL CFlash<T>::EraseBlock(T* pT)
///
/// Erase data block
///
/// Return: TRUE - Erase operation is successful
/// FALSE - Error. Check error code for reason.
///
{
pT->IssueCommand(READ_ARRAY);
pT->IssueCommand(CLEAR_STATUS_REGISTER);
pT->IssueCommand(ERASE_SETUP);
pT->IssueCommand(ERASE_RESUME);
EdbgOutputDebugString("[Erase Block] 0x%x", pT->m_ptr);
startcount();
do {
pT->IssueCommand(READ_STATUS_REGISTER);
if (pT->IsStateMachineReady())
return CheckError(pT);
} while ( checkcount() < ERASE_TIMEOUT );
FMAssertError(Block_Erase_Timeout);
pT->IssueCommand(READ_ARRAY);
pT->IssueCommand(READ_ARRAY);
return FALSE;
}
/////////////////////////////////////////////////////////////////////
///+
template<class T> BOOL CFlash<T>::BlockInfo
(
T* pCurUnit,
T* pBlkStart,
T* pBlkEnd
)
///
/// Get the block information of the flash chip given the the address
///
/// Return: TRUE - Got block number
/// FALSE - Address over flow
///
{
T sectionBase;
UINT uBockNumber;
//EdbgOutputDebugString("+CFlash::BlockInfo:pCurUnit->m_ptr=%X\r\n", pCurUnit->m_ptr);
if ( *pCurUnit < m_BaseAddress
|| *pCurUnit >= m_BaseAddress+m_SizeOfFlash )
{
FMAssertError(Address_Overflow);
return FALSE;
}
uBockNumber = 0;
sectionBase.Assign(m_BaseAddress);
*pBlkStart = sectionBase;
*pBlkEnd = sectionBase;
*pBlkEnd += m_BlockEndTable[0] * pCurUnit->Increment()/pCurUnit->ChipWidth();
//EdbgOutputDebugString(" Start: pCurUnit=%X pBlkStart=%X pBlkEnd=%X\r\n", pCurUnit->m_ptr, pBlkStart->m_ptr, pBlkEnd->m_ptr);
while (*pCurUnit > *pBlkEnd)
{
if (++uBockNumber >= m_NumberOfBlocks) {
uBockNumber = 0;
sectionBase.IssueCommand(READ_ARRAY);
sectionBase.IssueCommand(READ_ARRAY);
sectionBase = *pBlkEnd;
sectionBase += sectionBase.Increment()/pCurUnit->ChipWidth();
//EdbgOutputDebugString(" Pass boundary sectionBase=%X\r\n", sectionBase.m_ptr);
}
*pBlkStart = *pBlkEnd;
*pBlkStart += pBlkStart->Increment()/pBlkStart->ChipWidth();
*pBlkEnd = sectionBase;
*pBlkEnd += m_BlockEndTable[uBockNumber] * pCurUnit->Increment()/pCurUnit->ChipWidth();
//EdbgOutputDebugString(" Start1: pCurUnit=%X pBlkStart=%X pBlkEnd=%X\r\n",
// pCurUnit->m_ptr, pBlkStart->m_ptr, pBlkEnd->m_ptr);
}
//EdbgOutputDebugString("-CFlash::BlockInfo: *pCurUnit=%X *pBlkStart=%X *pBlkEnd=%X\r\n", pCurUnit->m_ptr, pBlkStart->m_ptr, pBlkEnd->m_ptr);
return TRUE;
}
extern "C" BOOL FlashWriteDWORD(DWORD dwFlashAddr, void *pSrc);
/////////////////////////////////////////////////////////////////////
///+
template<class T> BOOL CFlash<T>::WriteRegion
(
ADDRESS dest,
ADDRESS src,
UINT ulen
)
///
/// Write a chunk of data into the flash ROM
///
/// Return: TRUE - Write operation is successful
/// FALSE - Error. Check error code for reason.
///
/// Note: The addresses must be DWORD aligned.
///
{
T BlockStart, BlockEnd, TargetUnit, TargetEnd;
UINT uOffset;
unsigned char dsw;
TargetUnit.Assign(dest);
TargetEnd.Assign(dest + ulen);
uOffset = 0;
dsw = *(unsigned char *)(KSEG1_BASE+DIP_SWITCH_BASE);
if(!(dsw & 0x04)){
EdbgOutputDebugString("PUT S1-SW3 to OFF position to write into FLASH !!!!!!!\r\n");
return(TRUE);
}
//enable the flash
EdbgOutputDebugString ("WriteRegion:::\r\n");
EdbgOutputDebugString ("dest = 0x%x\r\n", dest);
EdbgOutputDebugString ("scr = 0x%x\r\n", src);
EdbgOutputDebugString ("ulen = 0x%x\r\n", ulen);
// EdbgOutputDebugString(" erase target unit = %x\r\n",&TargetUnit);
// EdbgOutputDebugString(" erase target End = %x\r\n",&TargetEnd);
// EdbgOutputDebugString(" erase BlockStart = %x\r\n",&BlockStart);
// EdbgOutputDebugString(" erase BlockEnd = %x\r\n",&BlockEnd);
EdbgOutputDebugString(" erase target End = %x\r\n",TargetEnd.m_ptr);
while (TargetUnit < TargetEnd) {
if (!BlockInfo(&TargetUnit, &BlockStart, &BlockEnd))
return FALSE;
// EdbgOutputDebugString(" erase BlockEnd = %x\r\n",&BlockEnd);
while (TargetUnit <= BlockEnd)
{
if ( (uOffset == 0) || (TargetUnit == BlockStart) )
{
EdbgOutputDebugString(" erase target unit = %x\r\n",&TargetUnit);
if ( !EraseBlock(&TargetUnit) )
return FALSE;
EdbgOutputDebugString("\r\n[Write Block] ");
}
//EdbgOutputDebugString("TargetUnit=%X data=%X\r\n", TargetUnit.m_ptr, *((DWORD *)(src+uOffset)));
if ( uOffset & 0x1fff ) {
//if (!Write(&TargetUnit, (void*)(src+uOffset)))
// return FALSE;
}
else
{
//if (!Write(&TargetUnit, (void*)(src+uOffset), TRUE))
// return FALSE;
EdbgOutputDebugString(".");
}
if (!FlashWriteDWORD((DWORD)TargetUnit.m_ptr, (void *)(src+uOffset)))
return FALSE;
uOffset += TargetUnit.Increment();
TargetUnit.Assign(dest + uOffset);
if (TargetUnit >= TargetEnd)
break;
}
};
EdbgOutputDebugString("\n\r");
EdbgOutputDebugString("TargetUnit.m_ptr=%X\r\n", TargetUnit.m_ptr);
TargetUnit.IssueCommand(READ_ARRAY);
TargetUnit.IssueCommand(READ_ARRAY);
return TRUE;
}
/////////////////////////////////////////////////////////////////////
///+ added by sudhakar
template<class T> BOOL CFlash<T>::EraseRegion
(
ADDRESS dest,
UINT ulen
)
///
/// Erase a chunk of data in the flash ROM
///
/// Return: TRUE - Erase operation is successful
/// FALSE - Error. Check error code for reason.
///
/// Note: The addresses must be DWORD aligned.
///
{
T BlockStart, BlockEnd, TargetUnit, TargetEnd;
UINT uOffset;
TargetUnit.Assign(dest);
TargetEnd.Assign(dest + ulen);
uOffset = 0;
EdbgOutputDebugString ("EraseRegion:::\r\n");
EdbgOutputDebugString ("dest = 0x%x\r\n", dest);
EdbgOutputDebugString ("ulen = 0x%x\r\n", ulen);
EdbgOutputDebugString("\r\n");
while (TargetUnit < TargetEnd) {
if (!BlockInfo(&TargetUnit, &BlockStart, &BlockEnd))
return FALSE;
while (TargetUnit <= BlockEnd)
{
if ( (uOffset == 0) || (TargetUnit == BlockStart) )
{
if ( !EraseBlock(&TargetUnit) )
return FALSE;
}
uOffset += TargetUnit.Increment();
TargetUnit.Assign(dest + uOffset);
if (TargetUnit >= TargetEnd)
break;
}
};
EdbgOutputDebugString("\n\r");
TargetUnit.IssueCommand(READ_ARRAY);
TargetUnit.IssueCommand(READ_ARRAY);
return TRUE;
}
/////////////////////////////////////////////////////////////////////
///+
template<class T> UINT CFlash<T>::Check(ADDRESS startAddr)
///
/// Check if the supported flash chip is present
///
/// Return: UINT - The size of detected flash ROM.
/// If size is zero, flash is not found.
///
{
T compareBase;
T flashBase;
BYTE mID;
BYTE dID;
UINT i;
int FlashDeviceNo=0;
BOOL continueDetect;
//EdbgOutputDebugString("+CFlash::Check: startAddr=%X\r\n", startAddr);
m_BaseAddress = startAddr;
compareBase.Assign(startAddr);
flashBase.Assign(startAddr);
m_ErrCode = Fm_No_Error;
m_SizeOfFlash = 0;
continueDetect=TRUE;
while (continueDetect)
{
compareBase.IssueCommand(INTELLIGENT_IDENTIFIER);
mID = LOBYTE(compareBase[0]);
dID = LOBYTE(compareBase[1]);
for ( i=0; i<NUMBER_OF_SUPPORTED_DEVICE; i++) {
if ((mID==_fd[i].ManufactureCode) && (dID==_fd[i].DeviceCode))
{
m_NumberOfBlocks = _fd[i].NumberOfBlocks;
m_BlockEndTable = _fd[i].BlockEnd;
m_SizeOfFlash += _fd[i].TotalSize*(flashBase.Increment()/flashBase.ChipWidth());
FlashDeviceNo ++;
break;
}
}
compareBase.IssueCommand(READ_ARRAY);
compareBase.Assign(startAddr + m_SizeOfFlash);
if (FlashDeviceNo >=2)
continueDetect=FALSE;
}
//EdbgOutputDebugString("\r\nFlash type %d found FlashDeviceNo = %d\r\n",i, FlashDeviceNo);
//EdbgOutputDebugString("m_SizeOfFlash = %X\r\n", m_SizeOfFlash);
//EdbgOutputDebugString("-CFlash::Check\r\n");
return m_SizeOfFlash;
}
/////////////////////////////////////////////////////////////////////
///+
template<class T> void CFlash<T>::ShowError()
///
/// Show flash memory operation error coniditions
///
{
EdbgOutputDebugString("\n\r");
switch(m_ErrCode) {
case Fm_No_Error:
EdbgOutputDebugString("No flash ROM error.\n\r");
break;
case Vpp_Low:
EdbgOutputDebugString("Error: VPP of the flash ROM is too low.\n\r");
break;
case Program_Error:
EdbgOutputDebugString("Error: Flash ROM does not program.\n\r");
break;
case Program_Timeout:
EdbgOutputDebugString("Error: Flash ROM programming timeout.\n\r");
break;
case Command_Sequence_Error:
EdbgOutputDebugString("Error: Illegal command sequence to the flash ROM.\n\r");
break;
case Block_Erase_Error:
EdbgOutputDebugString("Error: Flash ROM does erase.\n\r");
break;
case Block_Erase_Timeout:
EdbgOutputDebugString("Error: Flash ROM erasing timeout.\n\r");
break;
case Address_Overflow:
EdbgOutputDebugString("Error: Out of flash ROM address range.\n\r");
}
}
#endif // End of _FLASH_HXX_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -