📄 bf531am29driver.c
字号:
WriteFlash( ulFlashStartAddr + 0x0AAA, 0x10 );
// poll until the command has completed
ErrorCode = PollToggleBit(ulFlashStartAddr + 0x0000);
// erase should be complete
return ErrorCode;
}
//----------- E r a s e B l o c k ( ) ----------//
//
// PURPOSE
// Sends an "erase block" command to the flash.
//
// INPUTS
// int nBlock - block to erase
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE EraseBlock( int nBlock, unsigned long ulAddr ) //段擦除
{
ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash
unsigned long ulSectStart = 0x0; //stores the sector start offset
unsigned 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( (ulFlashStartAddr + 0x0AAA), 0xaa );
WriteFlash( (ulFlashStartAddr + 0x0554), 0x55 );
WriteFlash( (ulFlashStartAddr + 0x0AAA), 0x80 );
WriteFlash( (ulFlashStartAddr + 0x0AAA), 0xaa );
WriteFlash( (ulFlashStartAddr + 0x0554), 0x55 );
// the last write has to be at an address in the block
WriteFlash( (ulFlashStartAddr + ulSectStart), 0x30 );
// poll until the command has completed
ErrorCode = PollToggleBit(ulFlashStartAddr + ulSectStart);
// block erase should be complete
return ErrorCode;
}
//----------- 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 ulAddr) //轮番查询,是否嵌入式算法运行完成
{
ERROR_CODE ErrorCode = NO_ERR; // flag to indicate error
unsigned short sVal1;
unsigned short sVal2;
// read flash 1 time
ReadFlash( ulAddr, &sVal1 );
while( ErrorCode == NO_ERR )
{
// read the value 2 times
ReadFlash( ulAddr, &sVal1 );
ReadFlash( ulAddr, &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( ulAddr, &sVal1 );
ReadFlash( ulAddr, &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(ulAddr);
}
}
}
// we can return
return ErrorCode;
}
//----------- G e t C o d e s ( ) ----------//
//
// PURPOSE
// Sends an "auto select" command to the flash which will allow
// us to get the manufacturer and device codes.
//
// INPUTS
// int *pnManCode - pointer to manufacture code
// int *pnDevCode - pointer to device code
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE GetCodes(int *pnManCode, int *pnDevCode, unsigned long ulAddr)
{
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( ulFlashStartAddr + 0x0aaa, 0xaa );
WriteFlash( ulFlashStartAddr + 0x0554, 0x55 );
WriteFlash( ulFlashStartAddr + 0x0aaa, 0x90 );
// now we can read the codes
ReadFlash( ulFlashStartAddr + 0x0000,(unsigned short *)pnManCode ); //读产品型号
*pnManCode &= 0x00FF;
ReadFlash( ulFlashStartAddr + 0x0002, (unsigned short *)pnDevCode ); //读器件型号
*pnDevCode &= 0x00FF;
if( *pnDevCode == 0x49 ) //49 DB ----是否是49?
{
gNumSectors = 35; //35g段
pFlashDesc = "AM29LV160DB(2M x 8)";
}
else
{
gNumSectors = 35;
pFlashDesc = "S29AL004D(256 x 16)";
}
// 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(ulAddr);
// 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 ulAddr, int *pnSector )
{
int nSector = 0;
int i;
int error_code = 1;
unsigned long ulMask; //offset mask
unsigned long ulOffset; //offset
unsigned long ulStartOff;
unsigned long ulEndOff;
ulMask = 0x3fffff;
ulOffset = ulAddr & ulMask;
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( unsigned long *ulStartOff, unsigned long *ulEndOff, int nSector )
{
long lSectorSize = 0;
long lChipNo;
int nSectorOffsetInChip;
long lChipSize;
lChipNo = nSector/gNumSectors; //第几段 gNumSectors全局变量
nSectorOffsetInChip = nSector%gNumSectors; //除以取余数,以此判断段的起止地址
lChipSize = 1024 * 1024; //1M ---没用上!!
if( nSectorOffsetInChip == 0 )
{
*ulStartOff = 0x0;
*ulEndOff = (*ulStartOff + 0x4000) - 1; //第0段16k
}
else if( nSectorOffsetInChip == 1 )
{
*ulStartOff = 0x4000;
*ulEndOff = (*ulStartOff + 0x2000) - 1; //第1段8K
}
else if( nSectorOffsetInChip == 2 )
{
*ulStartOff = 0x6000;
*ulEndOff = (*ulStartOff + 0x2000) - 1; //第2段8K
}
else if( nSectorOffsetInChip == 3 )
{
*ulStartOff = 0x8000;
*ulEndOff = (*ulStartOff + 0x8000) - 1; //第4段32K
}
else if( (nSectorOffsetInChip >= 4) && (nSectorOffsetInChip <= 18) )
{
*ulStartOff = (nSectorOffsetInChip - 3) * 0x10000;
*ulEndOff = (*ulStartOff + 0x10000) - 1; //以后均为64K
}
else
return INVALID_SECTOR;
// ok
return NO_ERR;
}
//----------- G e t F l a s h S t a r t A d d r e s s ( ) ----------//
//
// PURPOSE
// Gets flash start address from an absolute address.
//
// INPUTS
// unsigned long ulAddr - absolute address
//
// RETURN VALUE
// unsigned long - Flash start address
unsigned long GetFlashStartAddress( unsigned long ulAddr)
{
ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash
unsigned long ulFlashStartAddr; //flash start address
unsigned long ulSectStartAddr; //sector start address
unsigned long ulSectEndAddr; //sector end address
unsigned long ulMask; //offset mask
// get flash start address from absolute address
GetSectorStartEnd( &ulSectStartAddr, &ulSectEndAddr, (gNumSectors-1));
ulMask = ~(ulSectEndAddr);
ulFlashStartAddr = ulAddr & ulMask; //从绝对地址读取FLASH起始地址?
return(ulFlashStartAddr);
}
//----------- 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 ulAddr, unsigned short *pusValue )
{
// 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 *)(ulAddr);
// read the value
*pusValue = (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 ulAddr, unsigned short usValue )
{
// 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 *)(ulAddr);
*pFlashAddr = usValue;
// Enable Interrupts
sti(uiSaveInts);
// ok
return NO_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -