/**
*   @file    Fls_Flash_Code.c
*   @version 1.0.0
*
*   @brief   AUTOSAR Fls - AUTOSAR Module Flash Driver.
*   @details Flash IPV_FLASHV2 driver source code.
*
*   @addtogroup FLS
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : IPV_FLASHV2
*   Dependencies         : none
*
*   Autosar Version      : 4.3.1
*   Autosar Revision     : ASR_REL_4_3_REV_0001
*   Autosar Conf.Variant :
*   SW Version           : 1.0.0
*   Build Version        : MPC5777C_MCAL_1_0_0_RTM_ASR_REL_4_3_REV_0001_20190315
*
*   (c) Copyright 2006-2016 Freescale Semiconductor, Inc. 
*       Copyright 2017-2019 NXP
*   All Rights Reserved.
==================================================================================================*/

#ifdef __cplusplus
extern "C"{
#endif

/**
* @page misra_violations MISRA-C:2012 violations
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.1, External identifiers shall be distinct.
* Identifiers (internal and external) shall not rely on the significance of more than 31 characters.
* The used compilers use more than 31 chars for identifiers.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.2, Identifiers declared in the same scope and namespace shall be distinct.
* This violation is due to the requirement that requests to have a file version check.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.4, Macro identifiers shall be distinct.
* This violation is due to the requirement that requests to have a file version check.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.5, Identifiers shall be distinct from macro names.
* This violation is due to the requirement that requests to have a file version check.
*
* @section Fls_Flash_c_REF_1
* Violates MISRA 2012 Required Directive 4.10, Precautions shall be taken in order to prevent the contents of a header file being included more than once.
* This violation is not fixed since the inclusion of <MA>_MemMap.h is as per AUTOSAR requirement [SWS_MemMap_00003].
*
* @section Fls_Flash_c_REF_2
* Violates MISRA 2012 Advisory Rule 11.4, A conversion should not be performed between a pointer to object and an integer type.
* The cast is used to access memory mapped registers.
*
* @section Fls_Flash_c_REF_3
* Violates MISRA 2012 Required Rule 11.6, A cast shall not be performed between pointer to void and an arithmetic type.
* This violation is due to casting unsigned long to pointer and access these addresses for updating  contents in that address.
*
* @section Fls_Flash_c_REF_4
* Violates MISRA 2012 Advisory Rule 15.5, A function should have a single point of exit at the end
* This violation is not fixed since if hardware error is detected it should return from the function
*
* @section Fls_Flash_c_REF_5
* Violates MISRA 2012 Advisory Rule 20.1, #Include directives should only be preceded by preprocessor directives or comments.
* <MA>_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR.
*
* @section Fls_Flash_c_REF_6
* Violates MISRA 2012 Required Rule 13.5, The right hand operand of a logical && or || operator shall not contain persistent side effects.
* This violation is because of complex statement
*
* @section Fls_Flash_c_REF_7
* Violates MISRA 2012 Advisory Rule 18.4, The +,- += and -= operators should not be applied to an expression of pointer type
* This violation is because of complex statement
*
* @section Fls_Flash_c_REF_8
* Violates MISRA 2012 Required Rule 11.3, A cast shall not be performed between a pointer to object type and a pointer to a different object type.
* The cast can not be avoided as it is used to access memory mapped.
*
* @section Fls_Flash_c_REF_9
* Violates MISRA 2012 Required Rule 11.1, Conversions shall not be performed between a pointer to a function and any other type.
* This violation is because of complex statement.
*
* @section Fls_Flash_c_REF_10
* Violates MISRA 2012 Required Rule 10.8, The value of a composite expression shall not be cast to a different essential
* type category or a wider essential type.
* This violation is due to the complex expression (macro) is given as parameter is not evaluated at preprocessing step.
*
* @section Fls_Flash_c_REF_11
* Violates MISRA 2012 Advisory Rule 8.9, An object should be defined at block scope if its identifier only appears in a single function.
* This violation is because other functions also used the object but do not build due to depending the guardian.
*
* @section Fls_Flash_c_REF_12
* Violates MISRA 2012 Advisory Rule 8.7, Function and object should not be defined with external linkage if they are referenced in only
* one translation unit.
* Function may be called in user callout functions or depend the guardian.
*
* @section Fls_Flash_c_REF_13
* Violates MISRA 2012 Required Rule 1.3, There shall be no occurrence of undefined or critical unspecified behaviour.
* This violation is because of complex statement
*
* @section Fls_Flash_c_REF_14
* Violates MISRA 2012 Required Rule 13.2, The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
* This violation is because of complex statement
*
* @section Fls_Flash_c_REF_15
* Violates MISRA 2012 Required Rule 14.4, The controlling expression of an if statement and the controlling expression 
* of an iteration-statement shall have essentially Boolean type.
* SMCAL coding guideline, Rule 3.3:
* Multi-statement macros shall be wrapped in a do-while loop
* so the macro can appear safely inside if clauses or other places that expect a single statement or a statement block
*/

/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Fls.h"
#include "Fls_Flash.h"
#include "Fls_Flash_Types.h"
#include "Reg_eSys_FLASHC.h"
#include "Det.h"
#include "SchM_Fls.h"
#include "StdRegMacros.h"

#if ( (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON) && (STD_OFF == FLS_TIMEOUT_AS_LOOP) )
#include "Os.h"
#endif /* #if ((STD_OFF == FLS_TIMEOUT_AS_LOOP) && (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)) */

#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
#include "RegLockMacros.h"
#endif /* STD_ON == FLS_ENABLE_USER_MODE_SUPPORT */
/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define FLS_FLASH_VENDOR_ID_C                      43
#define FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C       4
#define FLS_FLASH_AR_RELEASE_MINOR_VERSION_C       3
#define FLS_FLASH_AR_RELEASE_REVISION_VERSION_C    1
#define FLS_FLASH_SW_MAJOR_VERSION_C               1
#define FLS_FLASH_SW_MINOR_VERSION_C               0
#define FLS_FLASH_SW_PATCH_VERSION_C               0

/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if current file and Fls header file are of the same vendor */
#if (FLS_FLASH_VENDOR_ID_C != FLS_VENDOR_ID)
    #error "Fls_Flash.c and Fls.h have different vendor ids"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Fls header file are of the same Autosar version */
    #if ((FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C    != FLS_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_FLASH_AR_RELEASE_MINOR_VERSION_C    != FLS_AR_RELEASE_MINOR_VERSION) || \
         (FLS_FLASH_AR_RELEASE_REVISION_VERSION_C    != FLS_AR_RELEASE_REVISION_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_Flash.c and Fls.h are different"
    #endif
#endif
/* Check if current file and Fls header file are of the same Software version */
#if ((FLS_FLASH_SW_MAJOR_VERSION_C != FLS_SW_MAJOR_VERSION) || \
     (FLS_FLASH_SW_MINOR_VERSION_C != FLS_SW_MINOR_VERSION) || \
     (FLS_FLASH_SW_PATCH_VERSION_C != FLS_SW_PATCH_VERSION) \
    )
    #error "Software Version Numbers of Fls_Flash.c and Fls.h are different"
#endif
/* Check if current file and Reg_eSys_FLASHC.h header file are of the same vendor */
#if (FLS_FLASH_VENDOR_ID_C != ESYS_FLASHC_VENDOR_ID)
    #error "Fls_Flash.c and Reg_eSys_FLASHC.h have different vendor ids"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Fls header file are of the same Autosar version */
    #if ((FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C    != ESYS_FLASHC_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_FLASH_AR_RELEASE_MINOR_VERSION_C    != ESYS_FLASHC_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_Flash.c and Reg_eSys_FLASHC.h are different"
    #endif
#endif
/* Check if current file and Fls header file are of the same Software version */
#if ((FLS_FLASH_SW_MAJOR_VERSION_C != ESYS_FLASHC_SW_MAJOR_VERSION) || \
     (FLS_FLASH_SW_MINOR_VERSION_C != ESYS_FLASHC_SW_MINOR_VERSION) || \
     (FLS_FLASH_SW_PATCH_VERSION_C != ESYS_FLASHC_SW_PATCH_VERSION) \
    )
    #error "Software Version Numbers of Fls_Flash.c and Reg_eSys_FLASHC.h are different"
#endif

/* Check if current file and Fls_Flash_Types.h header file are of the same vendor */
#if (FLS_FLASH_VENDOR_ID_C != FLS_FLASH_TYPES_VENDOR_ID)
    #error "Fls_Flash.c and Fls_Flash_Types.h have different vendor ids"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Fls_Flash_Types header file are of the same Autosar version */
    #if ((FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C    != FLS_FLASH_TYPES_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_FLASH_AR_RELEASE_MINOR_VERSION_C    != FLS_FLASH_TYPES_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_Flash.c and Fls_Flash_Types.h are different"
    #endif
#endif
/* Check if current file and Fls_Flash_Types header file are of the same Software version */
#if ((FLS_FLASH_SW_MAJOR_VERSION_C != FLS_FLASH_TYPES_SW_MAJOR_VERSION) || \
     (FLS_FLASH_SW_MINOR_VERSION_C != FLS_FLASH_TYPES_SW_MINOR_VERSION) || \
     (FLS_FLASH_SW_PATCH_VERSION_C != FLS_FLASH_TYPES_SW_PATCH_VERSION) \
    )
    #error "Software Version Numbers of Fls_Flash.c and Fls_Flash_Types.h are different"
#endif

#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and StdRegMacros header file are of the same Autosar version */
    #if ((FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C    != STDREGMACROS_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_FLASH_AR_RELEASE_MINOR_VERSION_C    != STDREGMACROS_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_Flash.c and StdRegMacros.h are different"
    #endif
#endif

#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Det header file are of the same Autosar version */
    #if ((FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C != DET_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_FLASH_AR_RELEASE_MINOR_VERSION_C != DET_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls.c and Det.h are different"
    #endif
#endif

#if ( (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON) && (STD_OFF == FLS_TIMEOUT_AS_LOOP) )
/* Check if current file and Os header file are of the same Autosar version */
#if ((FLS_FLASH_AR_RELEASE_MAJOR_VERSION_C != OS_AR_RELEASE_MAJOR_VERSION) || \
     (FLS_FLASH_AR_RELEASE_MINOR_VERSION_C != OS_AR_RELEASE_MINOR_VERSION)  \
    )
    #error "AutoSar Version Numbers of Fls_Flash.c and Os.h are different"
#endif
#endif /*#if ((STD_OFF == FLS_TIMEOUT_AS_LOOP) && (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON))*/

/*==================================================================================================
                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/
#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)
#if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)
#define FLS_START_SEC_CODE
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
#ifdef FLS_FLASH_REG_PROT_AVAILABLE
static FUNC(void, FLS_CODE) Fls_Flash_SetUserAccessAllowed(void);
#endif /* FLS_FLASH_REG_PROT_AVAILABLE */
#endif /* STD_ON == FLS_ENABLE_USER_MODE_SUPPORT */
#if((FLS_ERASE_VERIFICATION_ENABLED == STD_ON) || (FLS_WRITE_VERIFICATION_ENABLED == STD_ON) || \
    (FLS_COMPARE_API == STD_ON) || (FLS_BLANK_CHECK_API == STD_ON))
static FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_VerifyMemoryArea
(
    VAR(volatile Fls_Flash_DataBusWidthType, AUTOMATIC ) u32FlashAreaPtr,
    P2CONST( Fls_Flash_DataBusWidthType, AUTOMATIC, FLS_APPL_CONST ) pUserBufferPtr,
    VAR( Fls_LengthType, AUTOMATIC) u32DataLength
);
#endif /* FLS_ERASE_VERIFICATION_ENABLED  || FLS_WRITE_VERIFICATION_ENABLED \
          FLS_COMPARE_API == STD_ON || FLS_BLANK_CHECK_API == STD_ON */
#if( FLS_ECC_CHECK == STD_ON )
static FUNC(uint32, FLS_CODE) Fls_Flash_GetPflashDataErrorSuppressionStatus(void);
#endif /*( FLS_ECC_CHECK == STD_ON )*/
static FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_ReadBytes
(
    VAR(Fls_DataBytesType, AUTOMATIC) u8DataLength
);
static FUNC( void, FLS_CODE ) Fls_Flash_PageWrite
(
    CONST(uint32, AUTOMATIC) u32TotalBytes
);
static FUNC( boolean, FLS_CODE ) Fls_Flash_FinishHVOperation( void );

#if( FLS_ECC_CHECK == STD_ON )
static FUNC( boolean, FLS_CODE ) Fls_Flash_ECCTest( void );
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

#define FLS_STOP_SEC_CODE
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

/*==================================================================================================
                                       GLOBAL VARIABLES
==================================================================================================*/

/*==================================================================================================
                                       LOCAL VARIABLES
==================================================================================================*/
#define FLS_START_SEC_VAR_INIT_UNSPECIFIED
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#if( FLS_ECC_CHECK == STD_ON )
/**
    @brief Current status of the sector read operation. The Fls_DsiHandler function can terminate
        the read operation by setting this volatile variable to FLASH_E_FAILED
*/
/* @violates @ref Fls_Flash_c_REF_11 An object should be defined at block scope if its identifier only appears in a single function. */
static VAR( volatile Fls_LLDReturnType, FLS_VAR ) Fls_Flash_eReadStatus = FLASH_E_OK;

/**
    @brief Current status of the sector compare operation. The Fls_DsiHandler function can terminate
        the compare operation by setting this volatile variable to FLASH_E_FAILED
*/
/* @violates @ref Fls_Flash_c_REF_11 An object should be defined at block scope if its identifier only appears in a single function. */
static VAR( volatile Fls_LLDReturnType, FLS_VAR ) Fls_Flash_eCompareStatus = FLASH_E_OK;
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

#define FLS_STOP_SEC_VAR_INIT_UNSPECIFIED
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#define FLS_START_SEC_VAR_INIT_8
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

/**
    @brief Physical address of currently read uint8, uint32 from flash
*/
/* @violates @ref Fls_Flash_c_REF_11 An object should be defined at block scope if its identifier only appears in a single function. */
static P2VAR(volatile uint8, FLS_VAR, FLS_APPL_DATA) volatile Fls_Flash_pReadAddressPtr = NULL_PTR;
/**
    @brief Physical address of currently compared uint8, uint32 from user buffer
*/
/* @violates @ref Fls_Flash_c_REF_11 An object should be defined at block scope if its identifier only appears in a single function. */
static P2CONST(volatile uint8, FLS_VAR, FLS_APPL_CONST) volatile Fls_Flash_pCompareAddressPtr = NULL_PTR;

#define FLS_STOP_SEC_VAR_INIT_8
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#define FLS_START_SEC_VAR_INIT_32
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

/**
    @brief 'double word program operation' iterator
*/
static VAR(uint32, FLS_VAR) Fls_Flash_u32ProgramCycle = 0UL;

/**
    @brief 'double word program operation' count
*/
static VAR(uint32, FLS_VAR) Fls_Flash_u32DoubleWordToCopy = 0UL;
/**
    @brief 'number of word / double word needed for program operation'
*/
static VAR(uint32, FLS_VAR) Fls_Flash_u32DoubleWordCounter = 0UL;

/**
    @brief 'read variables'
*/
static VAR(uint8, AUTOMATIC) Fls_Flash_u8ReadAddress8 = 0U;
static VAR(uint32, AUTOMATIC) Fls_Flash_u32ReadAddress32 = 0U;

/**
    @brief 'data copy' auxiliary pointers
*/
static P2VAR(volatile uint32, FLS_VAR, FLS_APPL_DATA) Fls_Flash_pTargetAddressPtr = NULL_PTR;
static P2CONST(uint32, FLS_VAR, FLS_APPL_CONST) Fls_Flash_pSourceAddressPtr = NULL_PTR;
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
static P2CONST(volatile uint32, FLS_VAR, FLS_APPL_CONST) Fls_Flash_pEndAddressPtr = NULL_PTR;
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */

#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
static VAR(uint32, AUTOMATIC) Fls_Flash_u32Abort_Timeout_Counter = 0UL;
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

#define FLS_STOP_SEC_VAR_INIT_32
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#define FLS_START_SEC_CONST_32
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#if ((FLS_BLANK_CHECK_API == STD_ON) || (FLS_ERASE_VERIFICATION_ENABLED == STD_ON))
/**
    @brief Flash erased value for erased state
*/
/* @violates @ref Fls_Flash_c_REF_11 An object should be defined at block scope if its identifier only appears in a single function. */
static CONST(uint32, FLS_CONST) Fls_Flash_ErasedValue = FLS_ERASED_VALUE;
#endif

#define FLS_STOP_SEC_CONST_32
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"
/*==================================================================================================
                                       LOCAL FUNCTIONS
==================================================================================================*/
#define FLS_START_SEC_CODE
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"

#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
#ifdef FLS_FLASH_REG_PROT_AVAILABLE
/**
* @brief        Enable user mode support to access C55FMC registers
*
* @details      Set UAA bit in FLASH_REG_PROT_GCR to allow user access locked registers in C55FMC module
*
* @param[in]    none
* @retval       none
*
* @pre         The user mode is enabled
*
*/
static FUNC(void, FLS_CODE) Fls_Flash_SetUserAccessAllowed(void)
{
   /* Set UAA bit in REG_PROT register */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    SET_USER_ACCESS_ALLOWED(FLASH_BASEADDR, FLASH_PERIPH_SIZE_U32);
}
#endif /* ifdef FLS_FLASH_REG_PROT_AVAILABLE */
#endif /* STD_ON == FLS_ENABLE_USER_MODE_SUPPORT */

/**
* @brief          Disables HV operation with timeout.
* @return         Success (DONE)
*/
static FUNC( boolean, FLS_CODE ) Fls_Flash_FinishHVOperation( void )
{
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
    VAR(uint32, AUTOMATIC) u32TimerCounterAbort = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_ABT_TIMEOUT_VALUE);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

    VAR(boolean, AUTOMATIC) bRetVal;

    /* disable HV to finalize/abort the operation */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    MCR_BIT_CLEAR32(FLASH_MCR_EHV_U32);

#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
    #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
    /* Return  the  current  tick value of the counter via <Value> */
    (void)GetCounterValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue);
    #endif
    /* wait until done or abort timeout is reached */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    while((0U == REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_DONE_U32)) && (0U < u32TimerCounterAbort) )
    {
        #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
        /*
        * Gets the number of ticks between the current tick value and a previously read tick value.
        * And It shall also return  the  current  tick  value  of  the counter in the <Value> parameter
        */
        (void)GetElapsedValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue, &Fls_u32ElapsedTime);
        if(u32TimerCounterAbort > Fls_u32ElapsedTime)
        {
            u32TimerCounterAbort -= Fls_u32ElapsedTime;
        }
        else
        {
            u32TimerCounterAbort = 0U;
        }
        #else
        --u32TimerCounterAbort;
        #endif /*#if (STD_OFF == FLS_TIMEOUT_AS_LOOP)*/
    }
#else
    /* wait until done or abort timeout is reached */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    while(0U == REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_DONE_U32))
    {
    }
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

    /* return true if DONE */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    if (0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_DONE_U32))
    {
        bRetVal = (boolean)TRUE;
    }
    else
    {
        bRetVal = (boolean)FALSE;
    }

    MCAL_FAULT_INJECTION_POINT(FLS_FIP_10_FLS_FLASH_FINISH_HV_OPERATION);

    return(bRetVal);
}


/**
* @brief          Initialize flash hardware.
*/
FUNC( void, FLS_CODE ) Fls_Flash_Init( void )
{
    VAR(uint32, AUTOMATIC) u32McrValue = 0UL;
    VAR(uint32, AUTOMATIC) u32ConfigIter=0UL;

    Fls_eLLDJobResult = MEMIF_JOB_OK;
#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
#ifdef FLS_FLASH_REG_PROT_AVAILABLE
    /* Enable user mode support */
    /* @violates @ref Fls_Flash_c_REF_15 The controlling expression 
    of an if statement and the controlling expression of an iteration-statement shall have essentially Boolean type.*/
    Mcal_Trusted_Call(Fls_Flash_SetUserAccessAllowed);

#endif /* FLS_FLASH_REG_PROT_AVAILABLE */
#endif /* STD_ON == FLS_ENABLE_USER_MODE_SUPPORT */

    /* Check suspended bit */
    if( FLASH_E_FAILED == Fls_Flash_AbortSuspended(FLS_INIT_ID))
    {
        Fls_eLLDJob = FLASH_JOB_NONE;
        Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return;
    }
    /* update the value of MCR register */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    u32McrValue = REG_READ32(FLASH_MCR_ADDR32);
    /* abort possible pending normal erase/program operation */
    if((0U != (u32McrValue & FLASH_MCR_ERS_U32)) || (0U != (u32McrValue & FLASH_MCR_PGM_U32)))
    {
       /* manage abort possible pending normal erase/program operation */
        if( (boolean)TRUE == Fls_Flash_FinishHVOperation() )
        {
            /* terminate erase operation */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            MCR_BIT_CLEAR32(FLASH_MCR_ERS_U32);
            /* terminate program operation */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32);
        }
        else
        {
            /* Error, operation was not aborted */
            if( 0U != (u32McrValue & FLASH_MCR_ERS_U32) )
            {
                (void)Det_ReportTransientFault((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_INIT_ID, FLS_E_ERASE_FAILED);
            }
            if( 0U != (u32McrValue & FLASH_MCR_PGM_U32) )
            {
                (void)Det_ReportTransientFault((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_INIT_ID, FLS_E_WRITE_FAILED);
            }
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        }
    }

    /* iterate over all configured sectors (they are allowed to be sorted
       independently of their physical order) */
    for (u32ConfigIter = 0U; u32ConfigIter < Fls_pConfigPtr->u32SectorCount; u32ConfigIter++ )
    {
        /* This sector is configured to be unlocked? */
        if (1U == (*(Fls_pConfigPtr->paSectorUnlock))[u32ConfigIter])
        {
            /* Directly set protection bit */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_BIT_CLEAR32((uint32)(*((*(Fls_pConfigPtr->pSectorList))[u32ConfigIter])).u32AddrSpaceBloLockRegAddr,
                            /*
                            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                            */
                            (uint32)(*((*(Fls_pConfigPtr->pSectorList))[u32ConfigIter])).u32AddrSpaceBloLockValue \
                           );
        }
    } /* for (u32ConfigIter = 0U; u32ConfigIter < Fls_pConfigPtr->u32SectorCount; u32ConfigIter++ ) */

}

/**
* @brief          Managing Abort Erase suspend.
* @details        An erase suspend is resumed and after immediately aborted
*/
/*
* @violates @ref Fls_Flash_c_REF_12 Function and object should not be defined with external linkage
* if they are referenced in only one translation unit
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_AbortSuspended( VAR( uint8, AUTOMATIC) u8ServiceID )
{
    VAR(uint32, AUTOMATIC) u32McrValue = 0UL;
    VAR( Fls_LLDReturnType, AUTOMATIC ) eRetVal = FLASH_E_OK;

    MCAL_FAULT_INJECTION_POINT(FLS_FIP_5_FLS_FLASH_ABORT_SUSPENDED);
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    u32McrValue = REG_READ32(FLASH_MCR_ADDR32);

    if(0U != (u32McrValue & FLASH_MCR_PSUS_U32))
    {
        /* suspended operation cannot be aborted, */
        /* so resume previously suspended program operation, and */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        MCR_BIT_CLEAR32(FLASH_MCR_PSUS_U32);

        MCAL_FAULT_INJECTION_POINT(FLS_FIP_6_FLS_FLASH_ABORT_SUSPENDED);
        /* if definitely in suspended operation state ...
        (PSUS Bit can be cleared only if suspended operation is completed)*/
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if(0U == REG_BIT_GET32(FLASH_MCR_ADDR32,FLASH_MCR_PSUS_U32))
        {
            /* immediately abort it */
            if( (boolean)TRUE == Fls_Flash_FinishHVOperation() )
            {
                /* terminate aborted program operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32);
            }
            else
            {
                /* Error, program was not aborted */
                #if(FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, u8ServiceID, FLS_E_TIMEOUT);
                #endif
                eRetVal = FLASH_E_FAILED;
            }
        }
        else
        {
            /* Error, program was not resumed because it is not yet suspended */
            (void)Det_ReportTransientFault((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, u8ServiceID, FLS_E_WRITE_FAILED);
            eRetVal = FLASH_E_FAILED;
        }
    }

    MCAL_FAULT_INJECTION_POINT(FLS_FIP_3_FLS_FLASH_ABORT_SUSPENDED);

    /* update the value of MCR register */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    u32McrValue = REG_READ32(FLASH_MCR_ADDR32);

    if(0U != (u32McrValue & FLASH_MCR_ESUS_U32))
    {
        /* suspended operation cannot be aborted, */
        /* so resume previously suspended erase operation, and */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            MCR_BIT_CLEAR32(FLASH_MCR_ESUS_U32);
            MCAL_FAULT_INJECTION_POINT(FLS_FIP_4_FLS_FLASH_ABORT_SUSPENDED);

            /* if definitely in suspended operation state ...
              (ESUS Bit can be cleared only if suspended operation is completed)*/
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            if(0U == REG_BIT_GET32(FLASH_MCR_ADDR32,FLASH_MCR_ESUS_U32))
            {
                /* immediately abort it */
                if( (boolean)TRUE == Fls_Flash_FinishHVOperation() )
                {
                    /* terminate aborted erase operation */
                    /*
                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                    */
                    MCR_BIT_CLEAR32(FLASH_MCR_ERS_U32);
                }
                else
                {
                    /* Error, erase was not aborted */
                    #if(FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
                    (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, u8ServiceID, FLS_E_TIMEOUT);
                    #endif
                    eRetVal = FLASH_E_FAILED;
                }
            }
            else
            {
                /* Error, erase was not resumed because it is not yet suspended */
                (void)Det_ReportTransientFault((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, u8ServiceID, FLS_E_ERASE_FAILED);
                eRetVal = FLASH_E_FAILED;
            }
    }

    return eRetVal;
}

#if((FLS_ERASE_VERIFICATION_ENABLED == STD_ON) || (FLS_WRITE_VERIFICATION_ENABLED == STD_ON) || \
    (FLS_COMPARE_API == STD_ON) || (FLS_BLANK_CHECK_API == STD_ON))
/**
* @brief          Check that the addressed flash memory area is erased or written
* @details        The function compares the contents of the addressed flash memory
*                 area against the value of an erased flash cell to check that the block
*                 has been completely erased or written
*
* @param[in]      1           u32FlashAreaPtr is variable to contain first address of the addressed flash memory area
*                             aligned to MCU bus width boundary
* @param[in]      2           pUserBufferPtr first address of the application buffer area
*                             aligned to MCU bus width boundary
* @param[in]      3           u32DataLength number of bytes to compare aligned to the MCU bus
*                             width
*
* @return         Fls_LLDReturnType
* @retval         FLASH_E_OK operation succeeded
* @retval         FLASH_E_FAILED operation failed due to hardware error (ECC)
*                 or contents of the addressed memory area don't match with value of
*                 an erased flash cell
*/
static FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_VerifyMemoryArea
(
    VAR(volatile Fls_Flash_DataBusWidthType, AUTOMATIC ) u32FlashAreaPtr,
    P2CONST( Fls_Flash_DataBusWidthType, AUTOMATIC, FLS_APPL_CONST ) pUserBufferPtr,
    VAR(Fls_LengthType, AUTOMATIC) u32DataLength
)
{
    VAR(Fls_DataBytesType, AUTOMATIC) u8DataLength = FLS_SIZE_1BYTE;
#if( FLS_ECC_CHECK == STD_ON )
    Fls_Flash_eCompareStatus = FLASH_E_PENDING;
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

    /* Start address to be compared */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    Fls_Flash_pReadAddressPtr = (uint8 *)u32FlashAreaPtr;
    /*This is referred to as an erase interlock write.*/
    
    /* Source address to be compared */
    if(NULL_PTR != pUserBufferPtr)
    {
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        Fls_Flash_pCompareAddressPtr = (const uint8 *)pUserBufferPtr;
    }
#if(( FLS_ERASE_VERIFICATION_ENABLED == STD_ON ) || (FLS_BLANK_CHECK_API == STD_ON))
    else
    {
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        Fls_Flash_pCompareAddressPtr = (volatile const uint8 *)(&Fls_Flash_ErasedValue);
    }
#endif /* #if(( FLS_ERASE_VERIFICATION_ENABLED == STD_ON ) || (FLS_BLANK_CHECK_API == STD_ON)) */

    do
    {
        /* Verifying 4 byte if it is aligned */
        /* Compiler_Warning: see fls_c_REF_CW_01 */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        * @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects.
        */
        if((4U <= u32DataLength ) && (0U == ( (uint32)Fls_Flash_pReadAddressPtr % 4U )) && (0U == ( (uint32)Fls_Flash_pCompareAddressPtr % 4U )))
        {
            u8DataLength = FLS_SIZE_4BYTE;
        }
        else /* Verifying 1 byte if it is not aligned */
        {
            u8DataLength = FLS_SIZE_1BYTE;
        }

        if(FLASH_E_FAILED == Fls_Flash_ReadBytes(u8DataLength))
        {
            /* Errors occurred when verify the memory flash*/
            /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
            return FLASH_E_FAILED;
        }

        if (FLS_SIZE_1BYTE == u8DataLength)
        {
            if( *Fls_Flash_pCompareAddressPtr != Fls_Flash_u8ReadAddress8 )
            {
#if( FLS_ECC_CHECK == STD_ON )
                if( FLASH_E_PENDING == Fls_Flash_eCompareStatus )
                {
                    Fls_Flash_eCompareStatus = FLASH_E_BLOCK_INCONSISTENT;
                }
#else
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return FLASH_E_BLOCK_INCONSISTENT;        /* Read data differs from expected value */
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */
            }
        }
        /* Compare 4byte*/
        else
        {
            /* @violates @ref Fls_Flash_c_REF_8 A cast shall not be performed between a pointer to object type and a pointer to a different object type */
            if( ((uint32)(*(const volatile uint32 *)Fls_Flash_pCompareAddressPtr)) != Fls_Flash_u32ReadAddress32 )
            {
#if( FLS_ECC_CHECK == STD_ON )
                if( FLASH_E_PENDING == Fls_Flash_eCompareStatus )
                {
                    Fls_Flash_eCompareStatus = FLASH_E_BLOCK_INCONSISTENT;
                }
#else
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return FLASH_E_BLOCK_INCONSISTENT;         /* Read data differs from expected value */
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */
            }
        }
        
        if(NULL_PTR != pUserBufferPtr)
        {
            /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type*/
            Fls_Flash_pCompareAddressPtr += (uint32)u8DataLength;
        }
        /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type*/
        Fls_Flash_pReadAddressPtr += (uint32)u8DataLength;
        u32DataLength -= (uint32)u8DataLength;
#if( FLS_ECC_CHECK == STD_ON )
    /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
    }while((u32DataLength > 0U) && ( FLASH_E_PENDING == Fls_Flash_eCompareStatus ));
#else /* #if( FLS_ECC_CHECK == STD_ON ) */
    }while(u32DataLength > 0U);
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

#if( FLS_ECC_CHECK == STD_ON )
    if( FLASH_E_PENDING == Fls_Flash_eCompareStatus )
    {
        Fls_Flash_eCompareStatus = FLASH_E_OK;
    }
    return Fls_Flash_eCompareStatus;
#else /* #if( FLS_ECC_CHECK == STD_ON ) */
    return FLASH_E_OK;
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */
}
#endif /* FLS_ERASE_VERIFICATION_ENABLED  || FLS_WRITE_VERIFICATION_ENABLED \
          FLS_COMPARE_API == STD_ON || FLS_BLANK_CHECK_API == STD_ON */
/**
* @brief          Check the status of PFlash Data Error Suppression
* @details        The function read Data_Error_Suppression bit from PFLASH_PFCRx register
*
* @param[in]      None
*
* @return         Uint32
* @retval         Status of PFlash Data Error Suppression
*/
#if( FLS_ECC_CHECK == STD_ON )
static FUNC(uint32, FLS_CODE)Fls_Flash_GetPflashDataErrorSuppressionStatus(void)
{
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    return REG_BIT_GET32(PFLASH_PFCRx_ADDR32, PFLASH_PFCRx_DERR_SUP_U32 );
}
#endif /*( FLS_ECC_CHECK == STD_ON )*/
/**
* @brief          Check that the addressed flash memory area is erased or written
* @details        The function compares the contents of the addressed flash memory
*                 area against the value of an erased flash cell to check that the block
*                 has been completely erased or written
*
* @param[in]      1           pUserBufferPtr first address of the application buffer area
*                             aligned to MCU bus width boundary
* @param[in]      2           u32DataLength number of bytes to compare aligned to the MCU bus
*                             width
*
* @return         Fls_LLDReturnType
* @retval         FLASH_E_OK operation succeeded
* @retval         FLASH_E_FAILED operation failed due to hardware error (ECC)
*                 or contents of the addressed memory area don't match with value of
*                 an erased flash cell
*/
static FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_ReadBytes
(
    VAR(Fls_DataBytesType, AUTOMATIC) u8DataLength
)
{
    VAR(Fls_LLDReturnType, AUTOMATIC) eRetVal = FLASH_E_OK;

#if( FLS_ECC_CHECK == STD_ON )
    VAR( boolean, AUTOMATIC ) bWasEccEvent;
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

#if( FLS_ECC_CHECK == STD_ON )
#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
    if(0U != Mcal_Trusted_Call_Return(Fls_Flash_GetPflashDataErrorSuppressionStatus))
#else
    if(0U != Fls_Flash_GetPflashDataErrorSuppressionStatus())
#endif
    {
            /* start flash access section: implementation depends on integrator */
            if( NULL_PTR != Fls_pConfigPtr->startFlashAccessNotifPtr )
            {
                /* Call FlsStartFlashAccessNotif function if configured */
                Fls_pConfigPtr->startFlashAccessNotifPtr();
            }
            /* clear ECC status (EER bit) (w1c) */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_BIT_SET32(FLASH_MCR_ADDR32,FLASH_MCR_EER_W1C );
    }
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */
    /* Read flash location */
    if ((Fls_DataBytesType)FLS_SIZE_1BYTE == (Fls_DataBytesType)u8DataLength)
    {
        Fls_Flash_u8ReadAddress8 = *Fls_Flash_pReadAddressPtr;
    }
    else if (FLS_SIZE_4BYTE == u8DataLength)
    {
        /* @violates @ref Fls_Flash_c_REF_8 A cast shall not be performed between a pointer to object type and a pointer to a different object type */
        Fls_Flash_u32ReadAddress32 = *(volatile uint32 *)Fls_Flash_pReadAddressPtr;
    }
    else
    {
        /* Errors because to configuration*/
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_FAILED;
    }
#if( FLS_ECC_CHECK == STD_ON )
#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
    if(0U != Mcal_Trusted_Call_Return(Fls_Flash_GetPflashDataErrorSuppressionStatus))
#else
    if(0U != Fls_Flash_GetPflashDataErrorSuppressionStatus())
#endif
    {
        /* Store the ECC status (EER bit) */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32,FLASH_MCR_EER_W1C))
        {
                bWasEccEvent = Fls_Flash_ECCTest();
        }
        else
        {
            bWasEccEvent = (boolean)FALSE;
        }

        /* end flash access section: implementation depends on integrator */
        if( NULL_PTR != Fls_pConfigPtr->finishedFlashAccessNotifPtr )
        {
            /* Call Fls_FinishedFlashAccessNotif function if configured */
            Fls_pConfigPtr->finishedFlashAccessNotifPtr();
        }

        if ( (((boolean)FALSE) == (uint32)(*((*(Fls_pConfigPtr->pSectorList))[Fls_u32JobSectorIt])).bEccTriggersExc) && \
             (((boolean)TRUE) == bWasEccEvent) \
           )
        {
            if(FLS_JOB_READ == Fls_eJob)
            {
                Fls_Flash_eReadStatus = FLASH_E_FAILED;
            }
            else
            {
                Fls_Flash_eCompareStatus = FLASH_E_FAILED;
            }
        }
    }
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

    return eRetVal;
}

FUNC( void, FLS_CODE ) Fls_Flash_MainFunctionErase( void )
{
    /* FLASH_JOB_ERASE */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_DONE_U32))
    {
        /* erase/program high voltage sequence already finished */

        /* verify that erase operation was successful */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PEG_U32 ))
        {
                /* disable high voltage */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_EHV_U32 );
                /* terminate erase operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_ERS_U32 );
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
            /* schedule erase blank check of flash sector */
            Fls_eLLDJob = FLASH_JOB_ERASE_BLANK_CHECK;
#else
            /* erase operation succeed */
            Fls_u32JobSectorIt++;   /* The sector was successfully erased, increment the sector iterator.*/

            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_OK;
#endif /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
        }
        else
        {
                /* disable high voltage */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_EHV_U32 );
                /* terminate erase operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_ERS_U32 );
            /* erase operation failed */
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        }
    }
    else
    {
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
        #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
        /*
        * Gets the number of ticks between the current tick value and a previously read tick value.
        * And It shall also return  the  current  tick  value  of  the counter in the <Value> parameter
        */
        (void)GetElapsedValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue, &Fls_u32ElapsedTime);
        if(Fls_u32LLDTimeout_Counter > Fls_u32ElapsedTime)
        {
            Fls_u32LLDTimeout_Counter -= Fls_u32ElapsedTime;
        }
        else
        {
            Fls_u32LLDTimeout_Counter = 0U;
        }
        #else
        /* Operation in progress, handle possible timeout */
        Fls_u32LLDTimeout_Counter--;
        #endif /*#if (STD_OFF == FLS_TIMEOUT_AS_LOOP)*/
        if( 0U == Fls_u32LLDTimeout_Counter )
        {
                /* Abort the HV operation */
                (void) Fls_Flash_FinishHVOperation();
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_ERS_U32 );
            /* clear block select registers */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_WRITE32(FLASH_SEL0_ADDR32,0U);
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_WRITE32(FLASH_SEL1_ADDR32,0U);
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_WRITE32(FLASH_SEL2_ADDR32,0U);
            /* erase operation failed */
            (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_TIMEOUT);
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        }
#else
        /* erase/program high voltage sequence didn't finished yet */
        /* wait for another call of Fls_Flash_MainFunction, do nothing */
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */
    }
    /* errors of transient fault will be reported */
    if (MEMIF_JOB_FAILED == Fls_eLLDJobResult)
    {
        (void)Det_ReportTransientFault((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_ERASE_FAILED);
    }
}

FUNC( void, FLS_CODE ) Fls_Flash_MainFunctionWrite( void )
{
    /* FLASH_JOB_WRITE */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_DONE_U32))
    {
        /* erase/program high voltage sequence already finished */
        /* verify that program operation was successful */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PEG_U32 ))
        {
            /* program operation was successful */

                /* disable high voltage */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_EHV_U32 );
            #if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
            if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                /* Compiler_Warning: see fls_c_REF_CW_01 */
                                /*
                                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                */
                                ( (uint32)((uint32)Fls_Flash_pTargetAddressPtr - Fls_u32LLDNumberOfStepBack), \
                                  Fls_Flash_pSourceAddressPtr - (Fls_u32LLDNumberOfStepBack/4U), \
                                  Fls_u32LLDNumberOfStepBack \
                                )
              )
            {
                    /* terminate program operation */
                    /*
                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                    */
                    MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32 );
                Fls_eLLDJob = FLASH_JOB_NONE;
                Fls_eLLDJobResult = MEMIF_JOB_FAILED;
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_WRITE_FAILED);
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return;
            }
            #endif    /* FLS_WRITE_VERIFICATION_ENABLED == STD_ON */

            /* more double word program operation to be performed? */
            if(Fls_Flash_u32ProgramCycle<Fls_Flash_u32DoubleWordToCopy)
            {
                /* continue with next double word program operation */

                /* if not page aligned execute dw programming */
                /* Compiler_Warning: see fls_c_REF_CW_01 */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
                * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
                */
                if( (0U !=((uint32)Fls_Flash_pTargetAddressPtr % (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] ))|| \
                    (Fls_u32LLDRemainingDataToWrite < (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] ) \
                  /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
                  )
                {
                    #if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
                    if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                        /* Compiler_Warning: see fls_c_REF_CW_01 */
                                        /*
                                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                        */
                                        ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                           NULL_PTR, \
                                          (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt] \
                                        )
                      )
                    {
                        /* terminate program operation */
                        /*
                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                        */
                        MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32 );
                        Fls_eLLDJob = FLASH_JOB_NONE;
                        Fls_eLLDJobResult = MEMIF_JOB_FAILED;
                        (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                        return;
                    }
                    #endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
                    /*It is time to do word or double word programming */
                    Fls_Flash_PageWrite((*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt]);
                    Fls_Flash_u32ProgramCycle++;
                    /*
                    * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
                    * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
                    */
                    Fls_u32LLDRemainingDataToWrite -= (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
                    #if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
                    /* target and source address has been incresed by Fls_Flash_PageWrite,
                       so we need a number of step back for both pointer to perform a write
                       verify check*/
                    Fls_u32LLDNumberOfStepBack = (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
                    #endif
                }
                else
                {
                    #if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
                    if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                        /* Compiler_Warning: see fls_c_REF_CW_01 */
                                        /*
                                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                        */
                                        ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                          NULL_PTR, \
                                          (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] \
                                        )
                      )
                    {
                        /* terminate program operation */
                        /*
                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                        */
                        MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32 );
                        Fls_eLLDJob = FLASH_JOB_NONE;
                        Fls_eLLDJobResult = MEMIF_JOB_FAILED;
                        (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                        return;
                    }
                    #endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
                    /* it is time to do page programming */
                    Fls_Flash_PageWrite((*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt]);
                    Fls_Flash_u32ProgramCycle+=Fls_Flash_u32DoubleWordCounter;
                    /*
                    * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
                    * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
                    */
                    Fls_u32LLDRemainingDataToWrite -= (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
                    #if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
                    /* target and source address has been increased by Fls_Flash_PageWrite,
                       so we need a number of step back for both pointer to perform a write
                       verify check*/
                    Fls_u32LLDNumberOfStepBack = (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
                    #endif
                }

                        /* start internal erase/program sequence */
                        /*
                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                        */
                        MCR_BIT_SET32(FLASH_MCR_EHV_U32 );
                        #if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
                            #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
                                /* Return  the  current  tick value of the counter via <Value> */
                                (void)GetCounterValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue);
                            #endif /*#if (STD_OFF == FLS_TIMEOUT_AS_LOOP)*/
                                /* Initialize timeout counter */
                                Fls_u32LLDTimeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_ASYNC_WRITE_TIMEOUT_VALUE);
                        #endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */
                Fls_eLLDJob = FLASH_JOB_WRITE;
                Fls_eLLDJobResult = MEMIF_JOB_PENDING;
            }
            else
            {
                    /* all double word program operations succeed */
                    /* terminate program operation */
                    /*
                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                    */
                    MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32 );
                /* For a Write Job in ASYNC mode check if Fls_u32JobSectorIt should be increased */
                if( (Fls_u32JobAddrIt > ((*(Fls_pConfigPtr->paSectorEndAddr))[Fls_u32JobSectorIt]) ))
                {
                    /* Move on to the next sector */
                    Fls_u32JobSectorIt++;
                }

                /* program operation succeed */
                Fls_eLLDJob = FLASH_JOB_NONE;
                Fls_eLLDJobResult = MEMIF_JOB_OK;
            }
        }
        else
        {
            /* program operation was not successful */

                /* disable high voltage */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_EHV_U32 );
                /* terminate program operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32 );
            /* program operation failed */
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        }
    }
    else
    {
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
        #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
        /*
        * Gets the number of ticks between the current tick value and a previously read tick value.
        * And It shall also return  the  current  tick  value  of  the counter in the <Value> parameter
        */
        (void)GetElapsedValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue, &Fls_u32ElapsedTime);
        if(Fls_u32LLDTimeout_Counter > Fls_u32ElapsedTime)
        {
            Fls_u32LLDTimeout_Counter -= Fls_u32ElapsedTime;
        }
        else
        {
            Fls_u32LLDTimeout_Counter = 0U;
        }
        #else
        /* Operation in progress, handle possible timeout */
        Fls_u32LLDTimeout_Counter--;
        #endif /*#if (STD_OFF == FLS_TIMEOUT_AS_LOOP)*/
        if( 0U == Fls_u32LLDTimeout_Counter )
        {
                /* Abort the HV operation */
                (void) Fls_Flash_FinishHVOperation();
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_PGM_U32);
            /* write operation failed */
            (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_TIMEOUT);
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        }
#else
        /* erase/program high voltage sequence didn't finished yet */
        /* wait for another call of Fls_Flash_MainFunction, do nothing */
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */
    }
    if(MEMIF_JOB_FAILED == Fls_eLLDJobResult)
    {
        (void)Det_ReportTransientFault((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_WRITE_FAILED);
    }
}

#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
FUNC( void, FLS_CODE ) Fls_Flash_MainFunctionEraseBlankCheck( void )
{
    /* FLASH_JOB_ERASE_BLANK_CHECK */
    /* Compiler_Warning: see fls_c_REF_CW_01 */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    while ((uint32)Fls_Flash_pTargetAddressPtr < (uint32)Fls_Flash_pEndAddressPtr)
    {
        /* Compiler_Warning: see fls_c_REF_CW_01 */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if (((uint32)Fls_Flash_pEndAddressPtr - (uint32)Fls_Flash_pTargetAddressPtr) >=
              FLS_MAX_ERASE_BLANK_CHECK
           )
        {
            /* at least one erase blank check with FLS_MAX_ERASE_BLANK_CHECK size */
            if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea\
                                /* Compiler_Warning: see fls_c_REF_CW_01 */
                                /*
                                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                */
                                ( (uint32)Fls_Flash_pTargetAddressPtr,
                                  NULL_PTR, \
                                  FLS_MAX_ERASE_BLANK_CHECK
                                )
              )
            {
                Fls_eLLDJob = FLASH_JOB_NONE;
                Fls_eLLDJobResult = MEMIF_JOB_FAILED;
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return;
            }
            /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
            Fls_Flash_pTargetAddressPtr += FLS_MAX_ERASE_BLANK_CHECK/(Fls_Flash_DataBusWidthType)4;
            /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
            return;
        }
        else
        {
            /* at least one erase blank check with 4 bytes size */
            if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                /* Compiler_Warning: see fls_c_REF_CW_01 */
                                /*
                                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                */
                                ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                  NULL_PTR, \
                                  (Fls_LengthType)((uint32)Fls_Flash_pEndAddressPtr - (uint32)Fls_Flash_pTargetAddressPtr) \
                                )
              )
            {
                Fls_eLLDJob = FLASH_JOB_NONE;
                Fls_eLLDJobResult = MEMIF_JOB_FAILED;
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return;
            }
            /* Compiler_Warning: see fls_c_REF_CW_01 */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            * @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type
            */
            Fls_Flash_pTargetAddressPtr += ((uint32)Fls_Flash_pEndAddressPtr - (uint32)Fls_Flash_pTargetAddressPtr)/4U;
            /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
            return;
        }
    }
    /* erase blank check succeeded */
    Fls_u32JobSectorIt++;   /* The sector was successfully erased, increment the sector iterator.*/

    Fls_eLLDJob = FLASH_JOB_NONE;
    Fls_eLLDJobResult = MEMIF_JOB_OK;
}
#endif

#if (FLS_CANCEL_API == STD_ON )
/**
* @brief          Cancel ongoing erase or write hardware job.
* @details        In case Async Operation is ongoing this function will abort the following jobs:
*                 - Erase
*                 - Erase on Interleaved sectors
*                 - Write
*                 .
*/
FUNC( void, FLS_CODE ) Fls_Flash_Cancel( void )
{
         /* abort erase/program operation */
        if( (boolean)TRUE == Fls_Flash_FinishHVOperation() )
        {
            if (FLASH_JOB_ERASE == Fls_eLLDJob )
            {
                /* FLASH_JOB_ERASE */
                
                /* terminate erase operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32(FLASH_MCR_ERS_U32);
                
                /* clear block select registers */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                REG_WRITE32(FLASH_SEL0_ADDR32,0U);
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                REG_WRITE32(FLASH_SEL1_ADDR32,0U);
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                REG_WRITE32(FLASH_SEL2_ADDR32,0U);
            }
            else
            {
                /* FLASH_JOB_WRITE */
                /* terminate program operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
            }
            /* erase operation canceled */
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_CANCELED;
        }
}
#endif /* FLS_CANCEL_API == STD_ON */

/**
* @brief          Erase one complete flash sector.
*
* @param[in]      1           ePhySector Physical sector ID
* @param[in]      2           bAsynch Set to TRUE for asynchronous and FALSE for synchronous
*                             function operation
*
* @return         Fls_LLDReturnType
* @retval         FLASH_E_OK Operation succeeded
* @retval         FLASH_E_FAILED Operation failed due to hardware error
* @retval         FLASH_E_PENDING The operation has not yet been finished
*                 (only for asynchronous operation )
*
* @pre            ePhySector must be in range
* @pre            The module must be initialized
*
* @implements     Fls_Flash_SectorErase_Activity
*
* @note           Dem_ReportErrorStatus(Fls_pConfigPtr->Fls_E_EraseFailedCfg.id, DEM_EVENT_STATUS_FAILED)
*                 when erase operation failed due to hardware error
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_SectorErase
(
    CONST( Fls_PhysicalSectorType, AUTOMATIC) ePhySector,
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
    CONST(Fls_LengthType, AUTOMATIC) u32PhysicalSectorSize,
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
    CONST( boolean, AUTOMATIC) bAsynch
)
{
    VAR(uint32, AUTOMATIC) u32BloSelRegAddr = (uint32)(*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).u32SectorBloSelRegAddr;
    VAR(uint32, AUTOMATIC) u32BloSelValue = (uint32)(*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).u32AddrSpaceBloSelValue;
    VAR(uint32, AUTOMATIC) u32BloLockRegAddr = (uint32)(*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).u32AddrSpaceBloLockRegAddr;
    VAR(uint32, AUTOMATIC) u32BloLockValue = (uint32)(*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).u32AddrSpaceBloLockValue;

    Fls_Flash_pTargetAddressPtr = (*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).pSectorStartAddressPtr;

#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
    /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
    Fls_Flash_pEndAddressPtr = ((*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).pSectorStartAddressPtr + (u32PhysicalSectorSize/(Fls_Flash_DataBusWidthType)4));
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */

    /* verify that EHV may be set */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    if((0UL != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_ERS_U32|FLASH_MCR_PGM_U32|FLASH_MCR_ESUS_U32)) || \
        (0UL != REG_BIT_GET32(FLASH_UT0_ADDR32, FLASH_UT0_AIE_U32))
      /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
      )
    {
        /*  EHV may not be set: modify operation already in progress */
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_FAILED;
    }
    /* verify that sector is not protected against erase/program operations */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    * @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects
    */
    if(( 0U != (REG_READ32(u32BloLockRegAddr) & u32BloLockValue )))
    {
        /* Sector protected: program operation failed */
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_FAILED;
    }
    if ((boolean)FALSE == bAsynch)
    {
        /* setup erase operation */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        MCR_BIT_SET32( FLASH_MCR_ERS_U32);
        /* load adequate block select register */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        REG_WRITE32(u32BloSelRegAddr, u32BloSelValue );
        /* make an erase interlock write, dummy data word write */
        *Fls_Flash_pTargetAddressPtr = FLASH_DATA_VALUE_U32;

#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
        /* Initialize timeout counters */
        Fls_u32LLDTimeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_SYNC_ERASE_TIMEOUT_VALUE);
        Fls_Flash_u32Abort_Timeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_ABT_TIMEOUT_VALUE);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

        /* start flash access section: implementation depends on integrator */
        if( NULL_PTR != Fls_pConfigPtr->startFlashAccessNotifPtr )
        {
            /* Call FlsStartFlashAccessNotif function if configured */
            Fls_pConfigPtr->startFlashAccessNotifPtr();
        }

        MCAL_FAULT_INJECTION_POINT(FLS_FIP_11_FLS_FLASH_SECTOR_ERASE);

        /* call flash access code routine */
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
        /*
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        * @violates @ref Fls_Flash_c_REF_9 A Conversions shall not be performed between a pointer to a function and any other type
        * @violates @ref Fls_Flash_c_REF_10 The value of a composite expression shall not be cast to a different essential
        * type category or a wider essential type
        */
        FLASH_AC_CALL(Fls_pConfigPtr->acErasePtr, Fls_AcErasePtrType)(FLASH_BASEADDR, Fls_pConfigPtr->acCallBackPtr, &Fls_u32LLDTimeout_Counter, &Fls_Flash_u32Abort_Timeout_Counter);
#else
        /*
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        * @violates @ref Fls_Flash_c_REF_9 A Conversions shall not be performed between a pointer to a function and any other type
        * @violates @ref Fls_Flash_c_REF_10 The value of a composite expression shall not be cast to a different essential
        * type category or a wider essential type
        */
        FLASH_AC_CALL(Fls_pConfigPtr->acErasePtr, Fls_AcErasePtrType)(FLASH_BASEADDR, Fls_pConfigPtr->acCallBackPtr);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

        MCAL_FAULT_INJECTION_POINT(FLS_FIP_12_FLS_FLASH_SECTOR_ERASE);

        /* end flash access section: implementation depends on integrator */
        if( NULL_PTR != Fls_pConfigPtr->finishedFlashAccessNotifPtr )
        {
            /* Call Fls_FinishedFlashAccessNotif function if configured */
            Fls_pConfigPtr->finishedFlashAccessNotifPtr();
        }

        /* verify that erase operation was successful */
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
        /*  PEG is valid only after DONE transition to 1 which might not be the case if the timeout event occured */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if((0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PEG_U32)) && (0U != Fls_u32LLDTimeout_Counter) && (0U != Fls_Flash_u32Abort_Timeout_Counter))
#else
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PEG_U32))
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */
        {
                /* terminate erase operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32( FLASH_MCR_ERS_U32);
            /* clear adequate block select register */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_WRITE32(u32BloSelRegAddr, 0U);
        }
        else
        {
            #if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
            if ((0U == Fls_u32LLDTimeout_Counter) || (0U == Fls_Flash_u32Abort_Timeout_Counter)) 
            {                
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_TIMEOUT);
            }
            #endif /*#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)*/
                /* terminate erase operation */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_CLEAR32( FLASH_MCR_ERS_U32);
            /* clear adequate block select register */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            REG_WRITE32(u32BloSelRegAddr, 0U);
            /* erase operation failed */
            /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
            return FLASH_E_FAILED;
        }

#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
        /* Compiler_Warning: see fls_c_REF_CW_01 */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea((uint32)Fls_Flash_pTargetAddressPtr, NULL_PTR, u32PhysicalSectorSize) )
        {
            (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
            /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
            return FLASH_E_FAILED;
        }
#endif   /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
        /* erase operation succeed */
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_OK;
    }
    else /* bAsynch == TRUE */
    {
        /* setup erase operation */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        MCR_BIT_SET32( FLASH_MCR_ERS_U32);
        /* load adequate block select register */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        REG_WRITE32(u32BloSelRegAddr, u32BloSelValue );
        /* make an erase interlock write, dummy data word write */
        *Fls_Flash_pTargetAddressPtr = FLASH_DATA_VALUE_U32;

                /* start internal erase/program sequence */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_SET32( FLASH_MCR_EHV_U32);

#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
        #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
                /* Return  the  current  tick value of the counter via <Value> */
                (void)GetCounterValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue);
        #endif /*#if (STD_OFF == FLS_TIMEOUT_AS_LOOP)*/
                /* Initialize timeout counter */
                Fls_u32LLDTimeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_ASYNC_ERASE_TIMEOUT_VALUE);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

        Fls_eLLDJob = FLASH_JOB_ERASE;
        Fls_eLLDJobResult = MEMIF_JOB_PENDING;

        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_PENDING;
    }
}

/**
* @brief          Write one or more complete flash pages into given flash sector.
*
* @param[in]      ePhySector Physical sector ID
* @param[in]      u32SectorOffset sector offset in bytes
* @param[in]      u32DataLength data length in bytes
* @param[in]      pDataPtr data to be written
* @param[in]      bAsynch set to TRUE for asynchronous and FALSE for synchronous function operation
*
* @return         Fls_LLDReturnType
* @retval         FLASH_E_OK Operation succeeded
* @retval         FLASH_E_FAILED Operation failed due to hardware error
* @retval         FLASH_E_PENDING The operation has not yet been finished
*                 (only for asynchronous operation )
*
* @pre            u32SectorOffset must be double word aligned
* @pre            u32DataLength must be multiple double word length
* @pre            ePhySector must be in range
* @pre            The module must be initialized
*
* @implements     Fls_Flash_SectorWrite_Activity
*
* @note           Dem_ReportErrorStatus(Fls_pConfigPtr->Fls_E_WriteFailedCfg.id, DEM_EVENT_STATUS_FAILED)
*                 when write operation failed due to hardware error
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_SectorWrite
(
    CONST( Fls_PhysicalSectorType, AUTOMATIC) ePhySector,
    CONST(Fls_AddressType, AUTOMATIC) u32SectorOffset,
    CONST(Fls_LengthType, AUTOMATIC) u32DataLength,
    CONSTP2CONST(uint8, AUTOMATIC, FLS_APPL_CONST) pDataPtr,
    CONST( boolean, AUTOMATIC) bAsynch
)
{
    VAR(uint32, AUTOMATIC) u32BloLockRegAddr = (uint32)(*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).u32AddrSpaceBloLockRegAddr;
    VAR(uint32, AUTOMATIC) u32BloLockValue = (uint32)(*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).u32AddrSpaceBloLockValue;
    VAR(Fls_LengthType, AUTOMATIC) u32TempSectorProgSize;

    /* @violates @ref Fls_Flash_c_REF_8 A cast shall not be performed between a pointer to object type and a pointer to a different object type */
    Fls_Flash_pSourceAddressPtr = (const uint32*)(pDataPtr);
    /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
    Fls_Flash_pTargetAddressPtr = (*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).pSectorStartAddressPtr + \
                               (u32SectorOffset/4U);

    Fls_u32LLDRemainingDataToWrite = u32DataLength;

    /* verify that EHV may be set */
   /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    if((0UL != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_ERS_U32|FLASH_MCR_PGM_U32|FLASH_MCR_ESUS_U32)) || \
        (0UL != REG_BIT_GET32(FLASH_UT0_ADDR32, FLASH_UT0_AIE_U32))
      /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
      )
    {
        /*  EHV may not be set: modify operation already in progress */
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_FAILED;
    }
    /* Verify that sector is not protected against erase/program operations and Program Hardware Lock */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    * @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects
    */
    if (( 0U != (REG_READ32(u32BloLockRegAddr) & u32BloLockValue )))
    {
        /* Sector protected: program operation failed */
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_FAILED;
    }
    /* Number of word (i.e.32bits=4bytes) double word (i.e.64bits=8bytes) to be copied  */
    Fls_Flash_u32DoubleWordToCopy = u32DataLength/(*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
    /* Number of word or dw to be copied in one program operation */
    u32TempSectorProgSize = (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
    Fls_Flash_u32DoubleWordCounter = u32TempSectorProgSize / (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
    Fls_Flash_u32ProgramCycle = 0U;

    /* before going into programming loop (and potential performing Verify Erase operation) and setting MCR[PGM],
       invalidate the flash prefetch buffer by performing a bogus interlock write while MCR[PGM,ERS] == 0 */
    *Fls_Flash_pTargetAddressPtr = 0x0UL;

    if ((boolean)FALSE == bAsynch)
    {
            /* setup program operation */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            MCR_BIT_SET32( FLASH_MCR_PGM_U32);

        /* process all double word program operations */
        /*for( Fls_Flash_u32ProgramCycle=0U; Fls_Flash_u32ProgramCycle < Fls_Flash_u32DoubleWordToCopy; \
             Fls_Flash_u32ProgramCycle++ )*/
        while (Fls_Flash_u32ProgramCycle < Fls_Flash_u32DoubleWordToCopy)
        {

            /* if not page aligned execute dw programming */
            /* Compiler_Warning: see fls_c_REF_CW_01 */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
            * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
            */
            if( (0U != ((uint32)Fls_Flash_pTargetAddressPtr % (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] )) || \
                (Fls_u32LLDRemainingDataToWrite < (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] ) \
              /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
              )
            {
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
                if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                    /* Compiler_Warning: see fls_c_REF_CW_01 */
                                    /*
                                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                    */
                                    ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                       NULL_PTR, \
                                      (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt] \
                                    )
                  )
                {
                        /* terminate program operation */
                        /*
                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                        */
                        MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
                    (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                    /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                    return FLASH_E_FAILED;
                }
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
                /*It is time to do word or double word programming */
                Fls_Flash_PageWrite((*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt]);
                Fls_Flash_u32ProgramCycle++;
                /*
                * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
                * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
                */
                Fls_u32LLDRemainingDataToWrite -= (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
#if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
                /* target and source address has been incresed by Fls_Flash_PageWrite,
                   so we need a number of step back for both pointer to perform a write
                   verify check*/
                Fls_u32LLDNumberOfStepBack = (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
#endif
            }
            else
            {
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
                if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                    /* Compiler_Warning: see fls_c_REF_CW_01 */
                                    /*
                                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                    */
                                    ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                       NULL_PTR, \
                                      (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] \
                                    )
                  )
                {
                        /* terminate program operation */
                        /*
                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                        */
                        MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
                    (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                    /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                    return FLASH_E_FAILED;
                }
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
                /* it is time to do page programming */
                Fls_Flash_PageWrite((*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt]);
                Fls_Flash_u32ProgramCycle+=Fls_Flash_u32DoubleWordCounter;
                /*
                * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
                * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
                */
                Fls_u32LLDRemainingDataToWrite -= (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
#if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
                /* target and source address has been increased by Fls_Flash_PageWrite,
                   so we need a number of step back for both pointer to perform a write
                   verify check*/
                Fls_u32LLDNumberOfStepBack = (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
#endif
            }

#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
            /* Initialize timeout counters */
            Fls_u32LLDTimeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_SYNC_WRITE_TIMEOUT_VALUE);
            Fls_Flash_u32Abort_Timeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_ABT_TIMEOUT_VALUE);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

            /* start flash access section: implementation depends on integrator */
            if( NULL_PTR != Fls_pConfigPtr->startFlashAccessNotifPtr )
            {
                /* Call FlsStartFlashAccessNotif function if configured */
                Fls_pConfigPtr->startFlashAccessNotifPtr();
            }

            MCAL_FAULT_INJECTION_POINT(FLS_FIP_13_FLS_FLASH_SECTOR_WRITE);

            /* call flash access code routine */
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
            /*
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            * @violates @ref Fls_Flash_c_REF_9 A Conversions shall not be performed between a pointer to a function and any other type
            * @violates @ref Fls_Flash_c_REF_10 The value of a composite expression shall not be cast to a different essential
            * type category or a wider essential type
            */
            FLASH_AC_CALL(Fls_pConfigPtr->acWritePtr, Fls_AcWritePtrType)(FLASH_BASEADDR, Fls_pConfigPtr->acCallBackPtr, &Fls_u32LLDTimeout_Counter, &Fls_Flash_u32Abort_Timeout_Counter);
#else
            /*
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            * @violates @ref Fls_Flash_c_REF_9 A Conversions shall not be performed between a pointer to a function and any other type
            * @violates @ref Fls_Flash_c_REF_10 The value of a composite expression shall not be cast to a different essential
            * type category or a wider essential type
            */
            FLASH_AC_CALL(Fls_pConfigPtr->acWritePtr, Fls_AcWritePtrType)(FLASH_BASEADDR, Fls_pConfigPtr->acCallBackPtr);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */

            MCAL_FAULT_INJECTION_POINT(FLS_FIP_14_FLS_FLASH_SECTOR_ERASE);

            /* end flash access section: implementation depends on integrator */
            if( NULL_PTR != Fls_pConfigPtr->finishedFlashAccessNotifPtr )
            {
                /* Call Fls_FinishedFlashAccessNotif function if configured */
                Fls_pConfigPtr->finishedFlashAccessNotifPtr();
            }

            /* verify that program operation was successful */
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
            /*  PEG is valid only after DONE transition to 1 which might not be the case if the timeout event occured */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            if((0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PEG_U32)) && (0U != Fls_u32LLDTimeout_Counter) && (0U != Fls_Flash_u32Abort_Timeout_Counter))
#else
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            if(0U != REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PEG_U32))
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */
            {
#if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
                if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea
                                     (
                                        /* Compiler_Warning: see fls_c_REF_CW_01 */
                                        /*
                                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                        */
                                        (uint32)((uint32)Fls_Flash_pTargetAddressPtr - Fls_u32LLDNumberOfStepBack),
                                        Fls_Flash_pSourceAddressPtr - (Fls_u32LLDNumberOfStepBack/4U),
                                        Fls_u32LLDNumberOfStepBack
                                     )
                  )
                {
                        /* terminate program operation */
                        /*
                        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                        */
                        MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
                    (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_WRITE_FAILED);
                    /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                    return FLASH_E_FAILED;
                }
#endif    /* FLS_WRITE_VERIFICATION_ENABLED == STD_ON */

                /* program operation succeed */
                /* continue with next double word program operation */
            }
            else
            {
                    /* terminate program operation */
                    /*
                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                    */
                    MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
                /* program operation failed */
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return FLASH_E_FAILED;
            }
        }

        /* all double word program operations succeed */
            /* terminate program operation */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
        /* program operation succeed */
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_OK;
    }
    else /* bAsynch == TRUE */
    {
            /* setup program operation */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            MCR_BIT_SET32( FLASH_MCR_PGM_U32);
        /* first double word program operation */
        Fls_Flash_u32ProgramCycle=0U;
#if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
        Fls_u32LLDNumberOfStepBack = 0U;
#endif
        /* if not page aligned execute dw programming */
        /* Compiler_Warning: see fls_c_REF_CW_01 */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
        * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
        */
        if( (0U != ((uint32)Fls_Flash_pTargetAddressPtr % (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] )) || \
                    (Fls_u32LLDRemainingDataToWrite < (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] ) \
          /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
          )
        {
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
            if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                /* Compiler_Warning: see fls_c_REF_CW_01 */
                                /*
                                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                */
                               ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                  NULL_PTR, \
                                 (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt] \
                               )
              )
            {
                    /* terminate program operation */
                    /*
                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                    */
                    MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return FLASH_E_FAILED;
            }
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
            /*It is time to do word or double word programming */
            Fls_Flash_PageWrite((*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt]);
            Fls_Flash_u32ProgramCycle++;
            /*
            * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
            * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
            */
            Fls_u32LLDRemainingDataToWrite -= (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
#if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
            /* target and source address has been incresed by Fls_Flash_PageWrite,
               so we need a number of step back for both pointer to perform a write
               verify check*/
            Fls_u32LLDNumberOfStepBack = (*(Fls_pConfigPtr->paSectorPageSize))[Fls_u32JobSectorIt];
#endif
        }
        else
        {
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
            if( FLASH_E_OK != Fls_Flash_VerifyMemoryArea \
                                /* Compiler_Warning: see fls_c_REF_CW_01 */
                                /*
                                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                                */
                                ( (uint32)Fls_Flash_pTargetAddressPtr, \
                                  NULL_PTR, \
                                  (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt] \
                                )
              )
            {
                    /* terminate program operation */
                    /*
                    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                    */
                    MCR_BIT_CLEAR32( FLASH_MCR_PGM_U32);
                (void)Det_ReportRuntimeError((uint16)FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_MAINFUNCTION_ID, FLS_E_VERIFY_ERASE_FAILED);
                /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
                return FLASH_E_FAILED;
            }
#endif    /* FLS_ERASE_VERIFICATION_ENABLED == STD_ON */
            /* it is time to do page programming */
            Fls_Flash_PageWrite((*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt]);
            Fls_Flash_u32ProgramCycle+=Fls_Flash_u32DoubleWordCounter;
            /*
            * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
            * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
            */
            Fls_u32LLDRemainingDataToWrite -= (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
#if( FLS_WRITE_VERIFICATION_ENABLED == STD_ON )
            /* target and source address has been incresed by Fls_Flash_PageWrite,
               so we need a number of step back for both pointer to perform a write
               verify check*/
            Fls_u32LLDNumberOfStepBack = (*(Fls_pConfigPtr->paSectorProgSize))[Fls_u32JobSectorIt];
#endif
        }
                /* start internal erase/program sequence */
                /*
                * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
                * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
                */
                MCR_BIT_SET32( FLASH_MCR_EHV_U32);
#if (FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON)
            #if (STD_OFF == FLS_TIMEOUT_AS_LOOP)
                /* Return  the  current  tick value of the counter via <Value> */
                (void)GetCounterValue((CounterType)FLS_TIMEOUT_COUNTER_NAME, &Fls_u32CurrentValue);
            #endif /*#if (STD_OFF == FLS_TIMEOUT_AS_LOOP)*/
                /* Initialize timeout counter */
                Fls_u32LLDTimeout_Counter = (uint32)Fls_UpdateTimeoutLoopOrOs((uint32)FLS_ASYNC_WRITE_TIMEOUT_VALUE);
#endif /* FLS_TIMEOUT_SUPERVISION_ENABLED == STD_ON */
        Fls_eLLDJob = FLASH_JOB_WRITE;
        Fls_eLLDJobResult = MEMIF_JOB_PENDING;
        /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
        return FLASH_E_PENDING;
    }
}

/**
* @brief          Execute an interlock write and next program.
*
* @param[in]      1           u32TotalBytes Total number of bytes to program
*
*/
static FUNC( void, FLS_CODE ) Fls_Flash_PageWrite
( CONST(uint32, AUTOMATIC) u32TotalBytes )
{
    VAR(uint32, AUTOMATIC) u32Counter;

    for (u32Counter=0UL; u32Counter < (u32TotalBytes/4U); u32Counter++)
    {
        /* make a program data interlock write, first word data write */
        *Fls_Flash_pTargetAddressPtr = *Fls_Flash_pSourceAddressPtr;
        /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
        Fls_Flash_pTargetAddressPtr += 1;
        /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
        Fls_Flash_pSourceAddressPtr += 1;
    }
}

/**
* @brief          Read one or more bytes from given flash sector
*
* @param[in]      1           ePhySector Physical sector ID
* @param[in]      2           u32SectorOffset sector offset in bytes
* @param[in]      3           u32DataLength data length in bytes
* @param[out]     pDataPtr    where read data to be written
*
* @return Fls_LLDReturnType
* @retval FLASH_E_OK Operation succeeded
*
* @implements     Fls_Flash_SectorRead_Activity
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_SectorRead
(
    CONST( Fls_PhysicalSectorType, AUTOMATIC) ePhySector,
    CONST(Fls_AddressType, AUTOMATIC) u32SectorOffset,
    VAR(Fls_LengthType, AUTOMATIC) u32DataLength,
    P2VAR(uint8, AUTOMATIC, FLS_APPL_DATA) pDataPtr
)
{
    VAR(Fls_LLDReturnType, AUTOMATIC) eRetVal = FLASH_E_OK;
    VAR(Fls_DataBytesType, AUTOMATIC) u8DataLength = FLS_SIZE_1BYTE;
#if( FLS_ECC_CHECK == STD_ON )
    Fls_Flash_eReadStatus = FLASH_E_PENDING;
#endif  /* #if( FLS_ECC_CHECK == STD_ON ) */

    /* Physical flash address to read */
    /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
    Fls_Flash_pReadAddressPtr = (volatile uint8 *)((*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).pSectorStartAddressPtr) + \
                              u32SectorOffset;

#if( FLS_ECC_CHECK == STD_ON )
#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
    if(0U != Mcal_Trusted_Call_Return(Fls_Flash_GetPflashDataErrorSuppressionStatus))
#else
    if(0U != Fls_Flash_GetPflashDataErrorSuppressionStatus())
#endif
    {
        /* first invalidate the flash prefetch buffer by performing a bogus interlock write
           (avoid write if MCR[PGM|ERS] == 0)*/
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if(0UL == REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PGM_U32 | FLASH_MCR_ERS_U32))
        {
            *Fls_Flash_pReadAddressPtr = 0U;
        }
    }
#endif  /* #if( FLS_ECC_CHECK == STD_ON ) */

    do
    {
        /* Read flash location */
        /* Compiler_Warning: see fls_c_REF_CW_01 */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        * @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects.
        */
        if((0U == ( (uint32)pDataPtr % 4U )) && (0U == ( (uint32)Fls_Flash_pReadAddressPtr % 4U )) && (4U <= u32DataLength))
        {
            u8DataLength = FLS_SIZE_4BYTE;
        }
        else /* At least one of the buffers is unaligned or there are less than 4 bytes left. */
        {
            u8DataLength = FLS_SIZE_1BYTE;
        }

        if(FLASH_E_FAILED == Fls_Flash_ReadBytes(u8DataLength))
        {
            /* Errors occurred when verify the memory flash*/
            /* @violates @ref Fls_Flash_c_REF_4 A function should have a single point of exit at the end */
            return FLASH_E_FAILED;
        }

        if(FLS_SIZE_4BYTE == u8DataLength)
        {
            /* @violates @ref Fls_Flash_c_REF_8 A cast shall not be performed between a pointer to object type and a pointer to a different object type */
            *( uint32*)(pDataPtr) = Fls_Flash_u32ReadAddress32;
        }
        else
        {
            *pDataPtr = Fls_Flash_u8ReadAddress8;
        }
        /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type*/
        pDataPtr += (uint32)u8DataLength;
        /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type*/
        Fls_Flash_pReadAddressPtr += (uint32)u8DataLength;
        u32DataLength -= (uint32)u8DataLength;
#if( FLS_ECC_CHECK == STD_ON )
    /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
    }while((u32DataLength > 0U) && ( FLASH_E_PENDING == Fls_Flash_eReadStatus ));
#else   /* #if( FLS_ECC_CHECK == STD_ON ) */
    }while(u32DataLength > 0U);
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

#if( FLS_ECC_CHECK == STD_ON )
    if( FLASH_E_PENDING == Fls_Flash_eReadStatus )
    {
        Fls_Flash_eReadStatus = FLASH_E_OK;
    }

    eRetVal = Fls_Flash_eReadStatus;
#else /* #if( FLS_ECC_CHECK == STD_ON ) */
    eRetVal = FLASH_E_OK;
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

    return eRetVal;
}
#if(( FLS_COMPARE_API == STD_ON ) || ( FLS_BLANK_CHECK_API == STD_ON ))
/**
* @brief          Compare data buffer with content of given flash sector.
*
* @param[in]      1           ePhySector Physical sector ID
* @param[in]      2           u32SectorOffset sector offset in bytes
* @param[in]      3           u32DataLength data length in bytes
* @param[in]      4           pDataPtr data to be compared
*
* @return         Fls_LLDReturnType
* @retval         FLASH_E_OK Operation succeeded
* @retval         FLASH_E_BLOCK_INCONSISTENT Data buffer doesn't match with content of flash sector
*
* @implements     Fls_Flash_SectorCompare_Activity
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_Flash_SectorCompare
(
    CONST( Fls_PhysicalSectorType, AUTOMATIC) ePhySector,
    CONST(Fls_AddressType, AUTOMATIC) u32SectorOffset,
    VAR(Fls_LengthType, AUTOMATIC) u32DataLength,
    P2CONST(uint8, AUTOMATIC, FLS_APPL_CONST) pDataPtr
)
{
#if( FLS_ECC_CHECK == STD_ON )
    Fls_Flash_eCompareStatus = FLASH_E_PENDING;
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */

    /* Physical flash address to read */
    /* @violates @ref Fls_Flash_c_REF_7 The +,- += and -= operators should not be applied to an expression of pointer type */
    Fls_Flash_pReadAddressPtr = (volatile uint8 *)((*((*(Fls_pConfigPtr->pSectorList))[ePhySector])).pSectorStartAddressPtr) + \
                              u32SectorOffset;

#if( FLS_ECC_CHECK == STD_ON )
#if (STD_ON == FLS_ENABLE_USER_MODE_SUPPORT)
    if(0U != Mcal_Trusted_Call_Return(Fls_Flash_GetPflashDataErrorSuppressionStatus))
#else
    if(0U != Fls_Flash_GetPflashDataErrorSuppressionStatus())
#endif
    {
        /* first invalidate the flash prefetch buffer by performing a bogus interlock write
           (avoid write if MCR[PGM|ERS] == 0)*/
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        * @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects.
        */
        if(0UL == REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PGM_U32 | FLASH_MCR_ERS_U32))
        {
            *Fls_Flash_pReadAddressPtr = 0U;
        }
    }
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */
    /* Compiler_Warning: see fls_c_REF_CW_01 */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    * @violates @ref Fls_Flash_c_REF_8 A cast shall not be performed between a pointer to object type and a pointer to a different object type
    */
    return Fls_Flash_VerifyMemoryArea((uint32)Fls_Flash_pReadAddressPtr,(const uint32*)pDataPtr, u32DataLength);
}
#endif /* ( FLS_COMPARE_API == STD_ON ) || (FLS_BLANK_CHECK_API == STD_ON) */


#if( FLS_ECC_CHECK == STD_ON )
/**
* @brief          Low level data storage exception handler.
*
* @return         Exc_CompHandlerReturnType
* @retval         EXC_HANDLED_SKIP The data storage exception was
*                 caused by currently pending flash read or compare job
* @retval         EXC_UNHANDLED The data storage exception was
*                 NOT caused by currently pending flash read or compare job
*
*/
/*
* @violates @ref Fls_Flash_c_REF_12 Function and object should not be defined with external linkage
* if they are referenced in only one translation unit
*/
FUNC( Fls_CompHandlerReturnType, FLS_CODE ) Fls_DsiHandler
(
    P2CONST( Fls_ExceptionDetailsType, AUTOMATIC, FLS_APPL_CONST ) pExceptionDetailsPtr
)
{
    VAR( Fls_CompHandlerReturnType, AUTOMATIC ) u8RetVal = FLS_UNHANDLED;

    /* @errata ERR_IPV_FLASH_0005 */
    #ifdef ERR_IPV_FLASH_0005
      #if (ERR_IPV_FLASH_0005 == STD_ON)
        VAR(uint8, AUTOMATIC) u8DataPtr;

        u8DataPtr = *((volatile uint8 *)0x00C02000U);
     #endif
    #endif

    /*  Check whether there is
        [1] pending read, compare, erase or write job,
        [2] exception syndrome register indicates "DSI reason"(caused by driver load instruction) or
                "DSI cache reason"(caused by a cache fetch, triggered by the flash access), and
        [3] data_pt is in the same cache line as the address currently accessed by pending flash read or flash compare job*/
    if( (FLASH_E_PENDING == Fls_Flash_eReadStatus )
        &&
        ( ( FLASH_DSI_EXC_SYNDROME       == (pExceptionDetailsPtr->syndrome_u32 & FLASH_DSI_EXC_SYNDROME)     ) ||
          ( FLASH_DSI_EXC_SYNDROME_CACHE == (pExceptionDetailsPtr->syndrome_u32 & FLASH_DSI_EXC_SYNDROME_CACHE) )
        )
        &&
        /* The reported exception address is in the same 32 bytes cache line as the Fls_Flash_pReadAddressPtr */
        /* Compiler_Warning: see fls_c_REF_CW_01 */
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        ( ((uint32)pExceptionDetailsPtr->data_pt >> 5) == ((uint32)Fls_Flash_pReadAddressPtr >> 5) )
      /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
      )
    {
        Fls_Flash_eReadStatus = FLASH_E_FAILED;
        u8RetVal = FLS_HANDLED_SKIP;
    }
    else if( (FLASH_E_PENDING == Fls_Flash_eCompareStatus )
            &&
            ( ( FLASH_DSI_EXC_SYNDROME       == (pExceptionDetailsPtr->syndrome_u32 & FLASH_DSI_EXC_SYNDROME)     ) ||
              ( FLASH_DSI_EXC_SYNDROME_CACHE == (pExceptionDetailsPtr->syndrome_u32 & FLASH_DSI_EXC_SYNDROME_CACHE) )
            )
            &&
            /* The reported exception address is in the same 32 bytes cache line as the Fls_Flash_pReadAddressPtr */
            /* Compiler_Warning: see fls_c_REF_CW_01 */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            ( ( ((uint32)pExceptionDetailsPtr->data_pt >> 5) == ((uint32)Fls_Flash_pReadAddressPtr >> 5) ) ||
            /* Compiler_Warning: see fls_c_REF_CW_01 */
            /*
            * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
            * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
            */
            ( ((uint32)pExceptionDetailsPtr->data_pt >> 5) == ((uint32)Fls_Flash_pCompareAddressPtr >> 5) )
            /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
            )
           /* @violates @ref Fls_Flash_c_REF_6 The right hand operand of a logical && or || shall not contain persistent side effects. */
           )
    {
        Fls_Flash_eCompareStatus = FLASH_E_FAILED;
        u8RetVal = FLS_HANDLED_SKIP;
    }
    else
    {
        /* FLS_UNHANDLED */
    }

    return u8RetVal;
}

static FUNC( boolean, FLS_CODE ) Fls_Flash_ECCTest( void )
{
    VAR(boolean, AUTOMATIC) bWasECC = (boolean)FALSE;
    VAR(uint32, AUTOMATIC) Fls_Flash_u32ReadECC = 0U;
    P2VAR(volatile uint32, AUTOMATIC, FLS_APPL_DATA) Fls_Flash_pECCAddressPtr;

    /* Compiler_Warning: see fls_c_REF_CW_01 */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    * @violates @ref Fls_Flash_c_REF_8 A cast shall not be performed between a pointer to object type and a pointer to a different object type
    * @violates @ref Fls_Flash_c_REF_13 There shall be no occurrence of undefined or critical unspecified behaviour.
    * @violates @ref Fls_Flash_c_REF_14 The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders.
    */
    Fls_Flash_pECCAddressPtr = (volatile uint32 *)(Fls_Flash_pReadAddressPtr - ((uint32)Fls_Flash_pReadAddressPtr % 4U));

    Fls_Flash_u32ReadECC = *Fls_Flash_pECCAddressPtr;

    /* first invalidate the flash prefetch buffer by performing a bogus interlock write*/
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    if(0UL == REG_BIT_GET32(FLASH_MCR_ADDR32, FLASH_MCR_PGM_U32 | FLASH_MCR_ERS_U32))
    {
        *Fls_Flash_pECCAddressPtr = 0U;
    }
    /* clear ECC status (EER bit) (w1c) */
    /*
    * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
    * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
    */
    REG_BIT_SET32(FLASH_MCR_ADDR32,FLASH_MCR_EER_W1C );

    if(FLS_ECC_VALUE != Fls_Flash_u32ReadECC)
    {
        bWasECC = FALSE;
    }
    else
    {
        Fls_Flash_u32ReadECC = *Fls_Flash_pECCAddressPtr;
        /*
        * @violates @ref Fls_Flash_c_REF_2 A conversion should not be performed between a pointer to object and an integer type
        * @violates @ref Fls_Flash_c_REF_3 A cast shall not be performed between pointer to void and an arithmetic type
        */
        if((0U != REG_BIT_GET32(FLASH_MCR_ADDR32,FLASH_MCR_EER_W1C)) && (FLS_ECC_VALUE == Fls_Flash_u32ReadECC))
        {
            bWasECC = TRUE;
        }
        else
        {
            bWasECC = FALSE;
        }
    }

    return bWasECC;
}
#endif /* #if( FLS_ECC_CHECK == STD_ON ) */
#define FLS_STOP_SEC_CODE
/*
* @violates @ref Fls_Flash_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_Flash_c_REF_5 #Include directives should only be preceded by preprocessor directives or comments
*/
#include "Fls_MemMap.h"
#endif /*(STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)*/
#endif /*(STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)*/
#ifdef __cplusplus
}
#endif
