/** Macro to enable all interrupts. */
#define EnableInterrupts asm ("CPSIE i")
/** Macro to disable all interrupts. */
#define DisableInterrupts asm ("CPSID i")
/**
* @brief erase a sector of the flash
*/
int flash_sectorErase( unsigned int* FlashPointer )
{
int Return = E_FLASH_SUCCESS;
uint32_t FlashPtr = (uint32_t)FlashPointer;
/* checking access error */
if ( FTFE_FSTAT & ( FTFE_FSTAT_ACCERR_MASK |
FTFE_FSTAT_FPVIOL_MASK |
FTFE_FSTAT_RDCOLERR_MASK ) )
{
/* clear error flag */
FTFE_FSTAT |= ( FTFE_FSTAT_ACCERR_MASK |
FTFE_FSTAT_FPVIOL_MASK |
FTFE_FSTAT_RDCOLERR_MASK );
}
FTFE_FCNFG &= ~(FTFE_FCNFG_RDCOLLIE_MASK);
DisableInterrupts;
/* Allocate space on stack to run flash command out of SRAM */
/* wait till CCIF is set*/
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK));
/* Write command to FCCOB registers */
FTFE_FCCOB0 = FlashCmd_SectorErase;
FTFE_FCCOB1 = (uint8_t)(FlashPtr >> 16);
FTFE_FCCOB2 = (uint8_t)((FlashPtr >> 8) & 0xFF);
FTFE_FCCOB3 = (uint8_t)(FlashPtr & 0xFF);
// Execute the Flash write
SpSub();
/* checking access error */
if (FTFE_FSTAT & FTFE_FSTAT_ACCERR_MASK)
{
/* clear error flag */
FTFE_FSTAT |= FTFE_FSTAT_ACCERR_MASK;
/* update return value*/
Return |= E_FLASH_FACCERR;
}
/* checking protection error */
else if (FTFE_FSTAT & FTFE_FSTAT_FPVIOL_MASK)
{
/* clear error flag */
FTFE_FSTAT |= FTFE_FSTAT_FPVIOL_MASK;
/* update return value*/
Return |= E_FLASH_FPVIOL;
}
else if (FTFE_FSTAT & FTFE_FSTAT_RDCOLERR_MASK)
{
/* clear error flag */
FTFE_FSTAT |= FTFE_FSTAT_RDCOLERR_MASK;
/* update return value*/
Return |= E_FLASH_RDCOLERR;
}
/* checking MGSTAT0 non-correctable error */
else if (FTFE_FSTAT & FTFE_FSTAT_MGSTAT0_MASK)
{
Return |= E_FLASH_MGSTAT0;
}
EnableInterrupts;
FTFE_FCNFG |= FTFE_FCNFG_RDCOLLIE_MASK;
/* function return */
return Return;
}
/**
* @brief Execute the Flash write while running out of SRAM
*/
__attribute__ ((section(".mydata"))) void SpSub(void)
{
/* Launch command */
FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;
/* wait for command completion */
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK));
}
/* Leave this immediately after SpSub */
void SpSubEnd(void) {}