📄 secam29lvbf531.c
字号:
{
// fill the value
for (i = 0; ( ( i < lCount ) && ( ErrorCode == NO_ERR ) ); i++, ulOffset += (lStride * 2) )
{
// check to see that the address is within a valid sector
ErrorCode = GetSectorNumber( ulOffset, &nSector );
if( NO_ERR == ErrorCode )
{
//ResetFlash();
// unlock the flash, do the write, and wait for completion
UnlockFlash(ulOffset);
WriteFlash( ulOffset, pnData[0] );
ErrorCode = PollToggleBit(ulOffset);
}
else
{
return ErrorCode;
}
}
}
// return the appropriate error code
return ErrorCode;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE ReadData()
//
// Read a buffer from flash.
//
// Inputs: unsigned long ulStart - offset in flash to start the reads at
// int nCount - number of elements to read, in this case bytes
// int nStride - number of locations to skip between reads
// int *pnData - pointer to data buffer to fill
//
//////////////////////////////////////////////////////////////
ERROR_CODE ReadData( unsigned long ulStart, long lCount, long lStride, int *pnData )
{
long i = 0; // loop counter
int j = 0; // inner loop counter
unsigned long ulOffset = ulStart; // current offset to write
int iShift = 0; // shift value by iShift bits
int iNumWords = 2; // number of words in a long
int nLeftover = lCount % 4; // how much if any do we have leftover to write
int nHi,nLow;
int nSector = 0;
ERROR_CODE ErrorCode = NO_ERR; // tells whether we had an error while filling
// write the buffer up to BUFFER_SIZE items
for (i = 0; (i < lCount/4) && (i < BUFFER_SIZE); i++)
{
for ( iShift = 0, j = 0; j < iNumWords ; j+=2 )
{
// check to see that the address is within a valid sector
ErrorCode = GetSectorNumber( ulOffset, &nSector );
if( NO_ERR == ErrorCode )
{
// Read flash
ReadFlash( ulOffset, &nLow );
ulOffset += (lStride * 2);
ReadFlash( ulOffset, &nHi );
ulOffset += (lStride * 2);
pnData[i] = (nHi << 16) | nLow;
}
else
{
return ErrorCode;
}
}
}
// because of the way our ldr file is built, we will always have
// 2 bytes leftover if there is leftover, because the flash is 16 bit
// that will mean that there is only one write left to do.
if( nLeftover > 0 )
{
// check to see that the address is within a valid sector
ErrorCode = GetSectorNumber( ulOffset, &nSector );
if( NO_ERR == ErrorCode )
{
ReadFlash( ulOffset, &pnData[i] );
}
else
{
return ErrorCode;
}
}
// return the appropriate error code
return ErrorCode;
}
//----------- R e a d F l a s h ( ) ----------//
//
// PURPOSE
// Reads a value from an address in flash.
//
// INPUTS
// unsigned long ulAddr - the address to read from
// int pnValue - pointer to store value read from flash
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE ReadFlash( unsigned long ulOffset, int *pnValue )
{
// disable interrupts before performing the load or store operation
// [refer warning: page 6-71 BF533 HRM]
//unsigned int uiSaveInts = cli();
// set our flash address to where we want to read
unsigned short *pFlashAddr = (unsigned short *)(ulFlashStartAddr+ulOffset);
// read the value
*pnValue = (unsigned short)*pFlashAddr; //没看明白??是因为将该地址中写数了!
// Enable Interrupts
//sti(uiSaveInts);
// ok
return NO_ERR;
}
//----------- W r i t e F l a s h ( ) ----------//
//
// PURPOSE
// Write a value to an address in flash.
//
// INPUTS
// unsigned long ulAddr - address to write to
// unsigned short nValue - value to write
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE WriteFlash( unsigned long ulOffset, int nValue )
{
// disable interrupts before performing the load or store operation
// [refer warning: page 6-71 BF533 HRM]
//unsigned int uiSaveInts = cli();
// set the address
unsigned short *pFlashAddr = (unsigned short *)(ulFlashStartAddr+ulOffset);
*pFlashAddr = nValue;
// Enable Interrupts
//sti(uiSaveInts);
// ok
return NO_ERR;
}
//----------- P o l l T o g g l e B i t ( ) ----------//
//
// PURPOSE
// Polls the toggle bit in the flash to see when the operation
// is complete.
//
// INPUTS
// unsigned long ulAddr - address in flash
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE PollToggleBit(unsigned long ulOffset) //轮番查询,是否嵌入式算法运行完成
{
ERROR_CODE ErrorCode = NO_ERR; // flag to indicate error
int sVal1;
int sVal2;
// read flash 1 time
ReadFlash( ulOffset, &sVal1 );
while( ErrorCode == NO_ERR )
{
// read the value 2 times
ReadFlash( ulOffset, &sVal1 );
ReadFlash( ulOffset, &sVal2 );
// XOR to see if any bits are different
sVal1 ^= sVal2;
// see if we are toggling
if( !(sVal1 & 0x40) )
break;
// check error bit
if( !(sVal2 & 0x20) )
continue;
else
{
// read the value 2 times
ReadFlash( ulOffset, &sVal1 );
ReadFlash( ulOffset, &sVal2 );
// XOR to see if any bits are different
sVal1 ^= sVal2;
// see if we are toggling
if( !(sVal1 & 0x40) )
break;
else
{
ErrorCode = POLL_TIMEOUT;
ResetFlash();
}
}
}
// we can return
return ErrorCode;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE ResetFlash()
//
// Sends a "reset" command to the flash.
//
//////////////////////////////////////////////////////////////
ERROR_CODE ResetFlash(void)
{
// send the reset command to the flash
WriteFlash(0x0AAA, 0xf0 );
// reset should be complete
return NO_ERR;
}
//----------- E r a s e F l a s h ( ) ----------//
//
// PURPOSE
// Sends an "erase all" command to the flash.
//
// INPUTS
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE EraseFlash(void)
{
ERROR_CODE ErrorCode = NO_ERR; // tells us if there was an error erasing flash
int nBlock = 0; // index for each block to erase
//unsigned long ulFlashStartAddr; // flash start address
// get flash start address from absolute address
// The ulAddr should ideally be pointing to the flash start
// address. However we just verify it here again.
//ulFlashStartAddr = GetFlashStartAddress(ulAddr);
// erase contents of Flash
WriteFlash(0x0555, 0xaa );
WriteFlash(0x02aa, 0x55 );
WriteFlash(0x0555, 0x80 );
WriteFlash(0x0555, 0xaa );
WriteFlash(0x02aa, 0x55 );
WriteFlash(0x0555, 0x10 );
// poll until the command has completed
ErrorCode = PollToggleBit(ulFlashStartAddr + 0x0000);
// erase should be complete
return ErrorCode;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE EraseBlock()
//
// Sends an "erase block" command to the flash.
//
//////////////////////////////////////////////////////////////
ERROR_CODE EraseBlock( int nBlock) //段擦除
{
ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash
long ulSectStart = 0x0; //stores the sector start offset
long ulSectEnd = 0x0; //stores the sector end offset(however we do not use it here)
//unsigned long ulFlashStartAddr; //flash start address
// get flash start address from absolute address
// The ulAddr should ideally be pointing to the flash start
// address. However we just verify it here again.
//ulFlashStartAddr = GetFlashStartAddress(ulAddr);
// Get the sector start offset
// we get the end offset too however we do not actually use it for Erase sector
GetSectorStartEnd( &ulSectStart, &ulSectEnd, nBlock );
// send the erase block command to the flash
WriteFlash( 0x0555, 0xaa );
WriteFlash( 0x02aa, 0x55 );
WriteFlash( 0x0555, 0x80 );
WriteFlash( 0x0555, 0xaa );
WriteFlash( 0x02aa, 0x55 );
// the last write has to be at an address in the block
WriteFlash(ulSectStart, 0x30 );
// poll until the command has completed
ErrorCode = PollToggleBit(ulSectStart);
// block erase should be complete
return ErrorCode;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE UnlockFlash()
//
// Sends an "unlock" command to the flash to allow the flash
// to be programmed.
//
//////////////////////////////////////////////////////////////
ERROR_CODE UnlockFlash(unsigned long ulOffset)
{
unsigned long ulOffsetAddr = ulOffset;
ulOffsetAddr &= 0xFFFF0000;
// send the unlock command to the flash
// ORed with lOffsetAddr so we know what block we are in
WriteFlash( 0x0555, 0xaa );
WriteFlash( 0x02aa, 0x55 );
WriteFlash( 0x0555, 0xa0 );
// ok
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE GetCodes()
//
// Sends an "auto select" command to the flash which will allow
// us to get the manufacturer and device codes.
//
//////////////////////////////////////////////////////////////
ERROR_CODE GetCodes(void)
{
//unsigned long ulFlashStartAddr; //flash start address
// get flash start address from absolute address
// The ulAddr should ideally be pointing to the flash start
// address. However we just verify it here again.
//ulFlashStartAddr = GetFlashStartAddress(ulAddr);
// send the auto select command to the flash
WriteFlash( 0x0555, 0xaa );
WriteFlash( 0x02aa, 0x55 );
WriteFlash( 0x0555, 0x90 );
// now we can read the codes
ReadFlash(0x0000,&AFP_ManCode); //读产品型号
AFP_ManCode &= 0x00FF;
ReadFlash(0x0001,&AFP_DevCode ); //读器件型号
AFP_DevCode &= 0x00FF;
// we need to issue another command to get the part out
// of auto select mode so issue a reset which just puts
// the device back in read mode
ResetFlash();
// ok
return NO_ERR;
}
//----------- G e t S e c t o r N u m b e r ( ) ----------//
//
// PURPOSE
// Gets a sector number based on the offset.
//
// INPUTS
// unsigned long ulAddr - absolute address
// int *pnSector - pointer to sector number
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE GetSectorNumber( unsigned long ulOffset, int *pnSector)
{
for(i = 0; i < gNumSectors; i++)
{
GetSectorStartEnd(&ulStartOff, &ulEndOff, i);
if ( (ulOffset >= ulStartOff)
&& (ulOffset <= ulEndOff) )
{
error_code = 0;
nSector = i;
break;
}
}
// if it is a valid sector, set it
if (error_code == 0)
*pnSector = nSector;
// else it is an invalid sector
else
return INVALID_SECTOR;
// ok
return NO_ERR;
}
//----------- G e t S e c t o r S t a r t E n d ( ) ----------//
//
// PURPOSE
// Gets a sector start and end address based on the sector number.
//
// INPUTS
// unsigned long *ulStartOff - pointer to the start offset
// unsigned long *ulEndOff - pointer to the end offset
// int nSector - sector number
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE GetSectorStartEnd( long *lStartOff, long *lEndOff, int nSector )
{
if( nSector == 0 )
{
*lStartOff = 0x0;
*lEndOff = (*lStartOff + 0x2000) - 1; //第0段16k
}
else if( nSector == 1 )
{
*lStartOff = 0x2000;
*lEndOff = (*lStartOff + 0x1000) - 1; //第1段8K
}
else if( nSector == 2 )
{
*lStartOff = 0x3000;
*lEndOff = (*lStartOff + 0x1000) - 1; //第2段8K
}
else if( nSector == 3 )
{
*lStartOff = 0x4000;
*lEndOff = (*lStartOff + 0x4000) - 1; //第4段32K
}
else if( (nSector >= 4) && (nSector <= 34) )
{
*lStartOff = (nSector - 3) * 0x8000;
*lEndOff = (*lStartOff + 0x8000) - 1; //以后均为64K
}
else
return INVALID_SECTOR;
// ok
return NO_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -