📄 extflash.c
字号:
//! \param pbError is storage for the returned error indicator.
//!
//! This function determines whether the last flash erase operation has
//! completed. The address passed in parameter \e ulAddress must correspond to
//! an address in the region which was last erased. When the operation
//! completes, \b true is returned and the caller should check the value of
//! \e *pbError to determine whether or not the operation was successful. If
//! \e *pbError is \b true, an error was reported by the device and the flash
//! may not have been correctly erased. If \e *pbError is \b false, the
//! operation completed successfully.
//!
//! It is assumed that the EPI configuration has previously been set correctly
//! using a call to PinoutSet().
//!
//! \return Returns \b true if the erase operation completed or \b false if it
//! is still ongoing.
//
//*****************************************************************************
tBoolean
ExtFlashEraseIsComplete(unsigned long ulAddress, tBoolean *pbError)
{
//
// If reading the location returns 0xFF, the erase must be complete.
//
if(HWREGB(ulAddress) == 0xFF)
{
*pbError = false;
return(true);
}
else
{
//
// The erase is not complete so we look at the value read to determine
// whether an error occurred or not.
//
if(HWREGB(ulAddress) & FLASH_STATUS_ERROR)
{
//
// An error seems to have been reported. Check once more as
// indicated in the datasheet.
if(HWREGB(ulAddress) == 0xFF)
{
//
// False alarm - tell the caller the operation completed.
//
*pbError = false;
return(true);
}
else
{
//
// Looks as if the error was real so issue a Read/Reset to get
// the chip back into read mode and clear the error condition.
// then report the failure to the caller.
//
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(EXT_FLASH_BASE) = 0xF0;
*pbError = true;
}
}
else
{
*pbError = false;
}
//
// If an error occurred, we return true so that any polling loop will
// exit. If no error occurred, the operation is not complete so we
// return false.
//
return(*pbError);
}
}
//*****************************************************************************
//
//! Erases a single block of the flash device.
//!
//! \param ulAddress is an address within the block to be erased.
//! \param bSync indicates whether to return immediately or poll until the
//! erase operation has completed.
//!
//! This function erases a single block of the flash device. The block erased
//! is identified by parameter \e ulAddress. If this is not a block start
//! address, the block containing \e ulAddress is erased. Applications may
//! call ExtFlashBlockSizeGet() to determine the size and start address of
//! the block containing a particular flash address.
//!
//! If called with \e bAsync set to \b false, the function will poll until the
//! erase operation completes and only return at this point. If, however, \e
//! bAsync is \b true, the function will return immediately and the caller can
//! determine when the erase operation completes by polling function
//! ExtFlashEraseIsComplete(), passing it the same \e ulAddress parameter as
//! was passed to this function.
//!
//! It is assumed that the EPI configuration has previously been set correctly
//! using a call to PinoutSet().
//!
//! \note A block erase will typically take 0.8 seconds to complete and may
//! take up to 6 seconds in the worst case.
//!
//! \return Returns \b true to indicate success or \b false to indicate that
//! an error occurred.
//
//*****************************************************************************
tBoolean
ExtFlashBlockErase(unsigned long ulAddress, tBoolean bSync)
{
tBoolean bError;
//
// Issue the command sequence to erase the block.
//
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0x80;
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(ulAddress) = 0x30;
//
// Have we been asked to block until the operation completes?
//
if(bSync)
{
//
// We've been asked to wait. Poll the status until we are told the
// erase completed.
//
while(!ExtFlashEraseIsComplete(ulAddress, &bError))
{
//
// Keep waiting...
//
}
//
// Return true if no error was reported in the erase operation.
//
return(!bError);
}
//
// If we get this far, either we started the erase operation and are
// returning immediately because bSync is true or the operation completed
// successfully.
//
return(true);
}
//*****************************************************************************
//
//! Erases the entire flash device.
//!
//! \param bSync indicates whether to return immediately or poll until the
//! erase operation has completed.
//!
//! This function erases the entire flash device. If called with \e bAsync set
//! to \b false, the function will poll until the erase operation completes and
//! only return at this point. If, however, \e bAsync is \b true, the function
//! will return immediately and the caller can determine when the erase
//! operation completes by polling function ExtFlashEraseIsComplete(), passing
//! \e EXT_FLASH_BASE as the \e ulAddress parameter.
//!
//! It is assumed that the EPI configuration has previously been set correctly
//! using a call to PinoutSet().
//!
//! \note A chip erase will typically take 80 seconds to complete and may
//! take up to 400 seconds in the worst case.
//!
//! \return Returns \b true to indicate success or \b false to indicate that
//! an error occurred.
//
//*****************************************************************************
tBoolean
ExtFlashChipErase(tBoolean bSync)
{
tBoolean bError;
//
// Issue the command sequence to erase the entire chip.
//
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0x80;
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0x10;
//
// Have we been asked to block until the operation completes?
//
if(bSync)
{
//
// We've been asked to wait. Poll the status until we are told the
// erase completed.
//
while(!ExtFlashEraseIsComplete(EXT_FLASH_BASE, &bError))
{
//
// Keep waiting...
//
}
//
// Return true if no error was reported in the erase operation.
//
return(!bError);
}
//
// If we get this far, either we started the erase operation and are
// returning immediately because bSync is true or the operation completed
// successfully.
//
return(true);
}
//*****************************************************************************
//
//! Writes data to the flash device.
//!
//! \param ulAddress is the address that the data is to be written to.
//! \param ulLength is the number of bytes of data to write.
//! \param pucSrc points to the first byte of data to write.
//!
//! This function writes data to the flash device. Callers must ensure that
//! the are of flash being written has previously been erased or, at least,
//! that writing the data will not require any bits which are already stored
//! as 0s in the flash to revert to 1s. The function returns either when an
//! error is detected or all data has been successfully written to the device.
//!
//! It is assumed that the EPI configuration has previously been set correctly
//! using a call to PinoutSet().
//!
//! \note Programming data may take as long as 200 microseconds per byte.
//!
//! \return Returns the number of bytes successfully written.
//
//*****************************************************************************
unsigned long
ExtFlashWrite(unsigned long ulAddress, unsigned long ulLength,
unsigned char *pucSrc)
{
unsigned long ulLoop;
//
// Program each byte in turn.
//
for(ulLoop = 0; ulLoop < ulLength; ulLoop++)
{
//
// Send the command to program this byte.
//
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xA0;
HWREGB(ulAddress) = *pucSrc;
//
// Wait for this byte to be programmed.
//
while(1)
{
if(HWREGB(ulAddress) == *pucSrc)
{
//
// The flash reads back the same data we wrote to it so this
// write operation has completed.
//
break;
}
else
{
//
// The operation has not completed. Is an error reported?
//
if(HWREGB(ulAddress) & FLASH_STATUS_ERROR)
{
//
// The error bit appears to be set but this may just be
// because the operation just completed. Check the location
// once more to be sure.
//
if(HWREGB(ulAddress) == *pucSrc)
{
//
// Yes - it completed. Move on to the next byte.
//
break;
}
else
{
//
// An error was reported. We clear the error and return
// early telling the caller how many bytes we actually
// programmed.
//
HWREGB(EXT_FLASH_BASE + 0xAAA) = 0xAA;
HWREGB(EXT_FLASH_BASE + 0x555) = 0x55;
HWREGB(EXT_FLASH_BASE) = 0xF0;
return(ulLoop);
}
}
}
}
//
// Move on to the next location.
//
ulAddress++;
pucSrc++;
}
//
// If we get here, we successfully programmed everything we were given.
//
return(ulLength);
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -