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);
}
Пример #3
0
/* 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, &currentSwapMode, \
                    &currentSwapBlock, &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, &currentSwapMode, &currentSwapBlock, &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, &currentSwapMode, \
                        &currentSwapBlock, &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, &currentSwapMode, \
                        &currentSwapBlock, &nextSwapBlock, g_FlashLaunchCommand);
        if ((FTFx_OK != ret)||(currentSwapMode != FTFx_SWAP_COMPLETE))
        {
            return ret;
        }
    }

    /*********************************************************************************************************/
    return(FTFx_OK);
}