📄 spi_flashdriver.c
字号:
}
// return the appropriate error code
return ErrorCode;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE FillData()
//
// Fill flash with a value.
//
// Inputs: unsigned long ulStart - offset in flash to start the writes at
// long lCount - number of elements to write, in this case bytes
// long lStride - number of locations to skip between writes
// int *pnData - pointer to data buffer
//
//////////////////////////////////////////////////////////////
ERROR_CODE FillData( unsigned long ulStart, long lCount, long lStride, int *pnData )
{
long i = 0; // loop counter
unsigned long ulOffset = ulStart; // current offset to write
ERROR_CODE ErrorCode = NO_ERR; // tells whether we had an error while filling
int nCompare = 0; // value that we use to verify flash
bool bVerifyError = FALSE; // lets us know if there was a verify error
unsigned long ulNewOffset = 0; // used if we have an odd address
int nSector = 0;
// if we have an odd offset we need to write a byte
// to the first location and the last
if(ulOffset%2 != 0)
{
// read the offset - 1 and OR in our value
ulNewOffset = ulOffset - 1;
ReadFlash( ulNewOffset, &nCompare );
nCompare &= 0xFF00;
nCompare |= (pnData[0] & 0x00FF);
// unlock the flash, do the write, and wait for completion
UnlockFlash(ulNewOffset);
WriteFlash( ulNewOffset, nCompare );
ErrorCode = PollToggleBit(ulNewOffset);
// move to the last offset
ulNewOffset = (ulOffset - 1) + (lCount * (lStride * 2) );
// read the value and OR in our value
ReadFlash( ulNewOffset, &nCompare );
nCompare &= 0x00FF;
nCompare |= (pnData[0] & 0xFF00);
// unlock the flash, do the write, and wait for completion
UnlockFlash(ulNewOffset);
WriteFlash( ulNewOffset, nCompare );
ErrorCode = PollToggleBit(ulNewOffset);
// increment the offset and count
ulOffset = ( (ulOffset - 1) + (lStride * 2) );
lCount--;
}
// verify writes if the user wants to
if( AFP_Verify == TRUE )
{
// 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 )
{
// unlock the flash, do the write, and wait for completion
UnlockFlash(ulOffset);
WriteFlash( ulOffset, pnData[0] );
ErrorCode = PollToggleBit(ulOffset);
ReadFlash( ulOffset, &nCompare );
if( nCompare != ( pnData[0] & 0x0000FFFF ) )
{
bVerifyError = TRUE;
break;
}
}
else
{
return ErrorCode;
}
}
// return appropriate error code if there was a verification error
if( bVerifyError == TRUE )
return VERIFY_WRITE;
}
// user did not want to verify writes
else
{
// 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 )
{
// 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;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE WriteFlash()
//
// Write a value to an offset in flash.
//
// Inputs: unsigned long ulOffset - offset to write to
// int nValue - value to write
//
//////////////////////////////////////////////////////////////
ERROR_CODE WriteFlash( unsigned long ulOffset, int nValue )
{
spi_write_byte (ulOffset, nValue&0x00FF);
spi_write_byte (ulOffset+1, (nValue>>8)&0x00FF );
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE ReadFlash()
//
// Read a value from an offset in flash.
//
// Inputs: unsigned long ulOffset - offset to read from
// int pnValue - pointer to store value read from flash
//
//////////////////////////////////////////////////////////////
ERROR_CODE ReadFlash( unsigned long ulOffset, int *pnValue )
{
unsigned char low, high;
low = spi_read_byte (ulOffset);
high = spi_read_byte (ulOffset+1);
*pnValue = (high<<8)|low;
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE PollToggleBit()
//
// Polls the toggle bit in the flash to see when the operation
// is complete.
//
// Inputs: unsigned long ulOffset - offset in flash
//
//////////////////////////////////////////////////////////////
ERROR_CODE PollToggleBit(unsigned long ulOffset)
{
// SPI routines handle the polling.
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE ResetFlash()
//
// Sends a "reset" command to the flash.
//
//////////////////////////////////////////////////////////////
ERROR_CODE ResetFlash()
{
spi_reset ();
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE EraseFlash()
//
// Sends an "erase all" command to the flash.
//
//////////////////////////////////////////////////////////////
ERROR_CODE EraseFlash()
{
// Full chip erase
spi_chip_erase ();
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE EraseBlock()
//
// Sends an "erase block" command to the flash.
//
//////////////////////////////////////////////////////////////
ERROR_CODE EraseBlock( int nBlock )
{
// if the block is invalid just return
if (nBlock < 0 || nBlock >= NUM_SECTORS) return INVALID_BLOCK;
// Erase a sector. Needs an addres within the sector
spi_sector_erase (nBlock*SECTOR_SIZE+SECTOR_SIZE/2);
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE UnlockFlash()
//
// Sends an "unlock" command to the flash to allow the flash
// to be programmed.
//
//////////////////////////////////////////////////////////////
ERROR_CODE UnlockFlash(unsigned long ulOffset)
{
// No ulock command for our flash
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()
{
// Use the device signature for the device code
AFP_DevCode = spi_reset ();
// there is no ManCode so just hard code it to 0x0
AFP_ManCode = 0x0;
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE GetSectorNumber()
//
// Gets a sector number based on the offset.
//
//////////////////////////////////////////////////////////////
ERROR_CODE GetSectorNumber( unsigned long ulOffset, int *pnSector )
{
if (ulOffset >= FLASH_SIZE) return INVALID_SECTOR;
// Return the sector number for and address
*pnSector = ulOffset/SECTOR_SIZE;
return NO_ERR;
}
//////////////////////////////////////////////////////////////
// ERROR_CODE GetSectorStartEnd()
//
// Gets a sector number based on the offset.
//
// Inputs: long *lStartOff - pointer to the start offset
// long *lEndOff - pointer to the end offset
// int nSector - sector number
//
//////////////////////////////////////////////////////////////
ERROR_CODE GetSectorStartEnd( long *lStartOff, long *lEndOff, int nSector )
{
if (nSector < 0 || nSector >= NUM_SECTORS) return INVALID_BLOCK;
// Return the start and end address for a sector
*lStartOff = (nSector)*SECTOR_SIZE;
*lEndOff = (nSector+1)*(SECTOR_SIZE-1);
return NO_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -