/**
*   @file    Can.c
*   @implements Can.c_Artifact
*   @version 1.0.0
*   @file    Can.c
*   @implements Can_module
*
*   @brief   AUTOSAR Can - module interface
*   @details API implementation for CAN driver.
*
*   @addtogroup CAN_DRIVER
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : MCAN
*   Dependencies         : 
*
*   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 Can_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 [global]
*          Violates MISRA 2012 Required Rule 5.1, External identifiers shall be distinct.
*          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 name space shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.4, Macro identifiers shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.5, Identifiers shall be distinct from macro names.
*          The used compilers use more than 31 chars for identifiers.
* 
* @section Can_c_REF_6
* Violates MISRA 2012 Advisory Rule 20.1, #include directives should only be preceded by preprocessor 
* directives or comments. AUTOSAR imposes the specification of the sections in which certain parts
* of the driver must be placed.
*
* @section Can_c_REF_7
* Violates MISRA 2012 Advisory Rule 8.7,  Functions and objects should not be defined with external 
* linkage if they are referenced in only one translation unit.
* These functions represent the API of the driver. External linkage is needed to export the API.
*
* @section Can_c_REF_8
* Violates MISRA 2012 Advisory Rule 8.9, An object should be defined at block scope if its identifier only appears
* in a single function.
*
* @section Can_c_REF_9
* 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.
*
* @section Can_c_REF_10
* Violates MISRA 2012 Advisory Rule 12.3, The comma operator should not be used.
* The comma is used  to abstract the trusted call function and to determine when the return into user mode is needed.
*
* @section Can_c_REF_11
* Violates MISRA 2012 Advisory Rule 2.5, A project should not contain unused macro declarations.
* Declaration is reserved for future feature.
*
*/


/*
Driver Limitations:
    1. The maximum number of Can_DisableControllerInterrupts levels of nesting is 127. (variable "sint8" used for nesting level: -128 .. +127)
    2. This file contains 2 types of functions: first are the Autosar APIs and then are some user defined functions.
*/


/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
/*
* @file           Can.c
*/
#include "Can.h"
#include "Can_IPW.h"
#include "CanIf_Cbk.h"
#include "Std_Types.h"
#ifdef CAN_ENABLE_WAKEUP_SUPPORT
    #if (CAN_ENABLE_WAKEUP_SUPPORT == STD_ON) 
        #include "EcuM.h"
    #endif /* (CAN_ENABLE_WAKEUP_SUPPORT == STD_ON) */
#endif
#if (CAN_DEV_ERROR_DETECT == STD_ON)
#include "Det.h"
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
#include "SchM_Can.h"
/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/
/*   Can.c shall check if the correct version of Can.h is included.
            This shall be done by a preprocessor check of the version numbers CAN_SW_MAJOR_VERSION, CAN_SW_MINOR_VERSION and CAN_SW_PATCH_VERSION.
*/
/**
* @file           Can.c
*/
#define CAN_VENDOR_ID_C                      43
/* @violates @ref Can_c_REF_11 MISRA 2012 Advisory Rule 2.5 */
#define CAN_MODULE_ID_C                      80
#define CAN_AR_RELEASE_MAJOR_VERSION_C       4
#define CAN_AR_RELEASE_MINOR_VERSION_C       3
#define CAN_AR_RELEASE_REVISION_VERSION_C    1
#define CAN_SW_MAJOR_VERSION_C               1
#define CAN_SW_MINOR_VERSION_C               0
#define CAN_SW_PATCH_VERSION_C               0


/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if current file and Can header file are of the same vendor */
#if (CAN_VENDOR_ID_C != CAN_VENDOR_ID)
    #error "Can.c and Can.h have different vendor ids"
#endif
/* Check if current file and Can header file are of the same Autosar version */
#if ((CAN_AR_RELEASE_MAJOR_VERSION_C    != CAN_AR_RELEASE_MAJOR_VERSION) || \
     (CAN_AR_RELEASE_MINOR_VERSION_C    != CAN_AR_RELEASE_MINOR_VERSION) || \
     (CAN_AR_RELEASE_REVISION_VERSION_C != CAN_AR_RELEASE_REVISION_VERSION))
    #error "AutoSar Version Numbers of Can.c and Can.h are different"
#endif
/* Check if current file and Can header file are of the same Software version */
#if ((CAN_SW_MAJOR_VERSION_C != CAN_SW_MAJOR_VERSION) || \
     (CAN_SW_MINOR_VERSION_C != CAN_SW_MINOR_VERSION) || \
     (CAN_SW_PATCH_VERSION_C != CAN_SW_PATCH_VERSION))
    #error "Software Version Numbers of Can.c and Can.h are different"
#endif

/* Check if current file and Can_IPW header file are of the same vendor */
#if (CAN_VENDOR_ID_C != CAN_IPW_VENDOR_ID_H)
    #error "Can.c and Can_IPW.h have different vendor ids"
#endif
/* Check if current file and Can_IPW header file are of the same Autosar version */
#if ((CAN_AR_RELEASE_MAJOR_VERSION_C    != CAN_IPW_AR_RELEASE_MAJOR_VERSION_H) || \
     (CAN_AR_RELEASE_MINOR_VERSION_C    != CAN_IPW_AR_RELEASE_MINOR_VERSION_H) || \
     (CAN_AR_RELEASE_REVISION_VERSION_C != CAN_IPW_AR_RELEASE_REVISION_VERSION_H))
    #error "AutoSar Version Numbers of Can.c and Can_IPW.h are different"
#endif
/* Check if current file and Can_IPW header file are of the same Software version */
#if ((CAN_SW_MAJOR_VERSION_C != CAN_IPW_SW_MAJOR_VERSION_H) || \
     (CAN_SW_MINOR_VERSION_C != CAN_IPW_SW_MINOR_VERSION_H) || \
     (CAN_SW_PATCH_VERSION_C != CAN_IPW_SW_PATCH_VERSION_H))
    #error "Software Version Numbers of Can.c and Can_IPW.h are different"
#endif

#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and CanIf_Cbk header file are of the same Autosar version */
    #if ( (CAN_AR_RELEASE_MAJOR_VERSION_C != CANIF_CBK_AR_RELEASE_MAJOR_VERSION) || \
        (CAN_AR_RELEASE_MINOR_VERSION_C != CANIF_CBK_AR_RELEASE_MINOR_VERSION) \
      )
        #error "AutoSar Version Numbers of Can.c and CanIf_Cbk.h are different"
    #endif
    
    /* Check if current file and Std_Types header file are of the same Autosar version */
    #if ( (CAN_AR_RELEASE_MAJOR_VERSION_C != STD_AR_RELEASE_MAJOR_VERSION) || \
        (CAN_AR_RELEASE_MINOR_VERSION_C != STD_AR_RELEASE_MINOR_VERSION) \
      )
        #error "AutoSar Version Numbers of Can.c and Std_Types.h are different"
    #endif
    
    /* Check if current file and EcuM header file are of the same Autosar version */
    #ifdef CAN_ENABLE_WAKEUP_SUPPORT
        #if (CAN_ENABLE_WAKEUP_SUPPORT == STD_ON)
            #if ((CAN_AR_RELEASE_MAJOR_VERSION_C != ECUM_AR_RELEASE_MAJOR_VERSION) || \
             (CAN_AR_RELEASE_MINOR_VERSION_C != ECUM_AR_RELEASE_MINOR_VERSION))
                #error "AutoSar Version Numbers of Can.c and EcuM.h are different"
            #endif
        #endif
    #endif
    /* Check if current file and Det header file are of the same Autosar version */
    #if (CAN_DEV_ERROR_DETECT == STD_ON)
        #if ((CAN_AR_RELEASE_MAJOR_VERSION_C != DET_AR_RELEASE_MAJOR_VERSION) || \
             (CAN_AR_RELEASE_MINOR_VERSION_C != DET_AR_RELEASE_MINOR_VERSION))
            #error "AutoSar Version Numbers of Can.c and Det.h are different"
        #endif
    #endif
#endif
/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/


/*==================================================================================================
*                                       LOCAL MACROS
==================================================================================================*/


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


/*==================================================================================================
*                                      LOCAL VARIABLES
==================================================================================================*/


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


/*==================================================================================================
*                                      GLOBAL VARIABLES
==================================================================================================*/
#define CAN_START_SEC_VAR_INIT_UNSPECIFIED
/* @violates @ref Can_c_REF_1 This violation is not fixed since the inclusion of Can_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Can_c_REF_6 Can_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR*/
#include "Can_MemMap.h"


/**
* @brief          This variable holds the state of the driver.
* @details        This variable holds the state of the driver. After reset is UNINIT. The output of Can_Init() function
*                 (only to first call) should set this variable into READY state.
*                  CAN_UNINIT = The CAN controller is not initialized. All registers belonging to the CAN module are in reset state, CAN interrupts are disabled.
*                  The CAN Controller is not participating on the CAN bus.
*                  The Can module must only implement a variable for the module state, when the development error tracing is switched on.
*                  When the development error tracing is switched off, the Can module does not need to implement this 'state machine',
*                  because the state information is only needed to check if Can_Init was called prior to any Can module function.
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
VAR(Can_StatusType, CAN_VAR) Can_eDriverStatus = CAN_UNINIT;

/* Pointer to the current Driver Configuration (passed to the driver during initialization). Initialized by Can_Init(). */
P2CONST(Can_ConfigType, CAN_VAR, CAN_APPL_CONST) Can_pCurrentConfig = NULL_PTR;
P2CONST(Can_ControlerDescriptorType, CAN_VAR, CAN_APPL_CONST) Can_pControlerDescriptors = NULL_PTR;
P2CONST(CanStatic_ControlerDescriptorType, CAN_VAR, CAN_APPL_CONST) CanStatic_pControlerDescriptors = NULL_PTR;
P2CONST(CanStatic_ConfigType, CAN_VAR, CAN_APPL_CONST) CanStatic_pCurrentConfig = NULL_PTR;
#define CAN_STOP_SEC_VAR_INIT_UNSPECIFIED
/* @violates @ref Can_c_REF_1 This violation is not fixed since the inclusion of Can_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Can_c_REF_6 Can_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR*/
#include "Can_MemMap.h"

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


/*==================================================================================================
*                                       LOCAL FUNCTIONS
==================================================================================================*/
#define CAN_START_SEC_CODE
/* @violates @ref Can_c_REF_1 This violation is not fixed since the inclusion of Can_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Can_c_REF_6 Can_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR*/
#include "Can_MemMap.h"


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


/*================================================================================================*/


#if (CAN_VERSION_INFO_API == STD_ON)
/**
* @brief          Returns the version information of this module. SID is 0x07
* @details        This routine is called by:
*                - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      versioninfo A pointer to location to store version info
*                             Must be omitted if the function does not have parameters.
*
* @return         void
*
*
* @pre            The CAN_VERSION_INFO_API define must be configured on.
* @post           The version information is return if the parameter versionInfo is not a null pointer.
*
* @implements     Can_GetVersionInfo_Activity
* @api
*
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_GetVersionInfo( P2VAR(Std_VersionInfoType, AUTOMATIC, CAN_APPL_DATA) versioninfo)
{

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /*
    (SWS_Can_00177) If development error detection for the Can module is enabled: The function Can_GetVersionInfo shall
                 raise the error CAN_E_PARAM_POINTER if the parameter versionInfo is a null pointer.
    */
    if ( NULL_PTR == versioninfo )
    {
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_VERSION_INFO, (uint8)CAN_E_PARAM_POINTER);
    }
    else
    {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
        /*
            The function Can_GetVersionInfo shall return the version information of this module. The version information
            includes: Module Id, Vendor Id, Vendor specific version numbers.
        */
        versioninfo->vendorID         = (uint16)CAN_VENDOR_ID;
        versioninfo->moduleID         = (uint16)CAN_MODULE_ID;
        versioninfo->sw_major_version = (uint8)CAN_SW_MAJOR_VERSION;
        versioninfo->sw_minor_version = (uint8)CAN_SW_MINOR_VERSION;
        versioninfo->sw_patch_version = (uint8)CAN_SW_PATCH_VERSION;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
}
#endif /* (CAN_VERSION_INFO_API == STD_ON) */

/*================================================================================================*/
/**
* @brief          Reports about the current status of the requested CAN controller. SID is 0x12
* @details        This routine is called by:
*                - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Controller: CAN controller for which the status shall be requested.
*
* @param[out]     ControllerModePtr: Pointer to a memory location, where the current mode of the CAN controller will be stored.
*
* @retval         E_OK : Controller mode request has been accepted.
* @retval         E_NOT_OK : Controller mode request has not been accepted.
*
* @pre            
* @post           
*
* @implements     Can_GetControllerMode_Activity
* @api
*
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerMode( VAR(uint8, AUTOMATIC) Controller, P2VAR(Can_ControllerStateType, AUTOMATIC, CAN_APPL_DATA) ControllerModePtr)
{
    /* Return the result of GetControllerMode */
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (Std_ReturnType)E_NOT_OK;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* 
        [SWS_Can_91016]  If default error detection for the Can module is enabled: The function Can_GetControllerMode shall raise the error CAN_E_UNINIT 
                    and return E_NOT_OK if the driver is not yet initialized.
    */
    if ( CAN_READY != Can_eDriverStatus )
    {
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_MODE , (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* 
            [SWS_Can_91017] If parameter Controller of Can_GetControllerMode() has an invalid value, 
                    the CanDrv shall report development error code CAN_E_PARAM_CONTROLLER to the Det_ReportError service of the DET. 
        */
        /* The Controller ID must be within range and the selected controller must be configured for use in the configuration tool. */
        if ( (Controller >= CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == CanStatic_pControlerDescriptors[Controller].u8ControllerOffset) 
           )
        {
           (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_MODE , (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
            /* 
                [SWS_Can_91018] If parameter ControllerModePtr of Can_GetControllerMode() has an null pointer, 
                        the CanDrv shall report development error code CAN_E_PARAM_POINTER to the Det_ReportError service of the DET.
            */
            if (NULL_PTR == ControllerModePtr)
            {
                (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_MODE , (uint8)CAN_E_PARAM_POINTER);
            }
            else
            {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
                /* Point to memory location, where the state of current controller is stored */
                *ControllerModePtr = Can_IPW_GetControllerMode(Controller);

                eReturnValue = (Std_ReturnType)E_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
            }
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
    return eReturnValue;
}

/*================================================================================================*/
/**
* @brief          Obtains the error state of the CAN controller.. SID is 0x11
* @details        This routine is called by:
*                - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      ControllerId: Abstracted CanIf ControllerId which is assigned to a CAN controller, which is requested for ErrorState.
*
* @param[out]     ErrorStatePtr: Pointer to a memory location, where the error state of the CAN controller will be stored.
*
* @retval         E_OK : Error state request has been accepted.
* @retval         E_NOT_OK : Error state request has not been accepted.
*
* @pre            
* @post           
*
* @implements     Can_GetControllerErrorState_Activity
* @api
*
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerErrorState( VAR(uint8, AUTOMATIC) ControllerId, P2VAR(Can_ErrorStateType, AUTOMATIC, CAN_APPL_DATA) ErrorStatePtr)
{
    /* Return the result of GetControllerErrorState */
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (Std_ReturnType)E_NOT_OK;
  
#if (CAN_DEV_ERROR_DETECT == STD_ON)  
    /* 
        [SWS_Can_91005] If default error detection for the Can module is enabled: if the module is not yet initialized, 
                the function Can_GetControllerErrorState shall raise default error CAN_E_UNINIT and return E_NOT_OK. 
    */
    if ( CAN_READY != Can_eDriverStatus )
    {
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_ERROR_STATE, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* 
            [SWS_Can_91006] If default error detection for the Can module is enabled: if the parameter ControllerId is out of range, 
                    the function Can_GetControllerErrorState shall raise default error CAN_E_PARAM_CONTROLLER and return E_NOT_OK. 
        */
                
        /* The Controller ID must be within range and the selected controller must be configured for use in the configuration tool. */
        if ( (ControllerId >= CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == CanStatic_pControlerDescriptors[ControllerId].u8ControllerOffset) 
           )
        {
           (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_ERROR_STATE, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
            /* 
                [SWS_Can_91007] If default error detection for the Can module is enabled: if the parameter ErrorStatePtr is a null pointer, 
                        the function Can_GetControllerErrorState shall raise default error CAN_E_PARAM_POINTER and return E_NOT_OK. 
            */
            if (NULL_PTR == ErrorStatePtr)
            {
                (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_ERROR_STATE, (uint8)CAN_E_PARAM_POINTER);
            }
            else
            {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
                *ErrorStatePtr = Can_IPW_GetControllerErrorState(ControllerId);

                eReturnValue = (Std_ReturnType) E_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON) 
            }
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
    return eReturnValue;
}
/*================================================================================================*/
/**
* @brief          Initialize the CAN driver. SID is 0x00.
* @details        Initialize all the controllers.
*                 The CAN module shall be initialized by Can_Init(<&Can_Configuration>) service call during the start-up.
*                 This routine is called by:
*                - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Config Pointer to driver configuration.
*
* @return         void
*
*
* @pre            Can_Init shall be called at most once during runtime.
* @post           Can_Init shall initialize all the controllers and set the driver in READY state.
*
* @implements     Can_Init_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_Init( P2CONST(Can_ConfigType, AUTOMATIC, CAN_APPL_CONST) Config)
{
    /* Variable for indexing the controllers. */
    VAR(uint8, AUTOMATIC) can_controller = 0U;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    if ( CAN_READY == Can_eDriverStatus )
    {
        /*
            (SWS_Can_00091) After return of the DET the Can module function that raised the development error shall return immediately.
            (SWS_Can_00174) If development error detection for the Can module is enabled: The function Can_Init shall raise the
                       error CAN_E_TRANSITION if the driver is not in 'uninitialized' state.
        */
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_INIT, (uint8)CAN_E_TRANSITION);
    }
    else
    {
#if (CAN_PRECOMPILE_SUPPORT == STD_ON)
        if (NULL_PTR != Config)
#else
        if (NULL_PTR == Config)
#endif /* CAN_PRECOMPILE_SUPPORT */
        {
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_INIT, (uint8)CAN_E_INIT_FAILED);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */

#if (CAN_PRECOMPILE_SUPPORT == STD_ON)
            /* Update config pointer with default configuration if precompile support on. */
            Can_pCurrentConfig = &Can_PBCfgVariantPredefined;

            (void)Config; /* Prevent compiler warning */
#else
            /* Copy pointer to current Can Driver configuration. */
            Can_pCurrentConfig = Config;
#endif /* CAN_PRECOMPILE_SUPPORT */
            Can_pControlerDescriptors = Can_pCurrentConfig->ControlerDescriptors;
            CanStatic_pCurrentConfig = &CanStatic_ConfigSet;
            CanStatic_pControlerDescriptors = CanStatic_pCurrentConfig->StaticControlerDescriptors;

            /* Initialisation of usefull indicators. */
            Can_IPW_InitVariables();

#if (STD_ON == CAN_ENABLE_USER_MODE_SUPPORT)
    #ifdef CAN_FLEXCAN_REG_PROT_AVAILABLE
            Can_IPW_SetUserAccessAllowed();
    #endif
#endif
            /* Loop through all Can controllers configured based CanControllerId parameter. */
            for ( can_controller = 0U; can_controller < (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured; can_controller++)
            {
                /* The initialization is skipped for the controllers that are not enabled. */
                if ( CAN_NULL_OFFSET != (CanStatic_pControlerDescriptors[can_controller].u8ControllerOffset))
                {
                    /* Init - ControllerState, uFirstHrhIndex, HthOffset, DefaultConfigIndex, u8MaxMBCount, Freeze controller and more. */
                    /*
                       (SWS_Can_00250) The function Can_Init shall initialize: static variables, including flags, Common setting for the
                               complete CAN HW unit, CAN controller specific settings for each CAN controller.
                       (SWS_Can_00245) The function Can_Init shall initialize all CAN controllers according to their configuration.
                       (SWS_Can_00053) Can_Init shall not change registers of CAN controller Hardware resources that are not used.
                    */
                    /* @violates @ref Can_c_REF_9 */
                    Can_IPW_InitController( can_controller);
                }
            }
            /*
              (SWS_Can_00246) After initializing all controllers inside the HW Unit, the function Can_Init shall change the module state to CAN_READY.
            */
            Can_eDriverStatus = CAN_READY;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        }     
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
}

/*================================================================================================*/
/**
* @brief          De-initialize the CAN driver. SID is 0x10.
* @details        De-initialize all the controllers.
*                 The CAN module shall be de-initialized by Can_DeInit() service call during the start-up.
*                 This routine is called by:
*                - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      None
*
* @return         void
*
*
* @pre            Before controller de-initalization, the driver must be initialized and the controllers must be not in Start state.
* @post           Can_DeInit shall de-initialize all the controllers and set the driver in UNINIT state.
*
* @implements     Can_DeInit_Activity
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_DeInit(void)
{
    /* Variable for indexing the controllers. */
    VAR(uint8, AUTOMATIC) u8CanCtrlIdx = 0U;
    
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* The flag of checking of Can Controller status */
    VAR(boolean, AUTOMATIC) bIsCanCtrlBusy = (boolean)FALSE;
#endif    
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    if ( CAN_READY != Can_eDriverStatus )
    {
        /* 
            (SWS_Can_91011) If development error detection for the Can module is enabled: The function Can_DeInit shall raise the error CAN_E_TRANSITION 
            if the driver is not in state CAN_READY.
        */
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_DEINIT, (uint8)CAN_E_TRANSITION);
    }
    else
    {
        /* Loop through all Can controllers configured based CanControllerId parameter. */
        for ( u8CanCtrlIdx = 0U; u8CanCtrlIdx < (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured; u8CanCtrlIdx++)
        {
            /* Skipping controllers that are not enabled. */
            if ( CAN_NULL_OFFSET != (CanStatic_pControlerDescriptors[u8CanCtrlIdx].u8ControllerOffset))
            {
                if (CAN_CS_STARTED == Can_IPW_GetControllerMode(u8CanCtrlIdx))
                {
                    /* 
                        (SWS_Can_91012) If development error detection for the Can module is enabled: The function Can_DeInit shall raise the error CAN_E_TRANSITION 
                        if any of the CAN controllers is in state STARTED.
                    */
                    (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_DEINIT, (uint8)CAN_E_TRANSITION);
                    
                    /* Controller is busy */
                    bIsCanCtrlBusy =  (boolean)TRUE;
                    /* Skipping the loop if any of Can Controller is in state STARTED */
                    break;
                }
            }
        }
        /* All Controllers are not busy */
        if ((boolean)TRUE != bIsCanCtrlBusy)
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */       
            /* Update state of Can driver */
            /* [SWS_Can_ 91009] The function Can_DeInit shall change the module state to
                CAN_UNINIT before de-initializing all controllers inside the HW unit */
            Can_eDriverStatus = CAN_UNINIT;
            
            /* Loop through all Can controllers configured based CanControllerId parameter. */
            for ( u8CanCtrlIdx = 0U; u8CanCtrlIdx < (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured; u8CanCtrlIdx++)
            {
                /* Skipping controllers that are not enabled. */
                if ( CAN_NULL_OFFSET != (CanStatic_pControlerDescriptors[u8CanCtrlIdx].u8ControllerOffset))
                {
                    /* @violates @ref Can_c_REF_10 */
                    Can_IPW_DeInitController(u8CanCtrlIdx);
                }
            }
            Can_pCurrentConfig = NULL_PTR;
            Can_pControlerDescriptors = NULL_PTR;
            CanStatic_pControlerDescriptors = NULL_PTR;
            CanStatic_pCurrentConfig = NULL_PTR;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
}


/*================================================================================================*/
/**
* @brief          Put the controller into a required state. SID is 0x03.
* @details        Switch the controller from one state to another.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Controller - Can controller for which the status shall be changed - based on configuration order list (CanControllerId).
* @param[in]      Transition - Possible transitions (CAN_CS_STOPPED , CAN_CS_STARTED , CAN_CS_SLEEP )
* @return         Std_ReturnType  Result of the transition.
* @retval         E_OK   request accepted.
* @retval         E_NOT_OK  request not accepted, a development error occurred.
*
*
* @pre            Before changing the controller state the driver must be initialized.
* @post           After the transition to the new state the interrupts required for that state must be enebaled.
*
* @implements     Can_SetControllerMode_Activity
*
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_SetControllerMode( VAR(uint8, AUTOMATIC) Controller,
                                                      VAR(Can_ControllerStateType, AUTOMATIC) Transition 
                                                    )
{
    /* Returns the result of transition mode. */
    VAR(Std_ReturnType, AUTOMATIC)  eReturnValue = E_NOT_OK;

    /*
        (SWS_Can_00089) The Can module environment shall indicate development errors only in the return values of a function of the Can module when DET
            is switched on and the function provides a return value. The returned value is E_NOT_OK.
    */
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* If Can_pCurrentConfig is NULL_PTR then the Driver was not initialised yet. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        /*
           (SWS_Can_00198) If development error detection for the Can module is enabled: if the module is not yet initialized, the
                   function Can_SetControllerMode shall raise development error CAN_E_UNINIT and return E_NOT_OK.
        */
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_CONTROLLER_MODE, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* Controller ID must be within range and the selected Controller must be configured for use in the config tool. */
        if ( (Controller >= (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[Controller].u8ControllerOffset)) 
           )
        {
            /*
               (SWS_Can_00199) If development error detection for the Can module is enabled: if the parameter Controller is out of range,
                       the function Can_SetControllerMode shall raise development error CAN_E_PARAM_CONTROLLER and return E_NOT_OK.
            */
            
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_CONTROLLER_MODE, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
            /* Call the IPW function for transition execution. */
            eReturnValue = (Std_ReturnType)Can_IPW_SetControllerMode( Controller, &(Can_pCurrentConfig->ControlerDescriptors[Controller]), Transition,(boolean)TRUE);
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT==STD_ON)  */

    return (eReturnValue);
}


/*================================================================================================*/
/**
* @brief          Disable INTs. SID is 0x04.
* @details        Switch OFF the controller's interrupts.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Controller Can controller for which interrupts shall be disabled - based on configuration order list (CanControllerId).
*
* @return         void
*
*
* @pre            Driver must be initalzied before changing the interrupts state (en or dis).
* @post           Controller must not respond to any interrupt assertion.
*
* @implements     Can_DisableControllerInterrupts_Activity
*
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_DisableControllerInterrupts( VAR(uint8, AUTOMATIC) Controller)
{
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* If Can_pCurrentConfig is NULL_PTR then the driver was not initialised yet. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        /*
           (SWS_Can_00205) If development error detection for the Can module is enabled: The function Can_DisableControllerInterrupts shall
                   raise the error CAN_E_UNINIT if the driver not yet initialized.
        */
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_DISABLE_CONTROLLER_INTERRUPTS, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* The Controller ID must be within range and the selected Controller must be configured for use in the config tool. */
        if ( (Controller >= (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[Controller].u8ControllerOffset)) 
           )
        {
            /*
               (SWS_Can_00206) If development error detection for the Can module is enabled: The function Can_DisableControllerInterrupts shall
                       raise the error CAN_E_PARAM_CONTROLLER if the parameter Controller is out of range.
            */
            
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_DISABLE_CONTROLLER_INTERRUPTS, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
            /* Call the IPW function for disabling interrupts. */
            Can_IPW_DisableControllerInterrupts( Controller);
#if (CAN_DEV_ERROR_DETECT == STD_ON)        
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
}


/*================================================================================================*/
/**
* @brief          Enable INTs. SID is 0x05.
* @details        Switch ON the controller's interrupts.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Controller Can controller for which interrupts shall be disabled - based on configuration order list (CanControllerId).
*
* @return         void
*
*
* @pre            Driver must be initalzied before changing the interrupts state (en or dis).
* @post           Controller must respond to interrupt assertion.
*
* @implements     Can_EnableControllerInterrupts_Activity
 * @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_EnableControllerInterrupts( VAR(uint8, AUTOMATIC) Controller)
{

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* If Can_pCurrentConfig is NULL_PTR then the driver was not initialised yet. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        /*
           (SWS_Can_00209) If development error detection for the Can module is enabled: The function Can_EnableControllerInterrupts shall raise
                   the error CAN_E_UNINIT if the driver not yet initialized.
        */
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_ENABLE_CONTROLLER_INTERRUPTS, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* Controller ID must be within range and the selected Controller must be configured for use in the config tool. */
        if ( (Controller >= (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[Controller].u8ControllerOffset)) 
           )
        {
            /*
               (SWS_Can_00210) If development error detection for the Can module is enabled: The function Can_EnableControllerInterrupts shall
                       raise the error CAN_E_PARAM_CONTROLLER if the parameter Controller is out of range.
            */
            
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_ENABLE_CONTROLLER_INTERRUPTS, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
            /* Call the IPW function for enabling interrupts. */
            Can_IPW_EnableControllerInterrupts( Controller, &(Can_pCurrentConfig->ControlerDescriptors[Controller]));
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
}


/*================================================================================================*/
/**
* @brief          Transmit information on CAN bus. SID is 0x06.
* @details        Can_Write checks if hardware transmit object that is identified by the HTH is free.
*                    Can_Write checks if another Can_Write is ongoing for the same HTH.
*                     a) hardware transmit object is free:
*                         The mutex for that HTH is set to 'signaled' the ID, DLC and SDU are put in a format appropriate for
*                           the hardware (if necessary) and copied in the appropriate hardware registers or buffers.
*                        All necessary control operations to initiate the transmit are done.
*                         The mutex for that HTH is released. The function returns with E_OK.
*                    b) hardware transmit object is busy with another transmit request.
*                         The function returns with CAN_BUSY.
*                     c) A preemptive call of Can_Write has been issued, that could not be handled reentrant (i.e. a call with the same HTH).
*                        The function returns with CAN_BUSY the function is non blocking
*                     d) The hardware transmit object is busy with another transmit request for an L-PDU that has lower priority than that for the current request
*                        The transmission of the previous L-PDU is cancelled (asynchronously).
*                        The function returns with CAN_BUSY.
*                   This routine is called by:
*                   - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Hth Information which HW-transmit handle shall be used for transmit.
*                 Implicitly this is also the information about the controller to use because the Hth numbers are unique inside one hardware unit.
* @param[in]      PduInfo Pointer to SDU user memory, DLC and Identifier.
* @return         Std_ReturnType   Result of the write operation.
* @retval         E_OK   Write command has been accepted.
* @retval         E_NOT_OK  Development error occured.
* @retval         CAN_BUSY   No of TX hardware buffer available or preemtive call of Can_Write() that can't be implemented reentrant.
*
*
* @pre            Driver must be initialized and MB must be configured for Tx.
* @post           The data can be transmitted or rejected because of another data with a higher priority.
*
* @implements     Can_Write_Activity
*
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_Write( VAR(Can_HwHandleType, AUTOMATIC) Hth,
                                          P2CONST(Can_PduType, AUTOMATIC, CAN_APPL_CONST) PduInfo 
                                        )
{
    /* Variable for return status */
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (Std_ReturnType)E_NOT_OK;
#if (STD_ON == CAN_TRIGGER_TRANSMIT_EN)
        static VAR(PduInfoType, AUTOMATIC) PduInfoPtr;
        static VAR(Can_PduType, AUTOMATIC) Can_Pdu;
    #if (STD_ON == CAN_FD_MODE_ENABLE)
        static VAR(uint8, AUTOMATIC) u8Can_SduData[64] = {0U};
    #else
        static VAR(uint8, AUTOMATIC) u8Can_SduData[8] = {0U};
    #endif
#endif

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* If Can_pCurrentConfig is NULL_PTR then the driver was not initialised yet. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        /*
           (SWS_Can_00216) If development error detection for the Can module is enabled: The function Can_Write shall raise the error CAN_E_UNINIT if
                   the driver not yet initialized.
        */
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_WRITE, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /*
        *   (SWS_Can_00217) If development error detection for the Can module is enabled: The function Can_Write shall raise the error 
        *   CAN_E_PARAM_HANDLE and shall return E_NOT_OK if the parameter Hth is not a configured Hardware Transmit Handle.
        */
        if ( (Hth > CanStatic_pCurrentConfig->u32CanMaxObjectId) || (CAN_TRANSMIT != Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].eMBType))
        {
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_WRITE, CAN_E_PARAM_HANDLE);
        }
        else
        {
            /*
            *   (SWS_CAN_00219) If development error detection for the Can module is enabled: The function Can_Write shall raise the
            *       error CAN_E_PARAM_POINTER if the parameter PduInfo or the SDU pointer inside PduInfo is a null-pointer.
            */
            if ( (NULL_PTR == PduInfo) )
            {
                (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_WRITE, CAN_E_PARAM_POINTER);
            }
            else
            {
                /*
                *   (SWS_CAN_00218) The function Can_Write shall return E_NOT_OK and if development error detection for the CAN module is enabled
                *   shall raise the error CAN_E_PARAM_DATA_LENGTH ...
                */
            #if (STD_ON == CAN_FD_MODE_ENABLE)
                if (((PduInfo->length > 8U) && ((PduInfo->id & CAN_FD_ID_DESCRIPTOR) != CAN_FD_ID_DESCRIPTOR)) || \
                     (PduInfo->length > Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].u8MBPayloadLength)
                    )
            #else
                if(PduInfo->length > Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].u8MBPayloadLength)
            #endif
                {
                    (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_WRITE, CAN_E_PARAM_DATA_LENGTH);
                }
                else
                {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
                #if (STD_ON == CAN_TRIGGER_TRANSMIT_EN)
                    if ((boolean)TRUE != Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].CanTriggerTransmitEnable)
                    {
                #endif
                    #if (CAN_DEV_ERROR_DETECT == STD_ON)
                        /*
                        *   (SWS_CAN_00505) If development error detection for CanDrv is enabled: Can_Write() shall raise CAN_E_PARAM_POINTER and 
                        *       shall return E_NOT_OK if the trigger transmit API is disabled for this hardware object 
                        *       (CanTriggerTransmitEnable = FALSE) and the SDU pointer inside PduInfo is a null pointer.
                        */
                        if (NULL_PTR == PduInfo->sdu)
                        {
                            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_WRITE, CAN_E_PARAM_POINTER);
                        }
                        else
                        {
                    #endif
                            eReturnValue = Can_IPW_Write(Hth, PduInfo);
                    #if (CAN_DEV_ERROR_DETECT == STD_ON)
                        }
                    #endif
                #if (STD_ON == CAN_TRIGGER_TRANSMIT_EN)
                    }
                    else
                    {
                        /*
                        * (SWS_CAN_00503) Can_Write() shall accept a null pointer as SDU (Can_PduType.Can_SduPtrType = NULL) if the 
                        * trigger transmit API is enabled for this hardware object (CanTriggerTransmitEnable = TRUE).
                        */
                        if (NULL_PTR == PduInfo->sdu)
                        {
                            /*
                            * (SWS_CAN_00504) If the trigger transmit API is enabled for the hardware object, Can_Write() shall interpret a 
                            * null pointer as SDU (Can_PduType.Can_SduPtrType = NULL) as request for using the trigger transmit interface.
                            * If so and the hardware object is free, Can_Write() shall call CanIf_TriggerTransmit() with the maximum size
                            * of the message buffer to acquire the PDU’s data.
                            */
                            eReturnValue = Can_IPW_CheckBufferFree(Hth);
                            if ((Std_ReturnType)E_OK == eReturnValue)
                            {
                                SchM_Enter_Can_CAN_EXCLUSIVE_AREA_06();
                                PduInfoPtr.SduLength = Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].u8MBPayloadLength;
                                PduInfoPtr.SduDataPtr = u8Can_SduData;
                                SchM_Exit_Can_CAN_EXCLUSIVE_AREA_06();
                                eReturnValue = CanIf_TriggerTransmit(PduInfo->swPduHandle, &PduInfoPtr);
                                if ((Std_ReturnType)E_NOT_OK != eReturnValue)
                                {
                                    SchM_Enter_Can_CAN_EXCLUSIVE_AREA_06();
                                    Can_Pdu.id = PduInfo->id;
                                    Can_Pdu.swPduHandle = PduInfo->swPduHandle;
                                    Can_Pdu.length = (uint8)PduInfoPtr.SduLength;
                                    Can_Pdu.sdu = PduInfoPtr.SduDataPtr;
                                    SchM_Exit_Can_CAN_EXCLUSIVE_AREA_06();
                                    eReturnValue = Can_IPW_Write(Hth, &Can_Pdu);
                                }
                            }
                            else
                            {
                                eReturnValue = CAN_BUSY;
                            }
                        }
                        else
                        {
                            eReturnValue = Can_IPW_Write(Hth, PduInfo);
                        }
                    }
                    #endif
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                }
            }
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
    return eReturnValue;
}

/*================================================================================================*/
/*================================================================================================*/

#if (CAN_TXPOLL_SUPPORTED == STD_ON)
    

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionWrite();
    }
}


#ifdef CAN_MAINFUNCTION_MULTIPLE_WRITE
#if (CAN_MAINFUNCTION_MULTIPLE_WRITE==STD_ON)

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_0
/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_0(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(0U);
    }
}
#endif
#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_1
/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_1(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(1U);
    }
}
#endif
#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_2
/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7  */
FUNC(void, CAN_CODE) Can_MainFunction_Write_2(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(2U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_3


/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_3(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(3U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_4

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_4(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(4U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_5

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_5(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(5U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_6

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_6(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(6U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_7

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_7(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(7U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_8

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_8(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(8U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_9

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_9( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(9U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_10

/**
* @brief          Function called at fixed cyclic time. SID is 0x01.
* @details        Service for performs the polling of TX confirmation and TX cancellation confirmation when CAN_TX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Send the data from that MB that is configured for Tx.
*
* @implements     Can_MainFunction_Write_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Write_10( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Tx MB statuses. */
        Can_IPW_MainFunctionMultipleWritePoll(10U);
    }
}
#endif
#endif /*CAN'_MAINFUNCTION_MULTIPLE_WRITE==STD_ON*/
#endif /*ifdef (CAN'_MAINFUNCTION_MULTIPLE_WRITE)*/
#endif /*(CAN_TXPOLL_SUPPORTED == STD_ON)   */


/*================================================================================================*/

#if (CAN_RXPOLL_SUPPORTED  == STD_ON)
   
/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionRead();
    }
}

#ifdef CAN_MAINFUNCTION_MULTIPLE_READ
#if (CAN_MAINFUNCTION_MULTIPLE_READ == STD_ON)
#ifdef CAN_MAINFUNCTION_PERIOD_READ_0
/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_0( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(0U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_1
/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_1( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(1U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_2

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_2( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(2U);
    }
}
#endif


#ifdef CAN_MAINFUNCTION_PERIOD_READ_3
/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_3( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(3U);
    }
}
#endif


#ifdef CAN_MAINFUNCTION_PERIOD_READ_4

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_4( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(4U);
    }
}
#endif


#ifdef CAN_MAINFUNCTION_PERIOD_READ_5

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_5( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(5U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_6
/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_6( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(6U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_7 

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_7( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(7U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_8

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_8( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(8U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_9

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_9( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(9U);
    }
}
#endif

#ifdef CAN_MAINFUNCTION_PERIOD_READ_10

/**
* @brief          Function called at fixed cyclic time.  SID is 0x08.
* @details        Service for performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Receive the data from that MB that is configured for Rx.
*
* @implements     Can_MainFunction_Read_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Read_10( void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Poll all controllers for Rx MB statuses. */
        Can_IPW_MainFunctionMultipleReadPoll(10U);
    }
}
#endif /*ifdef CAN'_MAINFUNCTION_PERIOD_READ_10*/
#endif /*(CAN_MAINFUNCTION_MULTIPLE_READ == STD_ON)*/
#endif /* ifdef (CAN_MAINFUNCTION_MULTIPLE_READ)*/
#endif /* (CAN_RXPOLL_SUPPORTED == STD_ON) */


/*================================================================================================*/

#if (CAN_BUSOFFPOLL_SUPPORTED == STD_ON)
/**
* @brief          Function called at fixed cyclic time. SID is 0x09.
* @details        Service for performs the polling of BusOff events that are configured statically as 'to be polled'.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Handle the Busoff event.
*
* @implements     Can_MainFunction_BusOff_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_BusOff( void)
{
    /* Variable for indexing the controllers */
    VAR(uint8, AUTOMATIC) can_controller = 0U;

    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Loop through all Can controllers configured based CanControllerId parameter. */
        for ( can_controller = (uint8)0U; can_controller < (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured; can_controller++)
        {
            /*
               (SWS_Can_00109) The function Can_MainFunction_BusOff shall perform the polling of bus-off events that are configured statically as 'to be polled'.
            */
            if ( (CAN_NULL_OFFSET !=(CanStatic_pControlerDescriptors[can_controller].u8ControllerOffset))  &&
                 ((CAN_CONTROLLERCONFIG_BOPOL_EN_U32 & (uint32)(CanStatic_pControlerDescriptors[can_controller].u32Options)) != (uint32)0x0U)
               )
            {
                /* Check for BusOff status. */
                if ( (Std_ReturnType)E_OK == Can_IPW_CheckBusOff(can_controller) )
                {
                    /* Process BusOff event. */
                    if ( (Std_ReturnType)E_OK == (Std_ReturnType)Can_IPW_SetControllerMode( can_controller,  &(Can_pCurrentConfig->ControlerDescriptors[can_controller]), CAN_CS_STOPPED,(boolean)FALSE) )
                    {
                        Can_IPW_ProcessBusOff(can_controller);
                        CanIf_ControllerBusOff(can_controller);
                    }

                }
            }
        }
    }
}

#endif /* (CAN_BUSOFFPOLL_SUPPORTED == STD_ON) */

/*================================================================================================*/

/*================================================================================================*/
#ifdef CAN_WAKEUPPOLL_SUPPORTED
    #if (CAN_WAKEUPPOLL_SUPPORTED  == STD_ON)
/**
* @brief          Function called at fixed cyclic time. SIDis 0x0A.
* @details        Service for performs performs the polling of CAN status register flags to detect Wakeup event of CAN Controller state
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Handle the wakeup event of Can Controller state.
*
* @implements     Can_MainFunction_Wakeup_Activity
* @api
*/
FUNC(void, CAN_CODE) Can_MainFunction_Wakeup(void)
{
    /* Variable for indexing the controllers */
    VAR(uint8, AUTOMATIC) can_controller = 0U;

    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Loop through all Can controllers configured based CanControllerId parameter. */
            for ( can_controller = (uint8)0U; can_controller < (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured; can_controller++)
            {
                /*
                   (SWS_Can_00112) The function Can_MainFunction_Wakeup shaal perform the polling of wake-up events that are configured statically as 'to be polled'.
                */
                if ( (CAN_NULL_OFFSET !=(CanStatic_pControlerDescriptors[can_controller].u8ControllerOffset))  &&
                     ((CAN_CONTCONFIG_WAKUPINT_EN_U32 & (uint32)(CanStatic_pControlerDescriptors[can_controller].u32Options)) == (uint32)0x0U)
                   )
                {
                    if ( (Std_ReturnType)E_OK == Can_IPW_CheckWakeup(can_controller))
                    {
                        Can_IPW_ProcessWakeup(can_controller);
                    }
                }
            }
    }
}
#endif /* (CAN_WAKEUPPOLL_SUPPORTED  == STD_ON) */
#endif
/*================================================================================================*/

/*================================================================================================*/
/**
* @brief          Function called at fixed cyclic time. SIDis 0x0C.
* @details        Service for performs performs the polling of CAN status register flags to detect transition of CAN Controller state
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
* @post           Handle the transition of Can Controller state.
*
* @implements     Can_MainFunction_Mode_Activity
* @api
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_MainFunction_Mode(void)
{
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT != Can_eDriverStatus )
    {
        /* Check for main function mode. */
        /* @violates @ref Can_c_REF_10 */
        Can_IPW_MainFunctionMode();
    }
}

/*================================================================================================*/
#ifdef CAN_ENABLE_WAKEUP_SUPPORT
    #if (CAN_ENABLE_WAKEUP_SUPPORT == STD_ON)
/**
* @brief          Process check of WakeUp condition. SID is 0x0B.
* @details        This service shall evaluate the WakeupSource parameter to get the information,
*                 which dedicate wakeup source needs to be checked, either a CAN transceiver or controller device.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      controller Can controller ID - based on configuration order list (CanControllerId).
* @return         Std_ReturnType Result of the wakeup verification.
* @retval         E_OK  Wakeup was detected for the given controller.
* @retval         E_NOT_OK  No wakeup was detected for the given controller.
*
*
* @pre            Driver must be initialized.
* @post           Return the Wakeup event occurence.
*
* @implements     Can_CheckWakeup_Activity
* Compiler_Warning: This warning is thrown because it doesn't exist hardware support for Wakeup, and parameter "controller" it is not used.
* @api
*
*/

FUNC(Std_ReturnType, CAN_CODE) Can_CheckWakeup( VAR(uint8, AUTOMATIC) controller)
{
    /* E_NOT_OK is defined as (uint8)0x01 */
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (Std_ReturnType)E_NOT_OK;
    VAR(uint8, AUTOMATIC) u8HwOffset = 0U;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* Test whether the driver is already initialised. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        /*
           (SWS_Can_00362) If development error detection for the Can module is enabled: The function Can_CheckWakeup shall raise
                   the error CAN_E_UNINIT if the driver is not yet initialized.
        */
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_CBK_CHECK_WAKEUP, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* Get the hardware offset for this controller. Note that hardware offset may not be the same with the controller index from the 'Can_ControlerDescriptorType' structure. */ 
        u8HwOffset = CanStatic_pControlerDescriptors[controller].u8ControllerOffset;
        /*
           (SWS_Can_00363) If development error detection for the Can module is enabled: The function Can_CheckWakeup shall raise the
                   error CAN_E_PARAM_CONTROLLER if the parameter Controller is out of range.
        */
        if ( (controller >= (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[controller].u8ControllerOffset))
           )
        {
            
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_CBK_CHECK_WAKEUP, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */

            if (CAN_CS_SLEEP == Can_IPW_GetControllerMode(controller))
            {
                if((Std_ReturnType)E_OK == Can_IPW_CheckWakeup(controller))
                {
                    EcuM_SetWakeupEvent(CanStatic_pControlerDescriptors[controller].u32ECUMWakeupSourceId);
                    /* Controller is in WakeUp state. */
                    eReturnValue = (Std_ReturnType)E_OK;
                }
            }
            else
            {
                eReturnValue = (Std_ReturnType)E_NOT_OK;
            }
    #if (CAN_DEV_ERROR_DETECT == STD_ON)
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */

    return (eReturnValue);
}
#endif /* (CAN_ENABLE_WAKEUP_SUPPORT == STD_ON) */
#endif
/*================================================================================================*/
#if ((CAN_API_ENABLE_ABORT_MB == STD_ON))
/**
* @brief          Process a message buffer abort
* @details        This function write a abort code (b'1001) to MBCS[CODE] field of the MB.
*                This routine is called by:
*                - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      Hth - HW-transmit handler
*
*
* @pre            Driver must be initialized and the current MB transmission should be ready for transmit.
*
*
* @note           Not AUTOSAR required. This is user implementation.
* @implements     Can_AbortMb_Activity
* @api
*
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(void, CAN_CODE) Can_AbortMb( VAR(Can_HwHandleType, AUTOMATIC) Hth )
{
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    VAR(uint8, AUTOMATIC) u8CtrlId = 0U; 
    /* Test if the driver is already initialised. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_ABORT_MB, (uint8)CAN_E_UNINIT);
    }
    else
    {
        if ( (Hth > CanStatic_pCurrentConfig->u32CanMaxObjectId) || (CAN_TRANSMIT != Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].eMBType))
        {
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_ABORT_MB, CAN_E_PARAM_HANDLE);
        }
        else
        {
            u8CtrlId = Can_pCurrentConfig->MBConfigContainer.pMessageBufferConfigsPtr[Hth].u8ControllerId;
            if (CAN_NULL_OFFSET == CanStatic_pControlerDescriptors[u8CtrlId].u8ControllerOffset)
            {
                (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_ABORT_MB, CAN_E_PARAM_CONTROLLER);
            }
            else
            {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
                Can_IPW_AbortMb(Hth);
#if (CAN_DEV_ERROR_DETECT == STD_ON)
            }
        }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
}
#endif /* ((CAN_API_ENABLE_ABORT_MB == STD_ON)) */

/*================================================================================================*/

#if (CAN_DUAL_CLOCK_MODE == STD_ON)
/**
* @brief          Process a transition from one clock source to another.
* @details        This function is configuring Can controllers to run on the same baudrate, but having a different MCU source clock.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
* @param[in]      can_controller controller ID
* @param[in]      can_clk_mode clock mode selection
* @return         Std_ReturnType Result of the clock switch operation.
* @retval         E_OK  Switch clock operation was ok.
* @retval         E_NOT_OK  Switch clock operation was not ok.
*
*
* @pre            Driver must be initialized and all the controllers must be in Stop state.
*
*
* @note           Not AUTOSAR required. This is user implementation.
* @implements     Can_SetClockMode_Activity
* @api
*
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_SetClockMode( VAR(uint8, AUTOMATIC) can_controller, VAR(Can_ClockModeType, AUTOMATIC) can_clk_mode)
{
    /* Returns the result of CAN clock mode */
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (uint8)E_NOT_OK;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* Test if the driver is already initialised. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SETCLOCKMODE, (uint8)CAN_E_UNINIT);
    }
    else
    {
        if ( (can_controller >= (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[can_controller].u8ControllerOffset)) 
           )
        {
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SETCLOCKMODE, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */

            if (CAN_CS_STOPPED == Can_IPW_GetControllerMode(can_controller))
            {
                eReturnValue = Can_IPW_SetClockMode( can_controller, can_clk_mode);
            }
            
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        
       }
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */

    return (eReturnValue);
}

#endif /* CAN_DUAL_CLOCK_MODE == STD_ON */
#ifdef CAN_SUPPORT_MRAF_EVENT
  #if (CAN_SUPPORT_MRAF_EVENT == STD_ON)
    #if (CAN_MRAFPOLL_SUPPORTED == STD_ON)
/**
* @brief          Do check Message RAM Access Failure event.
* @details        This is polling function to check whether Message RAM Access Failure.
*                 This routine is called by:
*                 - CanIf or an upper layer according to Autosar requirements.
*
*
* @pre            Driver must be initialized.
*
* @implements     Can_MainFunction_CheckMRAF_Activity
* @api
*/
FUNC(void, CAN_CODE) Can_MainFunction_CheckMRAF( void)
{
    #if (CAN_DEV_ERROR_DETECT == STD_ON)
        if ( CAN_UNINIT != Can_eDriverStatus )
        {
    #endif 
            Can_IPW_MainFunction_CheckMRAF();
    #if (CAN_DEV_ERROR_DETECT == STD_ON)
        }
    #endif 
}
    #endif
  #endif /* (CAN_SUPPORT_MRAF_EVENT == STD_OFF) */
#endif /* defined(CAN_SUPPORT_MRAF_EVENT) */

/*================================================================================================*/
#if (CAN_SET_BAUDRATE_API == STD_ON)
/**
* @brief         This function set baudrate 
* @details       This routine is called by an upper layer.
* 
* @param[in]     Controller controller ID
* @param[in]     BaudRateConfigID baudrateID selection
* 
* @return       
* @retval        E_OK  Switch baudrate operation was ok.
* @retval        E_NOT_OK  Switch baudrate operation was not ok.
* 
* @pre           Driver must be initialized.
* @implements    Can_SetBaudrate_Activity
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_SetBaudrate( VAR(uint8, AUTOMATIC) Controller, VAR(uint16, AUTOMATIC) BaudRateConfigID)
{
    /* Returns the result of CAN set baudrate */
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (Std_ReturnType)E_NOT_OK;
    VAR(uint8, AUTOMATIC) u8BaudrateIndex = 0U;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    /* If Can_eDriverStatus is CAN_UNINIT then the driver was not initialised yet. */
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        /*
           (SWS_CAN_00492) If development error detection for the Can module is enabled:
           The function Can_SetBaudrate shall raise the error CAN_E_UNINIT and return E_NOT_OK if the driver is not yet initialized.
        */
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_BAUDRATE, (uint8)CAN_E_UNINIT);
    }
    else
    {
        /* The Controller ID must be within range and the selected controller must be configured for use in the config tool. */
        if ( (Controller >= (uint8)CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[Controller].u8ControllerOffset))
           )
        {
            /*
               (SWS_CAN_00494) If development error detection for the Can module is enabled
                the function Can_SetBaudrate shall raise the error CAN_E_PARAM_CONTROLLER and return E_NOT_OK if the parameter Controller is out of range.
            */
                
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_BAUDRATE, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
            if (CAN_CS_STOPPED != Can_IPW_GetControllerMode(Controller))
            {
                /*
                    If the call of Can_SetBaudrate will cause a re-initialization of the CAN
                    Controller the CAN controller must be in state STOPPED when this function is called.
                    (SWS_Can_00256) If the call of Can_SetBaudrate() would cause a re-initialization
                        of the CAN Controller and the CAN Controller is not in state STOPPED, it shall return E_NOT_OK.
                */
                eReturnValue = (uint8)E_NOT_OK;
            }
            else
            {
                /* Check the Baudrate */
                for ( u8BaudrateIndex = 0U; u8BaudrateIndex < Can_pControlerDescriptors[Controller].u8MaxBaudRateCount; u8BaudrateIndex++)
                {
                    /* Check the Baudrate */
                    if (BaudRateConfigID == (uint16)(Can_pControlerDescriptors[Controller].pControllerBaudrateConfigsPtr[u8BaudrateIndex]. u16ControllerBaudRateConfigID))
                    {
                        /* Baudrate is Valid */
                        eReturnValue = (uint8)E_OK;
                        break;
                    }
                }
                
                if ( (uint8)E_OK != eReturnValue )
                {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                    /*
                        (SWS_CAN_00493) If development error detection for the Can module is enabled:
                            The function Can_SetBaudrate shall raise the error CAN_E_PARAM_BAUDRATE and return E_NOT_OK if the parameter BaudRateConfigID has an invalid value.
                    */

                    (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_BAUDRATE, (uint8)CAN_E_PARAM_BAUDRATE);
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
                }
                else
                {
                    /*
                        (SWS_Can_00256) If the call of Can_SetBaudrate() would cause a re-initialization
                           of the CAN Controller and the CAN Controller is not in state STOPPED, it shall return E_NOT_OK.
                        (SWS_Can_00260) If re-initialization is necessary the function Can_SetBaudrate shall maintain the CAN controller in the state STOPPED.
                        (SWS_Can_00422) If re-initialization is necessary the function Can_SetBaudrate
                            shall ensure that any settings that will cause the CAN controller to participate in the network are not set.
                    */
                    /* @violates @ref Can_c_REF_9 */
                    eReturnValue = Can_IPW_SetBaudrate(Controller, BaudRateConfigID);
                }
            }
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        }
   }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
    return (eReturnValue);
}
#endif

#ifdef ERR_IPV_MCAN_0004
    #if (STD_ON == ERR_IPV_MCAN_0004)
/**
* @brief            This service obtains the communication state of the CAN controller
* @details          This service obtains the communication state of the CAN controller
*
* @param[in]        Controller    CAN controller for which is requested for communication states.
* @param[out]       ControllerCommunicationStatePtr Pointer to a memory location, where the communication state of 
*                       the CAN controller will be stored.
*
* @return           Std_ReturnType   Result of the GetControllerCommunicationState operation.
* @retval           E_OK : Communication state request has been accepted.
* @retval           E_NOT_OK : Communication state request has not been accepted.
*
* @pre              Driver must be initialized.
*/
/* @violates @ref Can_c_REF_7 MISRA 2012 Advisory Rule 8.7 */
FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerCommunicationState(uint8 Controller, Can_ControllerCommunicationStateType* ControllerCommunicationStatePtr)
{
    VAR(Std_ReturnType, AUTOMATIC) eRetVal = (Std_ReturnType)E_NOT_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    if ( CAN_UNINIT == Can_eDriverStatus )
    {
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_COMMUNICATION_STATE, (uint8)CAN_E_UNINIT);
    }
    else
    {
        if ( (Controller >= CanStatic_pCurrentConfig->u8ControllersConfigured) ||
             (CAN_NULL_OFFSET == (CanStatic_pControlerDescriptors[Controller].u8ControllerOffset))
           )
        {
            (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_COMMUNICATION_STATE, (uint8)CAN_E_PARAM_CONTROLLER);
        }
        else
        {
            if (NULL_PTR == ControllerCommunicationStatePtr)
            {
                (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_GET_CONTROLLER_COMMUNICATION_STATE, (uint8)CAN_E_PARAM_POINTER);
            }
            else
            {
#endif
                switch(Can_IPW_GetControllerCommunicationState(Controller))
                {
                    case 0U:
                    {
                        *ControllerCommunicationStatePtr = CAN_SYNCHRONIZING;
                        eRetVal = (Std_ReturnType)E_OK;
                        break;
                    }
                    case 1U:
                    {
                        *ControllerCommunicationStatePtr = CAN_IDLE;
                        eRetVal = (Std_ReturnType)E_OK;
                        break;
                    }
                    case 2U:
                    {
                        *ControllerCommunicationStatePtr = CAN_RECEIVER;
                        eRetVal = (Std_ReturnType)E_OK;
                        break;
                    }
                    case 3U:
                    {
                        *ControllerCommunicationStatePtr = CAN_TRANSMITTER;
                        eRetVal = (Std_ReturnType)E_OK;
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
#if (CAN_DEV_ERROR_DETECT == STD_ON)
            }
        }
    }
#endif
    return eRetVal;
}
    #endif
#endif

/*================================================================================================*/
/* [SWS_CAN_00495] Can_SetIcomConfiguration() shall be pre compile time configurable ON/OFF by the configuration parameter CAN'_PUBLIC_ICOM_SUPPORT. */
#if(CAN_PUBLIC_ICOM_SUPPORT == STD_ON)
/**
* @brief          Set controller into Pretended Networking mode with the ConfigurationID valid.
* @details        This function is API which support the Pretended Networking featrue. After this function is called, it will configure for controller with information in the configurationIDs (corresponding with ID valid )
*                 This routine is called by:
*                  - Can_SetIcomConfiguration() from Can.c file.
*
* @param[in]      Controller    CAN controller for which the init shall be done. Based on configuration order list (CanControllerId).
* @param[in]      ConfigurationId the ID of CanIcomConfig
*
* @return        Std_ReturnType Result of the clock switch operation.
* @retval        E_OK  Configure was ok.
* @retval        E_NOT_OK  Configure was not ok.
*
* @pre            Driver must be initialized and all the controllers must be in Stop state.
*
* @note           At the momen, Just have Calypso to support this feature, base on ASR421.
* @implements    Can_SetIcomConfiguration_Activity
*/
FUNC(Std_ReturnType, CAN_CODE) Can_SetIcomConfiguration( VAR(uint8, AUTOMATIC) u8Controller, 
                                                         VAR(IcomConfigIdType, AUTOMATIC) u8ConfigurationId 
                                                       )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnValue = (Std_ReturnType)E_NOT_OK;
    VAR(uint8, AUTOMATIC) u8ConfigIcomIndex = 0U;
    
    if ((boolean)TRUE == CanStatic_pControlerDescriptors[u8Controller].bPnSupported)
    {
        /* Check status of controller. only configure for PNET mode when controller into Freeze  mode. */
        /* [SWS_CAN_00471] Pretended Networking shall be deactivated (i.e. CanDrv shall behave as when it is configured without Pretended Networking support) by calling Can_SetIcomConfiguration() with a configuration ID = 0. */
        if (0U == u8ConfigurationId)
        {
            eReturnValue = (Std_ReturnType)Can_IPW_DeactivateIcomConfiguration(u8Controller);
        }
        /* [SWS_CAN_00462] Pretended Networking shall be activated by calling Can_SetIcomConfiguration() with a configuration ID not set to 0. */
        /* [SWS_CAN_00481]If the requested ConfigurationId is not 0, the function Can_SetIcomConfiguration() shall reconfigure the controller with the ICOM configuration parameters of the CanIcomConfig container 
        which CanIcomConfigId matches the requested ConfigurationId. 
        */
        else 
        {
            for ( u8ConfigIcomIndex = 0U; u8ConfigIcomIndex < (CanStatic_pCurrentConfig->u8NumCanIcomConfigs); u8ConfigIcomIndex++)
            {
                /* Check the Baudrate */
                if (u8ConfigurationId == (uint8)(CanStatic_pCurrentConfig->pCanIcomConfigs[u8ConfigIcomIndex].u8CanIcomConfigId))
                {
                    /* ConfigID is Valid */
                    eReturnValue = (Std_ReturnType)Can_IPW_SetIcomConfiguration( u8Controller, u8ConfigIcomIndex);
                    break;
                }
            }
    #if (CAN_DEV_ERROR_DETECT == STD_ON)
            if((Std_ReturnType)E_NOT_OK == eReturnValue)
            {
                (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_ICOM_CONFIG, (uint8)CAN_E_ICOM_CONFIG_INVALID);
            }
    #endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
        }
        /* Refer to [SWS_CAN_00467] and [SWS_CAN_00474] */
        if((Std_ReturnType)E_OK == eReturnValue)
        {
            CanIf_CurrentIcomConfiguration( u8Controller, u8ConfigurationId, ICOM_SWITCH_E_OK);
        }
        else
        {
            CanIf_CurrentIcomConfiguration( u8Controller, u8ConfigurationId, ICOM_SWITCH_E_FAILED);
        }
    }
#if (CAN_DEV_ERROR_DETECT == STD_ON)
    else
    {
        (void)Det_ReportError( (uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, (uint8)CAN_SID_SET_ICOM_CONFIG, (uint8)CAN_E_INVALID_CONTROLLER);
    }
#endif /* (CAN_DEV_ERROR_DETECT == STD_ON) */
    return (eReturnValue);
}
#endif /* (CAN_PUBLIC_ICOM_SUPPORT == STD_OFF) */

#define CAN_STOP_SEC_CODE
/* @violates @ref Can_c_REF_1 This violation is not fixed since the inclusion of Can_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Can_c_REF_6 Can_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR*/
#include "Can_MemMap.h"


#ifdef __cplusplus
}
#endif


/** @} */
