bool SwapCallback(uint8_t currentSwapMode) { uint32_t destination, ret = FTFx_OK; switch (currentSwapMode) { case FTFx_SWAP_UNINIT: /* Put your application-specific code here */ PRINTF("\r\n\tSwap Callback -> Swap flash is uninitialization status!"); break; case FTFx_SWAP_READY: /* Put your application-specific code here */ PRINTF("\r\n\tSwap Callback -> Swap flash is initialization status!"); break; case FTFx_SWAP_UPDATE: /* Put your application-specific code here */ PRINTF("\r\n\tSwap Callback -> Swap flash is update status!"); /**************************************************************************/ /* erase swap indicator address so we can move to update-erased state */ /*************************************************************************/ destination = PSWAP_INDICATOR_ADDR + P_FLASH_SIZE/2; ret = FlashEraseSector(&flashSSDConfig, destination, FTFx_PSECTOR_SIZE, g_FlashLaunchCommand); if (FTFx_OK != ret) { return ret; } break; case FTFx_SWAP_UPDATE_ERASED: /* Put your application-specific code here */ PRINTF("\r\n\tSwap Callback -> swap flash is update erased status!"); /* Erase non active swap indicator and Program example application code to lower and upper location */ /* In a typical user mode, it may be desired to only update the upper half, then swap to run the new code */ /* The flash block will be swapped after the next reset */ ret = ProgramApplicationCode(); break; case FTFx_SWAP_COMPLETE: /* Put your application-specific code here */ PRINTF("\r\n\tSwap Callback -> swap flash is complete status!"); break; default: break; } /* Return TRUE to continue swapping and FALSE to stop swapping */ if (ret == FTFx_OK) return TRUE; else return FALSE; }
static uint32_t ProgramApplicationCode(void) { uint32_t ret = FTFx_OK; uint32_t dest; uint32_t size; uint8_t i; /* Erase upper half of Pflash */ for (i = P_BLOCK_NUM/2 ; i < P_BLOCK_NUM; i++) { dest = P_FLASH_BASE + i*(P_FLASH_SIZE/P_BLOCK_NUM); ret |= FlashEraseBlock(&flashSSDConfig, dest, g_FlashLaunchCommand); if (FTFx_OK != ret) { PRINTF("\r\nFlash Erase Upper Block Error, Address: 0x%x", (int)dest); return ret; } } /******************************************************************* Program upper block with exact same data from lower half except the last sector ( for swap inficator). This includes security information, for use when we swap blocks *******************************************************************/ dest = P_FLASH_BASE + P_FLASH_SIZE/2; size = P_FLASH_SIZE/2 - 2*P_SECTOR_SIZE; ret = FlashProgram(&flashSSDConfig, dest, size, P_FLASH_BASE, g_FlashLaunchCommand); if (FTFx_OK != ret) { PRINTF("\r\nFlashProgram Error, Pflash half program, Address: 0x%x", (int)dest); return ret; } /* program data to upper Pflash half for verification */ ret |= FlashProgram(&flashSSDConfig, PSWAP_UPPERDATA_ADDR, PGM_SIZE_BYTE, pgmData, g_FlashLaunchCommand); /* Program data to lower Pflash half*/ for (i = 0; i < PGM_SIZE_BYTE; i ++) { pgmData[i] = (i+0x10); } ret |= FlashEraseSector(&flashSSDConfig,PSWAP_LOWERDATA_ADDR, P_SECTOR_SIZE,g_FlashLaunchCommand); ret |= FlashProgram(&flashSSDConfig, PSWAP_LOWERDATA_ADDR, PGM_SIZE_BYTE, pgmData, g_FlashLaunchCommand); return (ret); }
/* erase flash, addr is base of a sector of a byte-wide flash */ FlashError_t BDMFlashEraseSector( unsigned int addr ) { return (FlashEraseSector( &Flash, addr /* base of sector of byte-wide flash */ )); }
/************************************************************************** Flash Swap Example Code IMPORTANT NOTE: This demo will operate on flash region from address PSWAP_INDICATOR_ADDR to to the end of PFlash. So please do NOT put any program and data in the region **************************************************************************/ uint32_t flash_swap(void) { uint32_t ret; uint8_t currentSwapMode, currentSwapBlock, nextSwapBlock; /* If standalone, FlashInit() is required here */ /************************************************************************** * Get current swap state * ***************************************************************************/ /* Important note: Use g_FlashLaunchCommand instead of FlashCommandSequence to run CCIF from SRAM! */ /* This allows swap application to execute from Flash memory space while CCIF flag is written from SRAM! */ ret = PFlashSwapCtl(&flashSSDConfig, PSWAP_INDICATOR_ADDR, FTFx_SWAP_REPORT_STATUS, ¤tSwapMode, \ ¤tSwapBlock, &nextSwapBlock, g_FlashLaunchCommand); if (FTFx_OK != ret) { return ret; } if (currentSwapMode == FTFx_SWAP_UNINIT) { /* Erase the sectors that containning swap indicator in the upper Pflash halves to make sure them all 0xFF */ ret = FlashEraseSector(&flashSSDConfig,PSWAP_INDICATOR_ADDR + P_FLASH_SIZE/2, P_SECTOR_SIZE,g_FlashLaunchCommand); ret |= FlashEraseSector(&flashSSDConfig,PSWAP_INDICATOR_ADDR, P_SECTOR_SIZE,g_FlashLaunchCommand); if (FTFx_OK != ret) { return ret; } /************************************************************************** * Call PFlashSwapCtl() to stop at each immediate state * ***************************************************************************/ /* after this call, swap state = UPDATE_ERS */ ret = PFlashSwapCtl(&flashSSDConfig, PSWAP_INDICATOR_ADDR, FTFx_SWAP_SET_INDICATOR_ADDR, ¤tSwapMode, ¤tSwapBlock, &nextSwapBlock, g_FlashLaunchCommand); if ((FTFx_OK != ret)||(currentSwapMode!= FTFx_SWAP_UPDATE_ERASED)) { return ret; } /* Erase non active swap indicator and program test data to lower/upper half */ ret = ProgramApplicationCode(); if (FTFx_OK != ret) { return ret; } /* Progress to swap complete mode now that our indicator address is set, and we have programmed some data */ ret = PFlashSwapCtl(&flashSSDConfig, PSWAP_INDICATOR_ADDR, FTFx_SWAP_SET_IN_COMPLETE, ¤tSwapMode, \ ¤tSwapBlock, &nextSwapBlock, g_FlashLaunchCommand); if ((FTFx_OK != ret)||(currentSwapMode!= FTFx_SWAP_COMPLETE)) { return ret; } /************************************************************************************/ /* Need to reset here to complete swap process */ /************************************************************************************/ } else /* swap system is in READY state */ { /************************************************************************** * Call PFlashSwap() * * Swap is already initialized, meaning the swap indicator locations * * have been assigned and swap is ready to be executed * ***************************************************************************/ ret = PFlashSwap(&flashSSDConfig, PSWAP_INDICATOR_ADDR, SwapCallback, g_FlashLaunchCommand); if (FTFx_OK != ret) { return ret; } ret = PFlashSwapCtl(&flashSSDConfig, PSWAP_INDICATOR_ADDR, FTFx_SWAP_REPORT_STATUS, ¤tSwapMode, \ ¤tSwapBlock, &nextSwapBlock, g_FlashLaunchCommand); if ((FTFx_OK != ret)||(currentSwapMode != FTFx_SWAP_COMPLETE)) { return ret; } } /*********************************************************************************************************/ return(FTFx_OK); }