/**
*   @file    Mcem_IPW.c
*   @implements     Mcem_IPW.c_Artifact
*
*   @version 1.0.0
*
*   @brief   AUTOSAR Mcem - MCEM IPW Layer
*   @details Implementation of the IP Wrapper layer of the MCEM.
*
*   @addtogroup MCEM_MODULE
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : Fccu
*   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:2004 violations
 *
 * @section Mcem_IPW_c_REF_1
 * Violates MISRA 2004 Required Rule 19.15, Precautions shall be taken in order to prevent the
 * contents of a header file being included twice
 * This is not a violation since all header files are protected against multiple inclusions
 * 
 * @section Mcem_IPW_c_REF_2
 * Violates MISRA 2004 Required Rule 1.4, Exceeds 31 characters due to AUTOSAR 
 * compatibility
 *
 * @section Mcem_IPW_c_REF_3
 * Violates MISRA 2004 Advisory Rule 19.1, #include statements in a file should only be preceded by other
 * preprocessor directives or comments.
 * Violated due to AUTOSAR requirement MEMMAP003.
 *
 * @section Mcem_IPW_c_REF_4
 * Violates MISRA 2004 Required Rule 8.7, Objects shall be defined at block scope if they are only
 * accessed from within a single function. External declaration required here.
 *
 * @section Mcem_IPW_c_REF_5
 * Violates MISRA 2004 Required Rule 19.4, C macros shall only expand to a braced initialiser, a constant, a parenthesised,
 * expression, a type qualifier, a storage class specifier, or a do-while-zero construct.
 * Need wrap naming to a Base function.
 *
 * @section Mcem_IPW_c_REF_6
 * Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined is required for expand the expression of Mcal_Trusted_Call
 *
 * @section [global]
 * Violates MISRA 2004 Required Rule 5.1, Exceeds 31 characters due to AUTOSAR compatibility
 *
 */

/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "CDD_Mcem_Cfg.h"
#include "Mcem_IPW.h"

/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/

#define MCEM_IPW_VENDOR_ID_C                      43
/* @violates @ref Mcem_IPW_c_REF_2 Exceeds 31 characters */
#define MCEM_IPW_AR_RELEASE_MAJOR_VERSION_C       4
/* @violates @ref Mcem_IPW_c_REF_2 Exceeds 31 characters */
#define MCEM_IPW_AR_RELEASE_MINOR_VERSION_C       3
/* @violates @ref Mcem_IPW_c_REF_2 Exceeds 31 characters */
#define MCEM_IPW_AR_RELEASE_REVISION_VERSION_C    1
#define MCEM_IPW_SW_MAJOR_VERSION_C               1
#define MCEM_IPW_SW_MINOR_VERSION_C               0
#define MCEM_IPW_SW_PATCH_VERSION_C               0

/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if current file and CDD_Mcem_Cfg.h header file are of the same vendor */
#if (MCEM_IPW_VENDOR_ID_C != CDD_MCEM_VENDOR_ID_CFG)
    #error "Mcem_IPW.c and CDD_Mcem_Cfg.h have different Vendor ids"
#endif
/* Check if current file and CDD_Mcem_Cfg.h header file are of the same Autosar version */
#if ((MCEM_IPW_AR_RELEASE_MAJOR_VERSION_C    != CDD_MCEM_AR_RELEASE_MAJOR_VERSION_CFG) || \
     (MCEM_IPW_AR_RELEASE_MINOR_VERSION_C    != CDD_MCEM_AR_RELEASE_MINOR_VERSION_CFG) || \
     (MCEM_IPW_AR_RELEASE_REVISION_VERSION_C != CDD_MCEM_AR_RELEASE_REVISION_VERSION_CFG))
    #error "AutoSar Version Numbers of Mcem_IPW.c and CDD_Mcem_Cfg.h are different"
#endif
/* Check if current file and CDD_Mcem_Cfg.h header file are of the same Software version */
#if ((MCEM_IPW_SW_MAJOR_VERSION_C != CDD_MCEM_SW_MAJOR_VERSION_CFG) || \
     (MCEM_IPW_SW_MINOR_VERSION_C != CDD_MCEM_SW_MINOR_VERSION_CFG) || \
     (MCEM_IPW_SW_PATCH_VERSION_C != CDD_MCEM_SW_PATCH_VERSION_CFG))
    #error "Software Version Numbers of Mcem_IPW.c and CDD_Mcem_Cfg.h are different"
#endif

/* Check if current file and Mcem_IPW.h header file are of the same vendor */
#if (MCEM_IPW_VENDOR_ID_C != MCEM_IPW_VENDOR_ID)
    #error "Mcem_IPW.c and Mcem_IPW.h have different Vendor ids"
#endif
/* Check if current file and Mcem_IPW.h header file are of the same Autosar version */
#if ((MCEM_IPW_AR_RELEASE_MAJOR_VERSION_C    != MCEM_IPW_AR_RELEASE_MAJOR_VERSION) || \
     (MCEM_IPW_AR_RELEASE_MINOR_VERSION_C    != MCEM_IPW_AR_RELEASE_MINOR_VERSION) || \
     (MCEM_IPW_AR_RELEASE_REVISION_VERSION_C != MCEM_IPW_AR_RELEASE_REVISION_VERSION))
    #error "AutoSar Version Numbers of Mcem_IPW.c and Mcem_IPW.h are different"
#endif
/* Check if current file and Mcem_IPW.h header file are of the same Software version */
#if ((MCEM_IPW_SW_MAJOR_VERSION_C != MCEM_IPW_SW_MAJOR_VERSION) || \
     (MCEM_IPW_SW_MINOR_VERSION_C != MCEM_IPW_SW_MINOR_VERSION) || \
     (MCEM_IPW_SW_PATCH_VERSION_C != MCEM_IPW_SW_PATCH_VERSION))
    #error "Software Version Numbers of Mcem_IPW.c and Mcem_IPW.h are different"
#endif


/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/


/*==================================================================================================
*                                       LOCAL MACROS
==================================================================================================*/
#if (STD_ON == MCEM_ENABLE_USER_MODE_SUPPORT)
    /* @violates @ref Mcem_IPW_c_REF_5 MISRA 2004 Required Rule 19.4, C macros shall only expand to a braced initialiser,  a constant, a parenthesised expression */
    /* @violates @ref Mcem_IPW_c_REF_6 MISRA 2004 Advisory Rule 19.7, Function-like macro defined. */
    #define Call_Mcem_Fccu_LockConfiguration()      Mcal_Trusted_Call(Mcem_Fccu_LockConfiguration)
#else
    /* @violates @ref Mcem_IPW_c_REF_5 MISRA 2004 Required Rule 19.4, C macros shall only expand to a braced initialiser,  a constant, a parenthesised expression */
    /* @violates @ref Mcem_IPW_c_REF_6 MISRA 2004 Advisory Rule 19.7, Function-like macro defined. */
    #define Call_Mcem_Fccu_LockConfiguration()      Mcem_Fccu_LockConfiguration()
#endif

/*==================================================================================================
*                                      LOCAL CONSTANTS
==================================================================================================*/


/*==================================================================================================
*                                      LOCAL VARIABLES
==================================================================================================*/
#define MCEM_START_SEC_VAR_NO_INIT_32
/* @violates @ref Mcem_IPW_c_REF_1 precautions to prevent the contents of a header file being included multiple time */
/* @violates @ref Mcem_IPW_c_REF_3 only preprocessor statements and comments before "#include". */
#include "Mcem_MemMap.h"

/**
* @brief          Temporary Flag for used in function Mcem_IPW_GetErrors for prevent MISRA rule 1.2
* @details        Temporary Flag for used in function Mcem_IPW_GetErrors for prevent MISRA rule 1.2
*/
/* @violates @ref Mcem_IPW_c_REF_4 Block scope */
static VAR(uint32,MCEM_VAR) Mcem_u32FaultAccumulator;


#define MCEM_STOP_SEC_VAR_NO_INIT_32
/* @violates @ref Mcem_IPW_c_REF_1 precautions to prevent the contents of a header file being included multiple time */
/* @violates @ref Mcem_IPW_c_REF_3 only preprocessor statements and comments before "#include". */
#include "Mcem_MemMap.h"


/*==================================================================================================
*                                      GLOBAL CONSTANTS
==================================================================================================*/


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


/*==================================================================================================
*                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/


/*==================================================================================================
*                                       LOCAL FUNCTIONS
==================================================================================================*/

#define MCEM_START_SEC_CODE
/* @violates @ref Mcem_IPW_c_REF_1 precautions to prevent the contents of a header file being included twice */
/* @violates @ref Mcem_IPW_c_REF_3 only preprocessor statements and comments before "#include". */
#include "Mcem_MemMap.h"

/*==================================================================================================
*                                       GLOBAL FUNCTIONS
==================================================================================================*/


/**
* @brief          Mcem IPW Init function
* @details        Function distributes the configuration for th two IPs of the driver.
*
* @param[in,out]  pConfigPtr   Configuration pointer for the driver.
*
* @return         Std_ReturnType 
* @retval E_OK                Driver has been initialized correctly and checked using readback.
* @retval E_NOT_OK            Driver has not been initialized correctly, readback failed.
*
* @api           
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(Std_ReturnType, MCEM_CODE) Mcem_IPW_Init(P2CONST(Mcem_ConfigType, AUTOMATIC, MCEM_APPL_CONST) pConfigPtr)
{
    VAR(Std_ReturnType, MCEM_VAR) nReturnValue = (Std_ReturnType)E_NOT_OK;

    /* Init the FCCU */
    nReturnValue = Mcem_Fccu_Init(pConfigPtr->FccuConfig);
    
    return nReturnValue;
}


/**
* @brief          Function to inject fake faults
* @details        Function is used to inject fake faults in order to test the reaction for each fault.
*
* @param[in]      nFaultId     The ID of the fault to be injected
*                            
* @return         void 
*
* @pre            nFaultId is valid
*
* @api            
*
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(void, MCEM_CODE) Mcem_IPW_InjectFault(VAR(Mcem_FaultType, AUTOMATIC) nFaultId)
{

    if ( MCEM_FAULT_IN_FCCU_RANGE(nFaultId) )
    {
        Mcem_Fccu_InjectFault(nFaultId);
    }
    else 
    {
        /* do nothing */
    }
}

/**
* @brief          Function to inject fake faults
* @details        Function is used to inject fake faults in order to test the reaction for each fault.
*
* @param[in]      nFaultId     The ID of the fault to be injected
*                            
* @return         void 
*
* @pre            nFaultId is valid
*
* @api            
*
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(boolean, MCEM_CODE) Mcem_IPW_CheckValidFault(VAR(Mcem_FaultType, AUTOMATIC) nFaultId)
{
    VAR(boolean, AUTOMATIC) bReturnValue;
    
    if (MCEM_FAULT_IN_FCCU_RANGE( (nFaultId) ))
    {
        bReturnValue = (Mcem_Fccu_CheckValidFault(nFaultId));
    }
    else
    {
        bReturnValue = (boolean)TRUE;
    }
    return (bReturnValue);
}
/**
* @brief          Get errors function
* @details        Function gets the errors logged in the hw IP and stores them into a container.
*
* @param[in,out]  pErrorContainer  Error container where the errors shall be stored.
*
* @return         Std_ReturnType
* @retval E_OK               No fault is pending.
* @retval E_FAULT_DETECTED   There is at least one logged fault.
* @retval E_NOT_OK           Otherwise (error occured while querying faults in the hardware).
*
* @api            
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(Std_ReturnType, MCEM_CODE) Mcem_IPW_GetErrors(P2VAR(Mcem_FaultContainerType, AUTOMATIC, MCEM_APPL_DATA) pErrorContainer, VAR(boolean, AUTOMATIC) bNmiCall)
{
    VAR(Std_ReturnType,MCEM_VAR) nReturnValue = (Std_ReturnType)E_NOT_OK;
    
    /* Initialized temporary flag */
    Mcem_u32FaultAccumulator = 0U;

    /* Store Fccu faults */
    nReturnValue = Mcem_Fccu_GetErrors( &(pErrorContainer->au32Faults[ 0 ]), &Mcem_u32FaultAccumulator , bNmiCall );
    
    MCAL_FAULT_INJECTION_POINT(MCEM_FIP_1_CLEAR_HARD_FAULTS);

    /* In case error status has been retrieved properly, handle global error flag */
    if ( ((Std_ReturnType)E_OK == nReturnValue) && (0UL != Mcem_u32FaultAccumulator) )
    {
        /* At least one bit has been set */
        nReturnValue = (Std_ReturnType)E_FAULT_DETECTED;
    }
    /* Store the resulting status */
    pErrorContainer->nErrorStatus = nReturnValue;

    return nReturnValue;
}


/**
* @brief          Clear fault function
* @details        The function shall clear the specified fault. The fault can be cleared only if the fault 
*                 cause is eliminated and the fault is marked as software recoverable.
*
* @param[in]      nFaultId     The ID of the fault that shall be cleared
*
* @return         Std_ReturnType 
* @retval E_OK                The fault has been successfully cleared
*
* @retval E_NOT_OK            The fault has not been successfully cleared. Possible causes : 
*                             -the fault source has not been eliminated
*                             -the fault occured again
*
* @pre            nFaultId is valid
*
* @api           
*
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(Std_ReturnType, MCEM_CODE) Mcem_IPW_ClearFaults(VAR(Mcem_FaultType, AUTOMATIC) nFaultId, VAR(boolean, AUTOMATIC) bNmiCall)
{
    VAR(Std_ReturnType,MCEM_VAR) nReturnValue = (Std_ReturnType)E_NOT_OK;

    if ( MCEM_FAULT_IN_FCCU_RANGE(nFaultId) )
    {
        /* FP1 - Failure Point 1  */
        nReturnValue = Mcem_Fccu_ClearFault(nFaultId, bNmiCall);
    }
    else 
    {
        /* do nothing */
    }
    return nReturnValue;
}


/**
* @brief          Configuration lock function
* @details        Function used to lock the configuration
*                 
*
* @return         void
*
* @api            
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(void, MCEM_CODE) Mcem_IPW_LockConfiguration( void )
{
    /* Hardlock the Fccu configuration */
    /** @violates @ref Mcem_IPW_c_REF_7 comma operator to extract expression of Mcal_Trusted_Call*. */
    Call_Mcem_Fccu_LockConfiguration();
}


/**
* @brief          Check whether an NMI has originated from the FCCU
* @details        Function checks whether the FCCU is the source of NMI request.
*
* @return         Std_ReturnType (extended) 
* @retval E_FCCU_SPURIOUS_NMI   The initialized MCEM (FCCU) might trigger a spurious interrupt.
* @retval E_OK                  The NMI request originates in initialized MCEM (FCCU).
* @retval E_NOT_OK              Othewise (non-FCCU related NMI, FCCU malfunction).
*
* @note           In case the preconditions for erratum e5922 are fulfilled, the user NMI handler has to 
*                 call Mcem_GetErrors() function to check whether there is at least one pending fault.
* @pre              MCEM/FCCU has been initialized
*/
/* @violates @ref Mcem_IPW_c_REF_8 Public API */
FUNC(Std_ReturnType, MCEM_CODE) Mcem_IPW_CheckNMI( void )
{
    /* Let FCCU perform the job */
    return Mcem_Fccu_CheckNMI();
}


#define MCEM_STOP_SEC_CODE
/* @violates @ref Mcem_IPW_c_REF_1 precautions to prevent the contents of a header file being included twice */
/* @violates @ref Mcem_IPW_c_REF_3 only preprocessor statements and comments before "#include". */
#include "Mcem_MemMap.h"

#ifdef __cplusplus
}
#endif

/** @} */
