?? flash.c
字號:
// Set the protection based on the requested proection.
//
switch(eProtect)
{
//
// Make this block execute only.
//
case FlashExecuteOnly:
{
//
// Turn off the read and program bits for this block.
//
ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
//
// We're done handling this protection.
//
break;
}
//
// Make this block read only.
//
case FlashReadOnly:
{
//
// The block can not be made read only if it is execute only.
//
if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
FLASH_FMP_BLOCK_0)
{
return(-1);
}
//
// Make this block read only.
//
ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
//
// We're done handling this protection.
//
break;
}
//
// Make this block read/write.
//
case FlashReadWrite:
default:
{
//
// The block can not be made read/write if it is not already
// read/write.
//
if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
FLASH_FMP_BLOCK_0) ||
(((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
FLASH_FMP_BLOCK_0))
{
return(-1);
}
//
// The block is already read/write, so there is nothing to do.
//
return(0);
}
}
//
// For Stellaris Sandstorm-class devices, revision C1 and C2, the upper
// bits of the FMPPE register are used for JTAG options, and are not
// available for the FLASH protection scheme. When setting block
// protection, ensure that these bits are not altered.
//
if(CLASS_IS_SANDSTORM && (REVISION_IS_C1 || REVISION_IS_C2))
{
ulProtectRE &= ~(FLASH_FMP_BLOCK_31 | FLASH_FMP_BLOCK_30);
ulProtectRE |= (HWREG(g_pulFMPRERegs[ulBank]) &
(FLASH_FMP_BLOCK_31 | FLASH_FMP_BLOCK_30));
}
//
// Set the new protection for the specified flash bank.
//
HWREG(g_pulFMPRERegs[ulBank]) = ulProtectRE;
HWREG(g_pulFMPPERegs[ulBank]) = ulProtectPE;
//
// Success.
//
return(0);
}
//*****************************************************************************
//
//! Saves the flash protection settings.
//!
//! This function will make the currently programmed flash protection settings
//! permanent. This is a non-reversible operation; a chip reset or power cycle
//! will not change the flash protection.
//!
//! This function will not return until the protection has been saved.
//!
//! \return Returns 0 on success, or -1 if a hardware error is encountered.
//
//*****************************************************************************
long
FlashProtectSave(void)
{
int ulTemp, ulLimit;
//
// If running on a Sandstorm-class device, only trigger a save of the first
// two protection registers (FMPRE and FMPPE). Otherwise, save the
// entire bank of flash protection registers.
//
ulLimit = CLASS_IS_SANDSTORM ? 2 : 8;
for(ulTemp = 0; ulTemp < ulLimit; ulTemp++)
{
//
// Tell the flash controller to write the flash protection register.
//
HWREG(FLASH_FMA) = ulTemp;
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
//
// Wait until the write has completed.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
{
}
}
//
// Success.
//
return(0);
}
//*****************************************************************************
//
//! Gets the user registers.
//!
//! \param pulUser0 is a pointer to the location to store USER Register 0.
//! \param pulUser1 is a pointer to the location to store USER Register 1.
//!
//! This function will read the contents of user registers (0 and 1), and
//! store them in the specified locations.
//!
//! \return Returns 0 on success, or -1 if a hardware error is encountered.
//
//*****************************************************************************
long
FlashUserGet(unsigned long *pulUser0, unsigned long *pulUser1)
{
//
// Verify that the pointers are valid.
//
ASSERT(pulUser0 != 0);
ASSERT(pulUser1 != 0);
//
// Verify that hardware supports user registers.
//
if(CLASS_IS_SANDSTORM)
{
return(-1);
}
//
// Get and store the current value of the user registers.
//
*pulUser0 = HWREG(FLASH_USERREG0);
*pulUser1 = HWREG(FLASH_USERREG1);
//
// Success.
//
return(0);
}
//*****************************************************************************
//
//! Sets the user registers.
//!
//! \param ulUser0 is the value to store in USER Register 0.
//! \param ulUser1 is the value to store in USER Register 1.
//!
//! This function will set the contents of the user registers (0 and 1) to
//! the specified values.
//!
//! \return Returns 0 on success, or -1 if a hardware error is encountered.
//
//*****************************************************************************
long
FlashUserSet(unsigned long ulUser0, unsigned long ulUser1)
{
//
// Verify that hardware supports user registers.
//
if(CLASS_IS_SANDSTORM)
{
return(-1);
}
//
// Save the new values into the user registers.
//
HWREG(FLASH_USERREG0) = ulUser0;
HWREG(FLASH_USERREG1) = ulUser1;
//
// Success.
//
return(0);
}
//*****************************************************************************
//
//! Saves the user registers.
//!
//! This function will make the currently programmed user register settings
//! permanent. This is a non-reversible operation; a chip reset or power cycle
//! will not change this setting.
//!
//! This function will not return until the protection has been saved.
//!
//! \return Returns 0 on success, or -1 if a hardware error is encountered.
//
//*****************************************************************************
long
FlashUserSave(void)
{
//
// Verify that hardware supports user registers.
//
if(CLASS_IS_SANDSTORM)
{
return(-1);
}
//
// Setting the MSB of FMA will trigger a permanent save of a USER
// register. Bit 0 will indicate User 0 (0) or User 1 (1).
//
HWREG(FLASH_FMA) = 0x80000000;
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
//
// Wait until the write has completed.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
{
}
//
// Tell the flash controller to write the USER1 Register.
//
HWREG(FLASH_FMA) = 0x80000001;
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
//
// Wait until the write has completed.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
{
}
//
// Success.
//
return(0);
}
//*****************************************************************************
//
//! Registers an interrupt handler for the flash interrupt.
//!
//! \param pfnHandler is a pointer to the function to be called when the flash
//! interrupt occurs.
//!
//! This sets the handler to be called when the flash interrupt occurs. The
//! flash controller can generate an interrupt when an invalid flash access
//! occurs, such as trying to program or erase a read-only block, or trying to
//! read from an execute-only block. It can also generate an interrupt when a
//! program or erase operation has completed. The interrupt will be
//! automatically enabled when the handler is registered.
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
FlashIntRegister(void (*pfnHandler)(void))
{
//
// Register the interrupt handler, returning an error if an error occurs.
//
IntRegister(INT_FLASH, pfnHandler);
//
// Enable the flash interrupt.
//
IntEnable(INT_FLASH);
}
//*****************************************************************************
//
//! Unregisters the interrupt handler for the flash interrupt.
//!
//! This function will clear the handler to be called when the flash interrupt
//! occurs. This will also mask off the interrupt in the interrupt controller
//! so that the interrupt handler is no longer called.
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
FlashIntUnregister(void)
{
//
// Disable the interrupt.
//
IntDisable(INT_FLASH);
//
// Unregister the interrupt handler.
//
IntUnregister(INT_FLASH);
}
//*****************************************************************************
//
//! Enables individual flash controller interrupt sources.
//!
//! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
//! Can be any of the \b FLASH_INT_PROGRAM or \b FLASH_INT_ACCESS values.
//!
//! Enables the indicated flash controller interrupt sources. Only the sources
//! that are enabled can be reflected to the processor interrupt; disabled
//! sources have no effect on the processor.
//!
//! \return None.
//
//*****************************************************************************
void
FlashIntEnable(unsigned long ulIntFlags)
{
//
// Enable the specified interrupts.
//
HWREG(FLASH_FCIM) |= ulIntFlags;
}
//*****************************************************************************
//
//! Disables individual flash controller interrupt sources.
//!
//! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
//! Can be any of the \b FLASH_INT_PROGRAM or \b FLASH_INT_ACCESS values.
//!
//! Disables the indicated flash controller interrupt sources. Only the
//! sources that are enabled can be reflected to the processor interrupt;
//! disabled sources have no effect on the processor.
//!
//! \return None.
//
//*****************************************************************************
void
FlashIntDisable(unsigned long ulIntFlags)
{
//
// Disable the specified interrupts.
//
HWREG(FLASH_FCIM) &= ~(ulIntFlags);
}
//*****************************************************************************
//
//! Gets the current interrupt status.
//!
//! \param bMasked is false if the raw interrupt status is required and true if
//! the masked interrupt status is required.
//!
//! This returns the interrupt status for the flash controller. Either the raw
//! interrupt status or the status of interrupts that are allowed to reflect to
//! the processor can be returned.
//!
//! \return The current interrupt status, enumerated as a bit field of
//! \b FLASH_INT_PROGRAM and \b FLASH_INT_ACCESS.
//
//*****************************************************************************
unsigned long
FlashIntStatus(tBoolean bMasked)
{
//
// Return either the interrupt status or the raw interrupt status as
// requested.
//
if(bMasked)
{
return(HWREG(FLASH_FCMISC));
}
else
{
return(HWREG(FLASH_FCRIS));
}
}
//*****************************************************************************
//
//! Clears flash controller interrupt sources.
//!
//! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
//! Can be any of the \b FLASH_INT_PROGRAM or \b FLASH_INT_AMISC values.
//!
//! The specified flash controller interrupt sources are cleared, so that they
//! no longer assert. This must be done in the interrupt handler to keep it
//! from being called again immediately upon exit.
//!
//! \note Since there is a write buffer in the Cortex-M3 processor, it may take
//! several clock cycles before the interrupt source is actually cleared.
//! Therefore, it is recommended that the interrupt source be cleared early in
//! the interrupt handler (as opposed to the very last action) to avoid
//! returning from the interrupt handler before the interrupt source is
//! actually cleared. Failure to do so may result in the interrupt handler
//! being immediately reentered (since NVIC still sees the interrupt source
//! asserted).
//!
//! \return None.
//
//*****************************************************************************
void
FlashIntClear(unsigned long ulIntFlags)
{
//
// Clear the flash interrupt.
//
HWREG(FLASH_FCMISC) = ulIntFlags;
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -