mcu/drv/fsl_flash_driver_c90tfs.c
/*FUNCTION**********************************************************************
 *
 * Function Name : PFlashSwap
 * Description   : Provides to user with an ability to interfere in a swap progress by letting the
 * user code know about the swap state in each phase of the process. This is done via pSwapCallBack()
 * parameter. To stop at each intermediate swap state, set the return value of
 * this callback function to FALSE. To complete swap process within a single call,
 * set the return value of this function to TRUE.
 *
 * Erase the non-active swap indicator somewhere in the application code
 * or in the swap call back function when swap system is in UPDATE state.
 *
 * In addition, if user does not want to use the swap call back parameter, pass the NULL_SWAP_CALLBACK
 * as a null pointer. In this situation, the PFlashSwap() behaves in the same way as setting the return
 * value of pSwapCallBack to TRUE and the user does not need to erase the non-active swap
 * indicator when the swap system is in UPDATE state.
 * The swap indicator provided by the user must be within the lower half of P-Flash block but not in the
 * Flash configuration area. If P-Flash block has two logical blocks, the swap indicator must be
 * in P-Flash block 0. If the P-Flash block has four logical blocks, the swap indicator can be in block
 * 0 or block 1. It must not be in the Flash configuration field.
 * The user must use the same swap indicator for all swap control code except report swap status once
 * swap system has been initialized. To refresh swap system to un-initialization state,
 * use the FlashEraseAllBlock() to clean up the swap environment.
 *
 * Implements    : PFlashSwap_Activity
 *END**************************************************************************/
FUNCTION

Function Name : PFlashSwap
Description   : Provides to user with an ability to interfere in a swap progress by letting the
user code know about the swap state in each phase of the process. This is done via pSwapCallBack()
parameter. To stop at each intermediate swap state, set the return value of
this callback function to FALSE. To complete swap process within a single call,
set the return value of this function to TRUE.

Erase the non-active swap indicator somewhere in the application code
or in the swap call back function when swap system is in UPDATE state.

In addition, if user does not want to use the swap call back parameter, pass the NULL_SWAP_CALLBACK
as a null pointer. In this situation, the PFlashSwap() behaves in the same way as setting the return
value of pSwapCallBack to TRUE and the user does not need to erase the non-active swap
indicator when the swap system is in UPDATE state.
The swap indicator provided by the user must be within the lower half of P-Flash block but not in the
Flash configuration area. If P-Flash block has two logical blocks, the swap indicator must be
in P-Flash block 0. If the P-Flash block has four logical blocks, the swap indicator can be in block
0 or block 1. It must not be in the Flash configuration field.
The user must use the same swap indicator for all swap control code except report swap status once
swap system has been initialized. To refresh swap system to un-initialization state,
use the FlashEraseAllBlock() to clean up the swap environment.

Implements    : PFlashSwap_Activity
END
FUNCTION Function Name : PFlashSwap Description : Provides to user with an ability to interfere in a swap progress by letting the user code know about the swap state in each phase of the process . This is done via pSwapCallBack () parameter . To stop at each intermediate swap state set the return value of this callback function to FALSE . To complete swap process within a single call set the return value of this function to TRUE . Erase the non - active swap indicator somewhere in the application code or in the swap call back function when swap system is in UPDATE state . In addition if user does not want to use the swap call back parameter pass the NULL_SWAP_CALLBACK as a null pointer . In this situation the PFlashSwap () behaves in the same way as setting the return value of pSwapCallBack to TRUE and the user does not need to erase the non - active swap indicator when the swap system is in UPDATE state . The swap indicator provided by the user must be within the lower half of P - Flash block but not in the Flash configuration area . If P - Flash block has two logical blocks the swap indicator must be in P - Flash block 0 . If the P - Flash block has four logical blocks the swap indicator can be in block 0 or block 1 . It must not be in the Flash configuration field . The user must use the same swap indicator for all swap control code except report swap status once swap system has been initialized . To refresh swap system to un - initialization state use the FlashEraseAllBlock () to clean up the swap environment . Implements : PFlashSwap_Activity END
flash_drv_status_t PFlashSwap(const flash_ssd_config_t * pSSDConfig, \
                              uint32_t addr, \
                              flash_swap_callback_t pSwapCallback, \
                              flash_command_sequence_t pFlashCommandSequence)
{
#ifdef DEV_ERROR_DETECT
    DEV_ASSERT(pSSDConfig != NULL);
    DEV_ASSERT(pSwapCallback != NULL);
    DEV_ASSERT(pFlashCommandSequence != NULL);
#endif
    flash_drv_status_t ret = FTFx_OK;    
    uint8_t currentSwapMode, currentSwapBlockStatus, nextSwapBlockStatus;
    bool swapContinue;
    currentSwapMode = 0xFFU;
    currentSwapBlockStatus = 0xFFU;
    nextSwapBlockStatus = 0xFFU;
    swapContinue = false;
    ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_REPORT_STATUS, &currentSwapMode, \
                        &currentSwapBlockStatus, &nextSwapBlockStatus, pFlashCommandSequence);
    if (FTFx_OK == ret)
    {
        if ((FTFx_SWAP_UNINIT == currentSwapMode) || (FTFx_SWAP_READY == currentSwapMode) || \
                (FTFx_SWAP_UPDATE == currentSwapMode))
        {
            if (FTFx_SWAP_UNINIT == currentSwapMode)
            {
                ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_SET_INDICATOR_ADDR, &currentSwapMode, \
                                    &currentSwapBlockStatus, &nextSwapBlockStatus, pFlashCommandSequence);
            }
            else if (FTFx_SWAP_READY == currentSwapMode)
            {
                ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_SET_IN_PREPARE, &currentSwapMode, \
                                    &currentSwapBlockStatus, &nextSwapBlockStatus, pFlashCommandSequence);
            }
            else
            {
            }
            if ((NULL_SWAP_CALLBACK != pSwapCallback) && (FTFx_OK == ret))
            {
                swapContinue = pSwapCallback(currentSwapMode);
                if (swapContinue == true)
                {
                    ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_REPORT_STATUS, &currentSwapMode, \
                                        &currentSwapBlockStatus, &nextSwapBlockStatus, pFlashCommandSequence);
                }
            }
        }
        else
        {
        }
        if ((NULL_SWAP_CALLBACK == pSwapCallback) && (FTFx_SWAP_UPDATE == currentSwapMode))
        {
            ret = FlashEraseSector(pSSDConfig, addr + (pSSDConfig->PFlashSize >> 1U), \
                                   (uint32_t)FSL_FEATURE_FLS_PF_BLOCK_SECTOR_SIZE, \
                                   pFlashCommandSequence);
            if (FTFx_OK == ret)
            {
                ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_REPORT_STATUS, &currentSwapMode, \
                                    &currentSwapBlockStatus, &nextSwapBlockStatus, pFlashCommandSequence);
            }
        }
        if (FTFx_SWAP_UPDATE_ERASED == currentSwapMode)
        {
            if (NULL_SWAP_CALLBACK == pSwapCallback)
            {
                swapContinue = true;
            }
            else
            {
                swapContinue = pSwapCallback(currentSwapMode);
            }
            if (swapContinue == true)
            {
                ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_SET_IN_COMPLETE, &currentSwapMode, \
                                    &currentSwapBlockStatus, &nextSwapBlockStatus, pFlashCommandSequence);
            }
        }
    }
    return (ret);
}
flash_drv_status_t PFlashSwap ( const flash_ssd_config_t * pSSDConfig , uint32_t addr , flash_swap_callback_t pSwapCallback , flash_command_sequence_t pFlashCommandSequence ) { #ifdef DEV_ERROR_DETECT DEV_ASSERT ( pSSDConfig != NULL ) ; DEV_ASSERT ( pSwapCallback != NULL ) ; DEV_ASSERT ( pFlashCommandSequence != NULL ) ; #endif flash_drv_status_t ret = FTFx_OK ; uint8_t currentSwapMode , currentSwapBlockStatus , nextSwapBlockStatus ; bool swapContinue ; currentSwapMode = 0xFFU ; currentSwapBlockStatus = 0xFFU ; nextSwapBlockStatus = 0xFFU ; swapContinue = false ; ret = PFlashSwapCtl ( pSSDConfig , addr , FTFx_SWAP_REPORT_STATUS , & currentSwapMode , & currentSwapBlockStatus , & nextSwapBlockStatus , pFlashCommandSequence ) ; if ( FTFx_OK == ret ) { if ( ( FTFx_SWAP_UNINIT == currentSwapMode ) || ( FTFx_SWAP_READY == currentSwapMode ) || ( FTFx_SWAP_UPDATE == currentSwapMode ) ) { if ( FTFx_SWAP_UNINIT == currentSwapMode ) { ret = PFlashSwapCtl ( pSSDConfig , addr , FTFx_SWAP_SET_INDICATOR_ADDR , & currentSwapMode , & currentSwapBlockStatus , & nextSwapBlockStatus , pFlashCommandSequence ) ; } else if ( FTFx_SWAP_READY == currentSwapMode ) { ret = PFlashSwapCtl ( pSSDConfig , addr , FTFx_SWAP_SET_IN_PREPARE , & currentSwapMode , & currentSwapBlockStatus , & nextSwapBlockStatus , pFlashCommandSequence ) ; } else { } if ( ( NULL_SWAP_CALLBACK != pSwapCallback ) && ( FTFx_OK == ret ) ) { swapContinue = pSwapCallback ( currentSwapMode ) ; if ( swapContinue == true ) { ret = PFlashSwapCtl ( pSSDConfig , addr , FTFx_SWAP_REPORT_STATUS , & currentSwapMode , & currentSwapBlockStatus , & nextSwapBlockStatus , pFlashCommandSequence ) ; } } } else { } if ( ( NULL_SWAP_CALLBACK == pSwapCallback ) && ( FTFx_SWAP_UPDATE == currentSwapMode ) ) { ret = FlashEraseSector ( pSSDConfig , addr + ( pSSDConfig -> PFlashSize >> 1U ) , ( uint32_t ) FSL_FEATURE_FLS_PF_BLOCK_SECTOR_SIZE , pFlashCommandSequence ) ; if ( FTFx_OK == ret ) { ret = PFlashSwapCtl ( pSSDConfig , addr , FTFx_SWAP_REPORT_STATUS , & currentSwapMode , & currentSwapBlockStatus , & nextSwapBlockStatus , pFlashCommandSequence ) ; } } if ( FTFx_SWAP_UPDATE_ERASED == currentSwapMode ) { if ( NULL_SWAP_CALLBACK == pSwapCallback ) { swapContinue = true ; } else { swapContinue = pSwapCallback ( currentSwapMode ) ; } if ( swapContinue == true ) { ret = PFlashSwapCtl ( pSSDConfig , addr , FTFx_SWAP_SET_IN_COMPLETE , & currentSwapMode , & currentSwapBlockStatus , & nextSwapBlockStatus , pFlashCommandSequence ) ; } } } return ( ret ) ; }
FUNCTION
FUNCTION
/* Return code variable */ /* Report current swap state */ /* If current swap mode is Uninitialized */ /* Initialize Swap to Initialized/READY state */ /* If current swap mode is Initialized/Ready */ /* Initialize Swap to UPDATE state */ /* if (FTFx_SWAP_UPDATE == currentSwapMode) do nothing */ /* Check for the success of command execution
             * Report the current swap state to user via callback
             */ /* Report current swap state */ /* Do nothing */ /* Erase indicator sector in non active block to proceed swap system to update-erased state */ /* Now the swap state must be Update-Erased, so report current swap state */ /* If current swap mode is Update or Update-Erased */ /* Progress Swap to COMPLETE State */