/*!
* @file     Can.c
*
* @version  1.0.0
*
* @brief    AUTOSAR CAN Driver source file
 *           
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_15-Nov-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

#ifdef __cplusplus
extern "C"{
#endif

#include "Can.h"
#include "CanIf_Cbk.h"
#include "Std_Types.h"

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
#include "Det.h"
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup CAN_Driver
  * @brief CAN driver modules
  @{
*/

/** @defgroup CAN_Macros
  @{
*/
/*******************************************************************************
                    VENDOR ID & AUTOSAR VERSION INFO
*******************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define CAN_VENDOR_ID                       0x00C1U
/** Module ID of this module, as defined in the BSW Module List. */
#define CAN_MODULE_ID                       0x0050U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CAN_AR_RELEASE_MAJOR_VERSION        0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CAN_AR_RELEASE_MINOR_VERSION        0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CAN_AR_RELEASE_REVISION_VERSION     0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CAN_SW_MAJOR_VERSION                0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CAN_SW_MINOR_VERSION                0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CAN_SW_PATCH_VERSION                0x00U
/**@} end of group CAN_Macros */
/*******************************************************************************
                                VERSION CHECK
*******************************************************************************/
/* Make sure the vendor id is the same between Can.c and Can.h */
#if (CAN_VENDOR_ID != CAN_H_VENDOR_ID)
    #error "Vendor id mismatch between Can.c and Can.h"
#endif
/* Make sure the module id is the same between Can.c and Can.h */
#if (CAN_MODULE_ID != CAN_H_MODULE_ID)
    #error "Module id mismatch between Can.c and Can.h"
#endif
/* Make sure the AUTOSAR major version number is the same between Can.c and Can.h */
#if (CAN_AR_RELEASE_MAJOR_VERSION != CAN_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR major version number mismatch between Can.c and Can.h"
#endif
/* Make sure the AUTOSAR minor version number is the same between Can.c and Can.h */
#if (CAN_AR_RELEASE_MINOR_VERSION != CAN_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR minor version number mismatch between Can.c and Can.h"
#endif
/* Make sure the AUTOSAR revision version number is the same between Can.c and Can.h */
#if (CAN_AR_RELEASE_REVISION_VERSION != CAN_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR revision version number mismatch between Can.c and Can.h"
#endif
/* Make sure the software major version number is the same between Can.c and Can.h */
#if (CAN_SW_MAJOR_VERSION != CAN_H_SW_MAJOR_VERSION)
    #error "Software major version number mismatch between Can.c and Can.h"
#endif
/* Make sure the software minor version number is the same between Can.c and Can.h */
#if (CAN_SW_MINOR_VERSION != CAN_H_SW_MINOR_VERSION)
    #error "Software minor version number mismatch between Can.c and Can.h"
#endif
/* Make sure the software patch version number is the same between Can.c and Can.h */
#if (CAN_SW_PATCH_VERSION != CAN_H_SW_PATCH_VERSION)
    #error "Software patch version number mismatch between Can.c and Can.h"
#endif

#ifdef ENABLE_INTERMODULE_MCAL_CHECK
    /* Make sure the AUTOSAR major version number is the same between Can.c and CanIf_Cbk.h */
    #if (CAN_AR_RELEASE_MAJOR_VERSION != CANIF_CBK_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR major version number mismatch between Can.c and CanIf_Cbk.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Can.c and CanIf_Cbk.h */
    #if (CAN_AR_RELEASE_MINOR_VERSION != CANIF_CBK_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR minor version number mismatch between Can.c and CanIf_Cbk.h"
    #endif
    /* Make sure the AUTOSAR major version number is the same between Can.c and Std_Types.h */
    #if (CAN_AR_RELEASE_MAJOR_VERSION != STD_TYPES_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR major version number mismatch between Can.c and Std_Types.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Can.c and Std_Types.h */
    #if (CAN_AR_RELEASE_MINOR_VERSION != STD_TYPES_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR minor version number mismatch between Can.c and Std_Types.h"
    #endif

    #if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
        /* Make sure the AUTOSAR major version number is the same between Can.c and Det.h */
        #if (CAN_AR_RELEASE_MAJOR_VERSION != DET_H_AR_RELEASE_MAJOR_VERSION)
            #error "AUTOSAR major version number mismatch between Can.c and Det.h"
        #endif
        /* Make sure the AUTOSAR minor version number is the same between Can.c and Det.h */
        #if (CAN_AR_RELEASE_MINOR_VERSION != DET_H_AR_RELEASE_MINOR_VERSION)
            #error "AUTOSAR minor version number mismatch between Can.c and Det.h"
        #endif
    #endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
#endif /* ENABLE_INTERMODULE_MCAL_CHECK */

/*******************************************************************************
                            GLOBAL VARIABLES
*******************************************************************************/
/** @defgroup CAN_Variable
  @{
*/
#define CAN_START_SEC_VAR_INIT_UNSPECIFIED
#include "Can_MemMap.h"

/** Pointer to CAN driver static configuration */
P2CONST(Can_StaticConfigType, CAN_VAR, CAN_APPL_CONST) g_canStaticConfigPtr = &g_canStaticConfig;

/** Pointer to CAN driver configuration */
P2CONST(Can_ConfigType, CAN_VAR, CAN_APPL_CONST) g_canConfigPtr = NULL_PTR;

/** Pointer to CAN controllers information */
P2CONST(Can_ControllerInfoType, CAN_VAR, CAN_APPL_CONST) g_canControllersInfoPtr = NULL_PTR;

/** Pointer to CAN controller configurations */
P2CONST(Can_ControllerStaticConfigType, CAN_VAR, CAN_APPL_CONST) g_canControllerStaticConfigPtr = NULL_PTR;

/** CAN driver status
*   CAN_UNINIT: The CAN driver was not initialized yet.
*   CAN_READY:  The CAN driver was initialized successfully.
*/
VAR(Can_DriverStatusType, CAN_VAR) g_canDriverStatus = CAN_UNINIT;

#define CAN_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Can_MemMap.h"
/**@} end of group CAN_Variable */
/*******************************************************************************
                        LOCAL FUNCTION DECLARATIONS
*******************************************************************************/
/** @defgroup CAN_Fuctions
  @{
*/
#define CAN_START_SEC_CODE
#include "Can_MemMap.h"

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
LOCAL_INLINE FUNC(Std_ReturnType, CAN_CODE) Can_CheckDriverInitialized(
    VAR(uint8, AUTOMATIC) ApiId);

FUNC(Std_ReturnType, CAN_CODE) Can_CheckControllerId(
    VAR(uint8, AUTOMATIC) ApiId,
    VAR(uint8, AUTOMATIC) Controller);

LOCAL_INLINE FUNC(Std_ReturnType, CAN_CODE) Can_CheckNullPointer(
     CONST(uint8, AUTOMATIC) ApiId,
     P2CONST(void, AUTOMATIC, CAN_APPL_CONST) Ptr);

LOCAL_INLINE FUNC(Std_ReturnType, CAN_CODE) Can_CheckHth(
    VAR(uint8, AUTOMATIC) ApiId,
    VAR(Can_HwHandleType, AUTOMATIC) Hth);
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */

#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

/*******************************************************************************
                            GLOBAL FUNCTIONS
*******************************************************************************/
#define CAN_START_SEC_CODE
#include "Can_MemMap.h"

/*!
* @brief    Initialize the CAN driver
*
* @param[in]    Config Pointer to driver configuration
*/
FUNC(void, CAN_CODE) Can_Init(P2CONST(Can_ConfigType, AUTOMATIC, CAN_APPL_CONST) Config)
{
    VAR(uint8, AUTOMATIC) index = 0U;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    /* Check if the CAN driver was already initialized */
    if (CAN_UNINIT == g_canDriverStatus)
    {
        if (NULL_PTR != Config)
        {
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */

            g_canConfigPtr = Config;

            g_canStaticConfigPtr = &g_canStaticConfig;
            g_canControllersInfoPtr = g_canConfigPtr->controllersInfoPtr;
            g_canControllerStaticConfigPtr = g_canStaticConfigPtr->controllerStaticConfigPtr;
            Can_Hw_InitVariables();

            /* Loop through all configured CAN controllers */
            index = 0U;
            while (index < (uint8)g_canStaticConfigPtr->controllersConfigured)
            {
                /* Skip controllers that are disabled */
                if (CAN_CONTROLLER_INVALID != (g_canControllerStaticConfigPtr[index].controllerOffset))
                {
                    (void)Can_Hw_InitController(index);
                }
                else
                {
                    /* No operation */
                }
                index++;
            }
            g_canDriverStatus = CAN_READY;

    #if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
        }
        else
        {
            (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                                  (uint8)CAN_SID_INIT, (uint8)CAN_E_PARAM_POINTER);
        }
    }
    else
    {
        /* CAN driver was already initialized, report error. */
        (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                              (uint8)CAN_SID_INIT, (uint8)CAN_E_TRANSITION);
    }
    #endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
}

/*!
 * @brief    De-initializes the CAN driver
 */
FUNC(void, CAN_CODE) Can_DeInit(void)
{
    VAR(uint8, AUTOMATIC) index = 0U;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    VAR(boolean, AUTOMATIC) controllerBusy = (boolean)FALSE;

    if (CAN_READY == g_canDriverStatus)
    {
        /* Loop through all configured CAN controllers */
        index = 0U;
        while (index < (uint8)g_canStaticConfigPtr->controllersConfigured)
        {
            /* Report DET error if any CAN controller is in STARTED state */
            if ((CAN_CONTROLLER_INVALID != (g_canControllerStaticConfigPtr[index].controllerOffset)) &&
                (CAN_CS_STARTED == g_canControllerStatus[index].controllerState))
            {
                (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                                      (uint8)CAN_SID_DEINIT, (uint8)CAN_E_TRANSITION);
                controllerBusy =  (boolean)TRUE;
                break;
            }
            else
            {
                /* Do Nothing */
            }
            index++;
        }

        /* None of the controllers are busy */
        if ((boolean)TRUE != controllerBusy)
        {
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */

            /* Loop through all configured CAN controllers */
            index = 0U;
            while (index < (uint8)g_canStaticConfigPtr->controllersConfigured)
            {
                /* Deinit the controller */
                if (CAN_CONTROLLER_INVALID != (g_canControllerStaticConfigPtr[index].controllerOffset))
                {
                    Can_Hw_DeInitController(index);
                }
                else
                {
                    /* Do Nothing */
                }
                index++;
            }
            g_canDriverStatus = CAN_UNINIT;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
        }
        else
        {
            /* Do Nothing */
        }
    }
    else
    {
        (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                              (uint8)CAN_SID_DEINIT, (uint8)CAN_E_TRANSITION);
    }
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
}

/*!
* @brief    Change the CAN controller state
* @details  This function performs software triggered state transitions of the
*           CAN controller state machine.
*
* @param[in]    Controller  CAN controller for which the status shall be changed
* @param[in]    Transition  Transition value to request new CAN controller state
*
* @retval   E_OK:       Request accepted
* @retval   E_NOT_OK:   Request not accepted
*/
FUNC(Std_ReturnType, CAN_CODE) Can_SetControllerMode(
    VAR(uint8, AUTOMATIC) Controller,
    VAR(Can_ControllerStateType, AUTOMATIC) Transition)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_SET_CONTROLLER_MODE))
    {
        /* nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckControllerId((uint8)CAN_SID_SET_CONTROLLER_MODE, Controller))
    {
        /* nothing */
    }
    else
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        result = Can_Hw_SetControllerMode(Controller,Transition, (boolean)TRUE);
    }
    return result;
}

/*!
* @brief    Reports the current status of the CAN controller
*
* @param[in]    Controller          CAN controller for which the status shall be requested
* @param[out]   ControllerModePtr   Pointer to 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
*/
FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerMode(
    VAR(uint8, AUTOMATIC) Controller,
    P2VAR(Can_ControllerStateType, AUTOMATIC, CAN_APPL_DATA) ControllerModePtr)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_GET_CONTROLLER_MODE))
    {
        /* nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckControllerId((uint8)CAN_SID_GET_CONTROLLER_MODE, Controller))
    {
        /* nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckNullPointer((uint8)CAN_SID_GET_CONTROLLER_MODE, ControllerModePtr))
    {
        /* nothing */
    }
    else
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        *ControllerModePtr = g_canControllerStatus[Controller].controllerState;
        result = (Std_ReturnType)E_OK;
    }
    
    return result;
}

/*!
* @brief    Transmit a CAN frame
*
* @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, data length and identifier.
*
* @retval   E_OK:       Write command has been accepted
* @retval   E_NOT_OK:   Development error occurred
* @retval   CAN_BUSY:   No TX hardware buffer available or pre-emptive call of
*                       Can_Write that can't be implemented re-entrant
*/
FUNC(Std_ReturnType, CAN_CODE) Can_Write(VAR(Can_HwHandleType, AUTOMATIC) Hth,
    P2CONST(Can_PduType, AUTOMATIC, CAN_APPL_CONST) PduInfo)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)

    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_WRITE)) 
    {
        /* nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckHth((uint8)CAN_SID_WRITE, Hth))
    {
        /* nothing */
    }
    else
    {
    #if (STD_ON == CAN_TRIGGER_TRANSMIT_ENABLE)
        /* The SDU can be null if trigger transmit is enabled, so we only check PDU here. */
        if ((Std_ReturnType)E_OK != Can_CheckNullPointer((uint8)CAN_SID_WRITE, PduInfo))
        {
            /* nothing */
        }
        else
    #else
        if ((Std_ReturnType)E_OK != Can_CheckNullPointer((uint8)CAN_SID_WRITE, PduInfo))
        {
            /* nothing */
        }
        else if ((Std_ReturnType)E_OK != Can_CheckNullPointer((uint8)CAN_SID_WRITE, PduInfo->sdu))
        {
            /* nothing */
        }
        else
    #endif /* STD_ON == CAN_TRIGGER_TRANSMIT_ENABLE */
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
        {
            result = Can_Hw_Write(Hth, PduInfo);
        }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    }
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    return result;
}

/*!
* @brief    Enables all allowed interrupts for a CAN controller
*
* @param[in]    Controller  CAN controller for which interrupts shall be re-enabled
*/
FUNC(void, CAN_CODE) Can_EnableControllerInterrupts(
    VAR(uint8, AUTOMATIC) Controller)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_ENABLE_CONTROLLER_INT))
    {
        /* nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckControllerId((uint8)CAN_SID_ENABLE_CONTROLLER_INT, Controller))
    {
        /* nothing */
    }
    else
    {
#endif 
        Can_Hw_EnableControllerInterrupts(Controller);
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    }
#endif 
}

/*!
* @brief    Disables all interrupts for a CAN controller
*
* @param[in]    Controller  CAN controller for which interrupts shall be disabled
*/
FUNC(void, CAN_CODE) Can_DisableControllerInterrupts(
    VAR(uint8, AUTOMATIC) Controller)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)

    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_DISABLE_CONTROLLER_INT))
    {
        /* nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckControllerId((uint8)CAN_SID_DISABLE_CONTROLLER_INT, Controller))
    {
        /* nothing */
    }
    else
    {
#endif  
        Can_Hw_DisableControllerInterrupts(Controller);
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    }
#endif 
}

/*!
* @brief    Obtains the error state of the CAN controller
*
* @param[in]    ControllerId    CAN controller ID which is requested for error state
* @param[out]   ErrorStatePtr   Pointer to memory location where the error state will be stored
*
* @retval   E_OK:       Error state request has been accepted
* @retval   E_NOT_OK:   Error state request has not been accepted
*/
FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerErrorState(
    VAR(uint8, AUTOMATIC) ControllerId,
    P2VAR(Can_ErrorStateType, AUTOMATIC, CAN_APPL_DATA) ErrorStatePtr)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)

    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_GET_CONTROLLER_ERROR_STATE))
    {
        /* Do Nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckControllerId((uint8)CAN_SID_GET_CONTROLLER_ERROR_STATE, ControllerId))
    {
        /* Do Nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckNullPointer((uint8)CAN_SID_GET_CONTROLLER_ERROR_STATE, ErrorStatePtr))
    {
        /* Do Nothing */
    }
    else
    {
#endif  
        *ErrorStatePtr = Can_Hw_GetControllerErrorState(ControllerId);
        result = (Std_ReturnType)E_OK;
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    }
#endif 
    return result;
}

#ifdef CAN_SET_BAUDRATE_API
#if (STD_ON == CAN_SET_BAUDRATE_API)
/*!
* @brief    Set the baud rate configuration of the CAN controller
*
* @param[in]     Controller         CAN controller whose baudrate shall be set
* @param[in]     BaudrateConfigId   References a baudrate configuration by ID
*
* @retval   E_OK:       Service request accepted
* @retval   E_NOT_OK:   Service request not accepted
*/
FUNC(Std_ReturnType, CAN_CODE) Can_SetBaudrate(
    VAR(uint8, AUTOMATIC) Controller,
    CONST(uint16, AUTOMATIC) BaudrateConfigId)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (uint8)E_NOT_OK;
    VAR(uint8, AUTOMATIC) baudrateIndex = 0U;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_SET_BAUDRATE))
    {
        /* Do Nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckControllerId((uint8)CAN_SID_SET_BAUDRATE, Controller))
    {
        /* Do Nothing */
    }
    else
    {
        if (CAN_CS_STOPPED == g_canControllerStatus[Controller].controllerState)
        {
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */

            baudrateIndex = 0U;
            while (baudrateIndex < g_canControllersInfoPtr[Controller].maxBaudrateCount)
            {
                if (BaudrateConfigId ==
                    (uint16)(g_canControllersInfoPtr[Controller].baudrateConfigs[baudrateIndex].baudrateConfigId))
                {
                    g_canControllerStatus[Controller].currentBaudrateIndex = baudrateIndex;
                    Can_Hw_SetBaudrate(Controller);
                    result = (Std_ReturnType)E_OK;
                    break;
                }
                else
                {
                    /* Do Nothing */
                }
                baudrateIndex++;
            }

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
            if ((Std_ReturnType)E_NOT_OK == result)
            {
                (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                                      (uint8)CAN_SID_SET_BAUDRATE, (uint8)CAN_E_PARAM_BAUDRATE);
            }
            else
            {
                /* Do Nothing */
            }
        }
        else
        {
            (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                                  (uint8)CAN_SID_SET_BAUDRATE, (uint8)CAN_E_TRANSITION);
        }
    }
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */

    return result;
}
#endif /* STD_ON == CAN_SET_BAUDRATE_API */
#endif /* CAN_SET_BAUDRATE_API */


#if (STD_ON == CAN_PUBLIC_ICOM_ENABLE)
/*!
* @brief    Change the Icom configuration of a CAN controller
*
* @param[in]    Controller      CAN controller for which the status shall be changed
* @param[in]    ConfigurationId Requested Icom configuration ID
*
* @retval   E_OK: Succeeded in setting a configuration
* @retval   E_NOT_OK: Failed to set a configuration
*/
FUNC(Std_ReturnType, CAN_CODE) Can_SetIcomConfiguration(
    VAR(uint8, AUTOMATIC) Controller,
    VAR(IcomConfigIdType, AUTOMATIC) ConfigurationId)
{
    VAR(uint8, AUTOMATIC) icomIndex = 0U;
    VAR(IcomSwitch_ErrorType, CANIF_VAR) icomError = ICOM_SWITCH_E_OK;
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_NOT_OK;

    /* Check if the controller support pretended networking */
    if ((boolean)FALSE == g_canControllerStaticConfigPtr[Controller].pnSupported)
    {
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
        (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                              (uint8)CAN_SID_SET_ICOM_CONFIG, (uint8)CAN_E_INVALID_CONTROLLER);
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    }
    else
    {
        if (0U != ConfigurationId)
        {
            /* Set ICOM configuration */
            icomIndex = 0U;
            while (icomIndex < g_canStaticConfigPtr->icomConfigPtr->icomConfigsCount)
            {
                if (ConfigurationId ==
                    (uint8)(g_canStaticConfigPtr->icomConfigPtr->icomSetConfigPtr[icomIndex].icomConfigId))
                {
                    result = (Std_ReturnType)Can_Hw_SetIcomConfig(Controller, icomIndex);
                    break;
                }
                else
                {
                    /* Do Nothing */
                }
                icomIndex++;
            }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
            if((Std_ReturnType)E_NOT_OK == result)
            {
                (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                                      (uint8)CAN_SID_SET_ICOM_CONFIG, (uint8)CAN_E_ICOM_CONFIG_INVALID);
            }
            else
            {
                /* Do Nothing */
            }
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
        }
        else
        {
            /* ConfigurationId = 0 means to deactivate pretended networking */
            result = (Std_ReturnType)Can_Hw_DeactivateIcom(Controller);
        }

        /* Notify the CanIf about Icom configuration change */
        icomError = ((Std_ReturnType)E_OK == result) ? ICOM_SWITCH_E_OK : ICOM_SWITCH_E_FAILED;
        CanIf_CurrentIcomConfiguration(Controller, ConfigurationId, icomError);
    }
    return result;
}
#endif /* STD_ON == CAN_PUBLIC_ICOM_ENABLE */

#if (STD_ON == CAN_GET_VERSION_INFO_API_ENABLE)
/*!
* @brief    Returns the version information of this module
*
* @param[in]    VersionInfo Pointer to where to store the version information
*/
FUNC(void, CAN_CODE) Can_GetVersionInfo(
    P2VAR(Std_VersionInfoType, AUTOMATIC, CAN_APPL_DATA) VersionInfo)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckNullPointer((uint8)CAN_SID_GET_VERSION_INFO, VersionInfo))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        VersionInfo->sw_major_version = (uint8)CAN_H_SW_MAJOR_VERSION;
        VersionInfo->sw_minor_version = (uint8)CAN_H_SW_MINOR_VERSION;
        VersionInfo->sw_patch_version = (uint8)CAN_H_SW_PATCH_VERSION;
        VersionInfo->moduleID         = (uint16)CAN_H_MODULE_ID;
        VersionInfo->vendorID         = (uint16)CAN_H_VENDOR_ID;
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* STD_ON == CAN_GET_VERSION_INFO_API_ENABLE */

#if (STD_ON == CAN_ABORT_MB_API_ENABLE)
/*!
* @brief    Abort transmission of a CAN frame
*
* @param[in]    Hth The HW-transmit handle to be aborted
*/
FUNC(void, CAN_CODE) Can_AbortMb(VAR(Can_HwHandleType, AUTOMATIC) Hth)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK != Can_CheckDriverInitialized((uint8)CAN_SID_ABORT_MB))
    {
        /* Do nothing */
    }
    else if ((Std_ReturnType)E_OK != Can_CheckHth((uint8)CAN_SID_ABORT_MB, Hth))
    {
        /* Do nothing */
    }
    else
#endif
    {
        Can_Hw_AbortMb(Hth);
    }
}
#endif /* STD_ON == CAN_ABORT_MB_API_ENABLE */

/*!
* @brief    Performs the polling of CAN controller mode transitions
*/
FUNC(void, CAN_CODE) Can_MainFunction_Mode(void)
{
    if (CAN_READY == g_canDriverStatus)
    {
        Can_Hw_MainFunctionMode();
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else
    {
        (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                              (uint8)CAN_SID_MAIN_MODE, (uint8)CAN_E_UNINIT);
    }
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
}

#if (STD_OFF == CAN_BUSOFF_INTERRUPT_HANDLE_ENABLE)
/*!
* @brief    Performs the polling of bus off events
*/
FUNC(void, CAN_CODE) Can_MainFunction_BusOff(void)
{
    VAR(uint8, AUTOMATIC) index = 0U;

#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_BUSOFF))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        /* Loop through all configured CAN controllers */
        while (index < (uint8)g_canStaticConfigPtr->controllersConfigured)
        {
            /* The controller shall be enabled, bus off polling shall be enabled for this controller. */
            if (CAN_CONTROLLER_INVALID != (g_canControllerStaticConfigPtr[index].controllerOffset))
            {
                /* Check and process bus off event */
                if ((E_OK == Can_Hw_IsBusOff(index)) && \
                    (E_OK == Can_Hw_SetControllerMode(index, CAN_CS_STOPPED, (boolean)FALSE)))
                {
                    Can_Hw_BusOffHandler(index);
                    CanIf_ControllerBusOff(index);
                }
                else
                {
                    /* Do nothing */
                }
            }
            else
            {
                /* Do nothing */
            }
            index++;
        }
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else
    {
        /* Do nothing */
    }
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
}
#endif /* STD_OFF == CAN_BUSOFF_INTERRUPT_HANDLE_ENABLE */

#if (STD_OFF == CAN_RX_INTERRUPT_HANDLE_ENABLE)
/*!
* @brief    Performs the polling of RX indications when CAN_RX_PROCESSING is set to POLLING
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionRead();
    }
 #if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}

#ifdef CAN_MAINFUNCTION_MULTIPLE_READ
#if (STD_ON == CAN_MAINFUNCTION_MULTIPLE_READ)

#ifdef CAN_MAINFUNCTION_PERIOD_READ_0
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_0(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(0U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_0 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_1
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_1(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(1U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_1 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_2
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_2(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(2U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_2 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_3
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_3(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(3U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_3 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_4
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_4(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(4U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_4 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_5
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_5(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(5U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_5 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_6
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_6(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(6U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_6 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_7
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_7(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(7U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_7 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_8
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_8(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(8U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_8 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_9
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_9(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(9U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_9 */

#ifdef CAN_MAINFUNCTION_PERIOD_READ_10
/*!
* @brief    Performs the polling of RX indications
*/
FUNC(void, CAN_CODE) Can_MainFunction_Read_10(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_READ))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleRead(10U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_READ_10 */

#endif /* STD_ON == CAN_MAINFUNCTION_MULTIPLE_READ */
#endif /* CAN_MAINFUNCTION_MULTIPLE_READ */
#endif /* STD_OFF == CAN_RX_INTERRUPT_HANDLE_ENABLE */

#if (STD_OFF == CAN_TX_INTERRUPT_HANDLE_ENABLE)
/*!
* @brief    Performs the polling of TX confirmation when CAN_TX_PROCESSING is set to POLLING
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionWrite();
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}

#ifdef CAN_MAINFUNCTION_MULTIPLE_WRITE
#if (STD_ON == CAN_MAINFUNCTION_MULTIPLE_WRITE)

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_0
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_0(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(0U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_0 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_1
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_1(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(1U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_1 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_2
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_2(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(2U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_2 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_3
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_3(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(3U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_3 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_4
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_4(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(4U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_4 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_5
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_5(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(5U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_5 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_6
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_6(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(6U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_6 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_7
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_7(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(7U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_7 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_8
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_8(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(8U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_8 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_9
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_9(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(9U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_9 */

#ifdef CAN_MAINFUNCTION_PERIOD_WRITE_10
/*!
* @brief    Performs the polling of TX confirmation
*/
FUNC(void, CAN_CODE) Can_MainFunction_Write_10(void)
{
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    if ((Std_ReturnType)E_OK == Can_CheckDriverInitialized((uint8)CAN_SID_MAIN_WRITE))
#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */
    {
        Can_Hw_MainFunctionMultipleWrite(10U);
    }
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
    else 
    {
        /* Do nothing */
    }
#endif 
}
#endif /* CAN_MAINFUNCTION_PERIOD_WRITE_10 */

#endif /* STD_ON == CAN_MAINFUNCTION_MULTIPLE_WRITE */
#endif /* CAN_MAINFUNCTION_MULTIPLE_WRITE */
#endif /* STD_OFF == CAN_TX_INTERRUPT_HANDLE_ENABLE */

/*******************************************************************************
                        LOCAL FUNCTIONS
*******************************************************************************/
#if (STD_ON == CAN_DEV_ERROR_DETECT_ENABLE)
/*!
* @brief Check if the CAN driver is initialized
*
* @param[in] ApiId The service ID to report DET error
*/
LOCAL_INLINE FUNC(Std_ReturnType, CAN_CODE) Can_CheckDriverInitialized(
    VAR(uint8, AUTOMATIC) ApiId)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_OK;

    if (CAN_UNINIT == g_canDriverStatus)
    {
        (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                              ApiId, (uint8)CAN_E_UNINIT);
        result = (Std_ReturnType)E_NOT_OK;
    }
    else
    {
        /* Do nothing */
    }
    return result;
}

/*!
* @brief Check if the given CAN controller ID is valid
*
* @param[in] ApiId      The service ID to report DET error
* @param[in] Controller The CAN controller ID to be checked
*/
FUNC(Std_ReturnType, CAN_CODE) Can_CheckControllerId(
    VAR(uint8, AUTOMATIC) ApiId,
    VAR(uint8, AUTOMATIC) Controller)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_OK;

    if ((Controller >= g_canStaticConfigPtr->controllersConfigured) ||
        (CAN_CONTROLLER_INVALID == g_canControllerStaticConfigPtr[Controller].controllerOffset))
    {
       (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                             ApiId, (uint8)CAN_E_PARAM_CONTROLLER);
        result = (Std_ReturnType)E_NOT_OK;
    }
    else
    {
        /* Do nothing */
    }
    return result;
}

/*!
* @brief Check if the given pointer is null
*
* @param[in] ApiId  The service ID to report DET error
* @param[in] Ptr    The pointer to be checked
*/
LOCAL_INLINE FUNC(Std_ReturnType, CAN_CODE) Can_CheckNullPointer(
     CONST(uint8, AUTOMATIC) ApiId,
     P2CONST(void, AUTOMATIC, CAN_APPL_CONST) Ptr)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_OK;

    if (NULL_PTR == Ptr)
    {
        (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                              ApiId, (uint8)CAN_E_PARAM_POINTER);
         result = (Std_ReturnType)E_NOT_OK;
    }
    else
    {
        /* Do nothing */
    }
    return result;
}

/*!
* @brief Check if the given HTH is valid
*
* @param[in] ApiId  The service ID to report DET error
* @param[in] Hth    The HTH to be checked
*/
LOCAL_INLINE FUNC(Std_ReturnType, CAN_CODE) Can_CheckHth(
    VAR(uint8, AUTOMATIC) ApiId,
    VAR(Can_HwHandleType, AUTOMATIC) Hth)
{
    VAR(Std_ReturnType, AUTOMATIC) result = (Std_ReturnType)E_NOT_OK;
    VAR(uint8, AUTOMATIC) circleCnt = 0U;

    for(; circleCnt < g_canConfigPtr->txMbConfigContainerPtr->txMbCount; circleCnt++)
    {
        if (Hth == g_canConfigPtr->txMbConfigContainerPtr->txMbConfigPtr[circleCnt].txHwObjId)
        {
            result = (Std_ReturnType)E_OK;
            break;
        }
        else
        {
            /* Do nothing */
        }
    }

    if ((Std_ReturnType)E_NOT_OK == result)
    {
       (void)Det_ReportError((uint16)CAN_H_MODULE_ID, (uint8)CAN_HW_INSTANCE0,
                             ApiId, (uint8)CAN_E_PARAM_HANDLE);
    }
    else
    {
        /* Do nothing */
    }

    return result;
}

#endif /* STD_ON == CAN_DEV_ERROR_DETECT_ENABLE */

#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

/**@} end of group CAN_Fuctions */
#ifdef __cplusplus
}
#endif
/**@} end of group CAN_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
