/*
 * FlexCAN_Ip.c
 *
 *  Created on: Apr 9, 2020
 *      Author: nxf31634
 */
/**
 *  @file FlexCAN_Ip.c
 *  @brief FlexCAN Driver File
 *  @addtogroup FlexCAN
 * @{
 */

/*==================================================================================================
*   Project              : RTD AUTOSAR 4.4
*   Platform             : CORTEXM
*   Peripheral           : FLEXCAN
*   Dependencies         : 
*
*   Autosar Version      : 4.4.0
*   Autosar Revision     : ASR_REL_4_4_REV_0000
*   Autosar Conf.Variant :
*   SW Version           : 0.9.0
*   Build Version        : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
*
*   (c) Copyright 2020 - 2021 NXP Semiconductors
*   All Rights Reserved.
*
*   NXP Confidential. This software is owned or controlled by NXP and may only be
*   used strictly in accordance with the applicable license terms. By expressly
*   accepting such terms or by downloading, installing, activating and/or otherwise
*   using the software, you are agreeing that you have read, and that you agree to
*   comply with and are bound by, such license terms. If you do not agree to be
*   bound by the applicable license terms, then you may not retain, install,
*   activate or otherwise use the software.
==================================================================================================*/

/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "FlexCAN_Ip.h"
#include "Devassert.h"
#include "FlexCAN_Ip_Irq.h"
#include "FlexCAN_Ip_HwAccess.h"
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
#include "Dma_Ip.h"
#endif

#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
    #define USER_MODE_REG_PROT_ENABLED      (STD_ON)
    #include "RegLockMacros.h"
#endif /* (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE) */

#include "SchM_Can.h"

#ifdef MCAL_ENABLE_FAULT_INJECTION
    #include "Mcal.h"
#endif
/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define FLEXCAN_IP_VENDOR_ID_C                      43
#define FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C       4
#define FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C       4
#define FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C    0
#define FLEXCAN_IP_SW_MAJOR_VERSION_C               0
#define FLEXCAN_IP_SW_MINOR_VERSION_C               9
#define FLEXCAN_IP_SW_PATCH_VERSION_C               0
/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if current file and FlexCAN_Ip.h header file are of the same vendor */
#if (FLEXCAN_IP_VENDOR_ID_C != FLEXCAN_IP_VENDOR_ID_H)
    #error "FlexCAN_Ip.c and FlexCAN_Ip.h have different vendor ids"
#endif
/* Check if current file and FlexCAN_Ip.h header file are of the same Autosar version */
#if ((FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C    != FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_H) || \
     (FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C    != FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_H) || \
     (FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C != FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_H))
    #error "AutoSar Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip.h are different"
#endif
/* Check if current file and FlexCAN_Ip.h header file are of the same Software version */
#if ((FLEXCAN_IP_SW_MAJOR_VERSION_C != FLEXCAN_IP_SW_MAJOR_VERSION_H) || \
     (FLEXCAN_IP_SW_MINOR_VERSION_C != FLEXCAN_IP_SW_MINOR_VERSION_H) || \
     (FLEXCAN_IP_SW_PATCH_VERSION_C != FLEXCAN_IP_SW_PATCH_VERSION_H))
    #error "Software Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip.h are different"
#endif

/* Check if current file and FlexCAN_Ip_Irq.h header file are of the same vendor */
#if (FLEXCAN_IP_VENDOR_ID_C != FLEXCAN_IP_IRQ_VENDOR_ID_H)
    #error "FlexCAN_Ip.c and FlexCAN_Ip_Irq.h have different vendor ids"
#endif
/* Check if current file and FlexCAN_Ip_Irq.h header file are of the same Autosar version */
#if ((FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C    != FLEXCAN_IP_IRQ_AR_RELEASE_MAJOR_VERSION_H) || \
     (FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C    != FLEXCAN_IP_IRQ_AR_RELEASE_MINOR_VERSION_H) || \
     (FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C != FLEXCAN_IP_IRQ_AR_RELEASE_REVISION_VERSION_H))
    #error "AutoSar Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_Irq.h are different"
#endif
/* Check if current file and FlexCAN_Ip_Irq.h header file are of the same Software version */
#if ((FLEXCAN_IP_SW_MAJOR_VERSION_C != FLEXCAN_IP_IRQ_SW_MAJOR_VERSION_H) || \
     (FLEXCAN_IP_SW_MINOR_VERSION_C != FLEXCAN_IP_IRQ_SW_MINOR_VERSION_H) || \
     (FLEXCAN_IP_SW_PATCH_VERSION_C != FLEXCAN_IP_IRQ_SW_PATCH_VERSION_H))
    #error "Software Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_Irq.h are different"
#endif

/* Check if current file and FlexCAN_Ip_HwAccess.h header file are of the same vendor */
#if (FLEXCAN_IP_VENDOR_ID_C != FLEXCAN_IP_HWACCESS_VENDOR_ID_H)
    #error "FlexCAN_Ip.c and FlexCAN_Ip_HwAccess.h have different vendor ids"
#endif
/* Check if current file and FlexCAN_Ip_HwAccess.h header file are of the same Autosar version */
#if ((FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C    != FLEXCAN_IP_HWACCESS_AR_RELEASE_MAJOR_VERSION_H) || \
     (FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C    != FLEXCAN_IP_HWACCESS_AR_RELEASE_MINOR_VERSION_H) || \
     (FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C != FLEXCAN_IP_HWACCESS_AR_RELEASE_REVISION_VERSION_H))
    #error "AutoSar Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_HwAccess.h are different"
#endif
/* Check if current file and FlexCAN_Ip_HwAccess.h header file are of the same Software version */
#if ((FLEXCAN_IP_SW_MAJOR_VERSION_C != FLEXCAN_IP_HWACCESS_SW_MAJOR_VERSION_H) || \
     (FLEXCAN_IP_SW_MINOR_VERSION_C != FLEXCAN_IP_HWACCESS_SW_MINOR_VERSION_H) || \
     (FLEXCAN_IP_SW_PATCH_VERSION_C != FLEXCAN_IP_HWACCESS_SW_PATCH_VERSION_H))
    #error "Software Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_HwAccess.h are different"
#endif

#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and SchM_Can header file are of the same version */
#endif
/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/

/*==================================================================================================
*                                       LOCAL MACROS
==================================================================================================*/
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    #if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
        #define CAN_ENHANCE_TRASNFER_DIMENSION_LIST (13U)
    #endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)  */

    #define CAN_TRASNFER_DIMENSION_LIST (10U)
#endif /*(FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)*/
/*==================================================================================================
*                                      LOCAL CONSTANTS
==================================================================================================*/

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

/*==================================================================================================
*                                      GLOBAL VARIABLES
==================================================================================================*/
#define CAN_START_SEC_CONST_UNSPECIFIED
#include "Can_MemMap.h"

/* Table of base addresses for CAN instances. */
static FLEXCAN_Type * const g_Flexcan_Ip_aBase[] = FLEXCAN_BASE_PTRS;

#define CAN_STOP_SEC_CONST_UNSPECIFIED
#include "Can_MemMap.h"

#define CAN_START_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
#include "Can_MemMap.h"

/* Pointer to runtime state structure.*/
static Flexcan_Ip_StateType * g_flexcan_Ip_StatePtr[FLEXCAN_INSTANCE_COUNT];

#define CAN_STOP_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
#include "Can_MemMap.h"


#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
/*==================================================================================================
*                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/
/* Init legacy, enhanced fifo if requested, if no fifo request, return success. */
static Flexcan_Ip_StatusType FlexCAN_InitRxFifo(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData);

/* Init basically controller , this function is called in FlexCAN_Ip_Init only */
static Flexcan_Ip_StatusType FlexCAN_InitController(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData);

static Flexcan_Ip_StatusType FlexCAN_StartRxMessageBufferData(uint8 instance,
                                                 uint8 mb_idx,
                                                 Flexcan_Ip_MsgBuffType * data,
                                                 boolean isPolling);

static Flexcan_Ip_StatusType FlexCAN_StartSendData(uint8 Flexcan_Ip_u8Instance,
                                                  uint8 mb_idx,
                                                  const Flexcan_Ip_DataInfoType * tx_info,
                                                  uint32 msg_id,
                                                  const uint8 * mb_data);

static Flexcan_Ip_StatusType FlexCAN_StartRxMessageFifoData(uint8 instance,
                                                          Flexcan_Ip_MsgBuffType * data);

static Flexcan_Ip_StatusType FlexCAN_ProccessLegacyRxFIFO(uint8 u8Instance, uint32 u32TimeoutMs);

static void FlexCAN_IRQHandlerRxMB(uint8 instance,
                                   uint32 mb_idx);

static void FlexCAN_IRQHandlerTxMB(uint8 u8Instance, uint32 u32MbIdx);

static inline void FlexCAN_IRQHandlerRxFIFO(uint8 instance,
                                            uint32 mb_idx);

static inline void FlexCAN_ProcessSpuriousInterruptMB(uint8 instance, uint32 startMbIdx, uint32 endMbIdx);

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
static void DMA_Can_Callback(uint8 instance);
#endif

#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
static void FlexCAN_SetUserAccessAllowed(const FLEXCAN_Type * pBase);
static void FlexCAN_ClrUserAccessAllowed(const FLEXCAN_Type * pBase);
#endif

static Flexcan_Ip_StatusType FlexCAN_AbortTxTransfer(uint8 u8Instance, uint8 mb_idx);
static void FlexCAN_AbortRxTransfer(uint8 u8Instance, uint8 mb_idx);

static void FlexCAN_CompleteRxMessageFifoData(uint8 instance);

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
static void FlexCAN_IRQHandlerEnhancedRxFIFO(uint8 instance, uint32 intType);
static inline boolean FlexCAN_ProcessIRQHandlerEnhancedRxFIFO(uint8 u8Instance, boolean bIsSpuriousIntPrevious);
static void FlexCAN_CompleteRxMessageEnhancedFifoData(uint8 instance);
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageEnhancedFifoData(uint8 instance,
                                                                    Flexcan_Ip_MsgBuffType * data);
static Flexcan_Ip_StatusType FlexCAN_ProccessEnhancedRxFifo(uint8 u8Instance, uint32 u32TimeoutMs);
/*==================================================================================================
*                                       LOCAL FUNCTIONS
==================================================================================================*/
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_InitRxFifo
 * Description   : Initialize fifo and dma if requested.
 *
 * This is not a public API as it is called from other driver functions.
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_InitRxFifo(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;

    /* Enable RxFIFO feature, if requested. This might fail if the FD mode is enabled. */
    if (Flexcan_Ip_pData->is_rx_fifo_needed)
    {
        eResult = FlexCAN_EnableRxFifo(pBase, (uint32)Flexcan_Ip_pData->num_id_filters);
    }

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
/* Enable Enhanced RxFIFO feature, if requested.
 * This might fail if the current CAN instance does not support Enhaneced RxFIFO or the Rx FIFO is enabled. */
    if ((FLEXCAN_STATUS_SUCCESS == eResult) && (Flexcan_Ip_pData->is_enhanced_rx_fifo_needed))
    {
    #if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
        if (Flexcan_Ip_pData->transfer_type == FLEXCAN_RXFIFO_USING_DMA)
        {
            eResult = FlexCAN_EnableEnhancedRxFifo(pBase,
                                             (uint32)Flexcan_Ip_pData->num_enhanced_std_id_filters,
                                             (uint32)Flexcan_Ip_pData->num_enhanced_ext_id_filters,
                                             (uint32)0U); /* for dma, each a frame received -> a minor loop */
        }
        else
    #endif /* FEATURE_CAN_HAS_DMA_ENABLE */
        {
            eResult = FlexCAN_EnableEnhancedRxFifo(pBase,
                                             (uint32)Flexcan_Ip_pData->num_enhanced_std_id_filters,
                                             (uint32)Flexcan_Ip_pData->num_enhanced_ext_id_filters,
                                             (uint32)Flexcan_Ip_pData->num_enhanced_watermark);
        }
    }
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    if (FLEXCAN_STATUS_SUCCESS == eResult)
    {
    /* Enable DMA support for RxFIFO transfer, if requested. */
    if (Flexcan_Ip_pData->transfer_type == FLEXCAN_RXFIFO_USING_DMA)
    {
        if (((pBase->MCR & FLEXCAN_MCR_RFEN_MASK) >> FLEXCAN_MCR_RFEN_SHIFT) != 0U)
        {
            FlexCAN_SetRxFifoDMA(pBase, TRUE);
        }
    #if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
        else if (FlexCAN_IsEnhancedRxFifoAvailable(pBase))
        {
            if (FlexCAN_IsEnhancedRxFifoEnabled(pBase))
            {
                FlexCAN_SetRxFifoDMA(pBase, TRUE);
                FlexCAN_ConfigEnhancedRxFifoDMA(pBase, 20U); /* always transfer 80 bytes (DMALW = 19)*/
            }
            else
            {
                eResult = FLEXCAN_STATUS_ERROR;
            }
        }
    #endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
        else
        {
            eResult = FLEXCAN_STATUS_ERROR;
        }
    }
    else
    {
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
        if (FlexCAN_IsEnhancedRxFifoAvailable(pBase))
        {
            /* Clear Enhanced Rx FIFO status.*/
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE);
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_WATERMARK);
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_OVERFLOW);
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_UNDERFLOW);
            /* Clear the Enhanced RX FIFO engine */
            FlexCAN_ClearEnhancedRxFifoEngine(pBase);
        }
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
        FlexCAN_SetRxFifoDMA(pBase, FALSE);
    }
    }
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */

    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_InitController
 * Description   : Initialize basically controller.
 *
 * This is not a public API as it is called from other driver functions.
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_InitController(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;

    if (FlexCAN_IsEnabled(pBase))
    {
        /* To enter Disable Mode requires FreezMode first */
        eResult = FlexCAN_EnterFreezeMode(pBase);
        if(FLEXCAN_STATUS_SUCCESS == eResult)
        {
            eResult = FlexCAN_Disable(pBase);
        }
    }

    if(FLEXCAN_STATUS_SUCCESS == eResult)
    {
        /* Start critical section: implementation depends on integrator */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();
        /* Enable FlexCAN Module need to perform SoftReset & ClearRam */
        pBase->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
        /* End critical section: implementation depends on integrator */
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
        /* Initialize FLEXCAN device */
        eResult = FlexCAN_Init(pBase);
        if (eResult != FLEXCAN_STATUS_SUCCESS)
        {
            /* To enter Disable Mode requires FreezMode first */
            (void)FlexCAN_EnterFreezeMode(pBase);
            (void)FlexCAN_Disable(pBase);
        }
        else
        {
        #if (FEATURE_CAN_HAS_MEM_ERR_DET == STD_ON)
            /* Disable the Protection again because is enabled by soft reset */
            FlexCAN_DisableMemErrorDetection(pBase);
        #endif

            /* Enable/Disable FD and check FD was set as expected. Setting FD as enabled
             * might fail if the current CAN instance does not support FD. */
            FlexCAN_SetFDEnabled(pBase, Flexcan_Ip_pData->fd_enable, Flexcan_Ip_pData->bitRateSwitch);
            /* No more required, I don't expect any other NPIs with and without Interfaces with FD support
             * if (FLEXCAN_IsFDEnabled(base) != Flexcan_Ip_pData->fd_enable)
            {
                return FLEXCAN_STATUS_ERROR;
            }*/

            /* configure depends on controller options. */
            FlexCAN_ConfigCtrlOptions(pBase, Flexcan_Ip_pData->ctrlOptions);

            /* Disable the self reception feature if FlexCAN is not in loopback mode. */
            if (Flexcan_Ip_pData->flexcanMode != FLEXCAN_LOOPBACK_MODE)
            {
                FlexCAN_SetSelfReception(pBase, FALSE);
            }

            /* Init legacy fifo, enhanced fifo if requested. */
            eResult = FlexCAN_InitRxFifo(pBase, Flexcan_Ip_pData);
            if (eResult != FLEXCAN_STATUS_SUCCESS)
            {
                /* To enter Disable Mode requires FreezMode first */
                (void)FlexCAN_EnterFreezeMode(pBase);
                (void)FlexCAN_Disable(pBase);
            }
            else
            {
            #if (FEATURE_CAN_HAS_FD == STD_ON)
                /* Set payload size. */
                FlexCAN_SetPayloadSize(pBase, &Flexcan_Ip_pData->payload);
            #endif /* FEATURE_CAN_HAS_FD */

            #if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
                eResult = FlexCAN_SetMaxMsgBuffNum(pBase, Flexcan_Ip_pData->max_num_mb);
                if (eResult != FLEXCAN_STATUS_SUCCESS)
                {
                    /* To enter Disable Mode requires FreezMode first */
                    (void)FlexCAN_EnterFreezeMode(pBase);
                    (void)FlexCAN_Disable(pBase);
                }
            #else
                (void)FlexCAN_SetMaxMsgBuffNum(pBase, Flexcan_Ip_pData->max_num_mb);
            #endif /* FLEXCAN_DEV_ERROR_DETECT */
            }
        }
    }

    return eResult;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_CompleteRxMessageEnhancedFifoData
 * Description   : Finish up a receive by completing the process of receiving
 * data and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void FlexCAN_CompleteRxMessageEnhancedFifoData(uint8 instance)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    uint32 u32MbCnt = 0U;
    uint8 j;
    Flexcan_Ip_MsgBuffType * fifo_message = NULL_PTR;
    uint32 * msgData_32 = NULL_PTR;
    uint8 flexcan_mb_dlc_value = 0U;
    uint8 can_dlc_payload = 0U;
    uint8 can_real_payload = 0U;
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(FlexCAN_IsEnhancedRxFifoAvailable(base));
#endif /* (FLEXCAN_DEV_ERROR_DETECT == STD_ON) */

    if (state->enhancedFifoOutput.isPolling == FALSE)
    {
        /* Reset to default value to avoid re-enable when calling Ip_EnableInterrupt */
        state->enhancedFifoOutput.isPolling = TRUE;
        /* Disable Enhanced RX FIFO interrupts*/
        FlexCAN_SetEnhancedRxFifoIntAll(base, FALSE);
    }
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    else if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
    {
        Dma_Ip_LogicChannelStatusType dmaStatus;
        Dma_Ip_GetLogicChannelStatus(state->rxFifoDMAChannel, &dmaStatus);

        if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
        {
            (void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_ERROR);
            state->enhancedFifoOutput.state = FLEXCAN_MB_DMA_ERROR;
        }

        (void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);

        if (state->enhancedFifoOutput.state != FLEXCAN_MB_DMA_ERROR)
        {
            fifo_message = state->enhancedFifoOutput.pMBmessage;
            msgData_32 = (uint32 *)fifo_message->data;

            for (u32MbCnt = 0U; u32MbCnt < state->u32NumOfMbTransferByDMA; u32MbCnt++)
            {
                /* Adjust the ID if it is not extended */
                if (((fifo_message->cs) & CAN_CS_IDE_MASK) == 0U)
                {
                    fifo_message->msgId = fifo_message->msgId >> CAN_ID_STD_SHIFT;
                }

                /* Extract the data length */
                flexcan_mb_dlc_value = (uint8)((fifo_message->cs & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
                can_dlc_payload = FlexCAN_ComputePayloadSize(flexcan_mb_dlc_value);
                can_real_payload = 0U;
                /* Extract the IDHIT and Time Stamp */
                if ((fifo_message->cs & CAN_CS_RTR_MASK) != 0U)
                {
                    can_real_payload = 0U;
                }
                else
                {
                    can_real_payload = can_dlc_payload;
                }

                uint8 idhit_offset = (can_real_payload >> 2U) + (((can_real_payload % 4U) != 0U) ? 1U : 0U);
#if (FEATURE_CAN_HAS_HR_TIMER == STD_ON)
                /* Extract the Time Stamp */
                if (FLEXCAN_IsHRTimeStampEnabled(base))
                {
                    fifo_message->time_stamp = (uint32)(msgData_32[idhit_offset + 1U]);
                }
                else
#endif /* FEATURE_CAN_HAS_HR_TIMER */
                {
                    fifo_message->time_stamp = (uint32)((fifo_message->cs & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
                }

                /* Extract the IDHIT */
                fifo_message->id_hit = (uint8)(((msgData_32[idhit_offset]) & CAN_ENHANCED_IDHIT_MASK) >> CAN_ENHANCED_IDHIT_SHIFT);
                /* Extract the dataLen */
                fifo_message->dataLen = can_dlc_payload;
                /* Reverse the endianness */
                for (j = 0U; j < idhit_offset; j++)
                {
                    FlexcanSwapBytesInWord(msgData_32[j], msgData_32[j]);
                }

                fifo_message++;
                msgData_32 = (uint32 *)fifo_message->data;
            }
        }
        else
        {
            /* If Enhanced Rx FIFO has Pending Request that generated error,
             * the EnhancedRxFIFO need to be empty to activate DMA */
            FlexCAN_ClearOutputEnhanceFIFO(base);
        }
    }
    else
    {
        /* avoid misra */
    }
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */

    /* Clear enhanced rx fifo message*/
    state->enhancedFifoOutput.pMBmessage = NULL_PTR;

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    if (state->enhancedFifoOutput.state != FLEXCAN_MB_DMA_ERROR)
    {
        state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
        if ((state->callback != NULL_PTR) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
        {
            state->callback(instance, FLEXCAN_EVENT_DMA_COMPLETE, FLEXCAN_MB_ENHANCED_RXFIFO, state);
        }
    }
    else
    {
        if (state->callback != NULL_PTR)
        {
            state->callback((uint8)instance, FLEXCAN_EVENT_DMA_ERROR, FLEXCAN_MB_ENHANCED_RXFIFO, state);
        }
    }
#else  /* if FEATURE_CAN_HAS_DMA_ENABLE */
    state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_StartRxMessageEnhancedFifoData
 * Description   : Initiate (start) a receive by beginning the process of
 * receiving data and enabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageEnhancedFifoData(uint8 instance,
                                                                    Flexcan_Ip_MsgBuffType * data)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif /* (FLEXCAN_DEV_ERROR_DETECT == STD_ON) */

    /* Start receiving fifo */
    if (state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY)
    {
        eResult = FLEXCAN_STATUS_BUSY;
    }
    else
    {
    state->enhancedFifoOutput.state = FLEXCAN_MB_RX_BUSY;
    /* This will get filled by the interrupt handler */
    state->enhancedFifoOutput.pMBmessage = data;
    if (state->transferType == FLEXCAN_RXFIFO_USING_INTERRUPTS)
    {
        state->enhancedFifoOutput.isPolling = FALSE;
        if ((boolean)TRUE == state->isIntActive)
        {
            /* Enable All Enhanced RX FIFO interrupts*/
            FlexCAN_SetEnhancedRxFifoIntAll(base, TRUE);
        }
    }
    if (state->transferType == FLEXCAN_RXFIFO_USING_POLLING)
    {
        state->enhancedFifoOutput.isPolling = TRUE;
    }

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
    {
        /* reset to default to avoid enabling interrupt */
        state->enhancedFifoOutput.isPolling = TRUE;
        Dma_Ip_ReturnType edmaStatus;

        Dma_Ip_LogicChannelTransferListType trasfer[CAN_ENHANCE_TRASNFER_DIMENSION_LIST] = {
            {
                .Param = DMA_IP_CH_SET_SOURCE_ADDRESS,
                .Value = ((uint32)base + (uint32)FEATURE_CAN_ENHANCED_FIFO_RAM_OFFSET),
            },
            {
                .Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET ,
                .Value = 4,
            },
            {
                .Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE,
                .Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
            },
            {
                .Param = DMA_IP_CH_SET_DESTINATION_ADDRESS,
                .Value = (uint32)(state->enhancedFifoOutput.pMBmessage),
            },
            {
                .Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET,
                .Value = 4,
            },
            {
                .Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE,
                .Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
            },
            {
                .Param = DMA_IP_CH_SET_MINORLOOP_SIZE,
                .Value = 80,
            },
            {
                .Param = DMA_IP_CH_SET_MAJORLOOP_COUNT,
                .Value = state->u32NumOfMbTransferByDMA,
            },
            {
                .Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT,
                .Value = 1,
            },
            {
                .Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST,
                .Value = 1,
            },
            {
                .Param = DMA_IP_CH_SET_MINORLOOP_EN_SRC_OFFSET,
                .Value = 1, /* enable for src address: after each minor loop, jump back to output of enhance fifo */
            },
            {
                .Param = DMA_IP_CH_SET_MINORLOOP_EN_DST_OFFSET,
                .Value = 0, /* disable for dst address: after each minor loop: standing on next element of pMBmessage array */
            },
            {
                .Param = DMA_IP_CH_SET_MINORLOOP_SIGNED_OFFSET,
                .Value = (uint32)((sint32)(-80)), /* enable for src address: after each minor loop, jump back to output of enhance fifo */
            }
        };

        edmaStatus = Dma_Ip_SetLogicChannelTransferList(state->rxFifoDMAChannel, &trasfer[0], CAN_ENHANCE_TRASNFER_DIMENSION_LIST);

        if (edmaStatus != DMA_IP_STATUS_SUCCESS)
        {
            state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;

            eResult = FLEXCAN_STATUS_ERROR;
        }
        else
        {
        edmaStatus = Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);

        if (edmaStatus != DMA_IP_STATUS_SUCCESS)
        {
            state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;

            eResult = FLEXCAN_STATUS_ERROR;
        }
        }
    }
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
    }
    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_ProccessEnhancedRxFifo
 * Description   : This function will process the enhanced RxFIFO in blocking mode.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_ProccessEnhancedRxFifo(uint8 u8Instance, uint32 u32TimeoutMs)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StateType * pState = g_flexcan_Ip_StatePtr[u8Instance];
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    uint32 timeStart = 0U;
    uint32 timeElapsed = 0U;
    uint32 mS2Ticks = OsIf_MicrosToTicks((u32TimeoutMs * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
    uint32 u32intType = 0U;

        timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
        while (FLEXCAN_MB_RX_BUSY == pState->enhancedFifoOutput.state)
        {
            if (FLEXCAN_RXFIFO_USING_POLLING == pState->transferType)
            {
                for (u32intType = CAN_ENHANCED_RXFIFO_UNDERFLOW; \
                     u32intType >= CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE; \
                     u32intType--)
                {
                    if (FlexCAN_GetEnhancedRxFIFOStatusFlag(pBase, u32intType) != 0U)
                    {
                        FlexCAN_IRQHandlerEnhancedRxFIFO(u8Instance, u32intType);
                    }
                }
            }

            timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
            if (timeElapsed >= mS2Ticks)
            {
                eResult = FLEXCAN_STATUS_TIMEOUT;
                break;
            }
        }

        if ((FLEXCAN_STATUS_TIMEOUT == eResult) && (FLEXCAN_RXFIFO_USING_POLLING != pState->transferType))
        {
            /* Disable Enhanced RX FIFO interrupts*/
            FlexCAN_SetEnhancedRxFifoIntAll(pBase, (boolean)FALSE);
#if FEATURE_CAN_HAS_DMA_ENABLE
            /* Check if transfer is done over DMA and stop transfer */
            if ((FLEXCAN_MB_RX_BUSY == pState->enhancedFifoOutput.state) && (FLEXCAN_RXFIFO_USING_DMA == pState->transferType))
            {
                (void)Dma_Ip_SetLogicChannelCommand(pState->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
                /* Reset Entire Enhance FIFO if timeout occurred */
                if (FLEXCAN_MB_RX_BUSY == pState->enhancedFifoOutput.state)
                {
                #if ((STD_ON == FLEXCAN_ENABLE_USER_MODE_SUPPORT) && (STD_OFF == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE))
                    OsIf_Trusted_Call1param(FlexCAN_ClearOutputEnhanceFIFO, pBase);
                #else
                    FlexCAN_ClearOutputEnhanceFIFO(pBase);
                #endif
                }
            }
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
        }

        switch (pState->enhancedFifoOutput.state)
        {
            case FLEXCAN_MB_RX_BUSY:
                pState->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
                break;
            case FLEXCAN_MB_IDLE:
                eResult = FLEXCAN_STATUS_SUCCESS;
                break;
#if FEATURE_CAN_HAS_DMA_ENABLE
            case FLEXCAN_MB_DMA_ERROR:
                eResult = FLEXCAN_STATUS_ERROR;
                break;
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
            default:
                eResult = FLEXCAN_STATUS_ERROR;
                break;
        }

    return eResult;
}
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_ProccessLegacyRxFIFO
 * Description   : This function will process the enhanced RxFIFO in blocking mode.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_ProccessLegacyRxFIFO(uint8 u8Instance, uint32 u32TimeoutMs)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StateType * pState = g_flexcan_Ip_StatePtr[u8Instance];
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    uint32 timeStart = 0U;
    uint32 timeElapsed = 0U;
    uint32 mS2Ticks = OsIf_MicrosToTicks((u32TimeoutMs * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
    uint32 u32intType = 0U;

        timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);

        while (FLEXCAN_MB_RX_BUSY == pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state)
        {
            if (FLEXCAN_RXFIFO_USING_POLLING == pState->transferType)
            {
                for (u32intType = CAN_LEGACY_RXFIFO_OVERFLOW; \
                     u32intType >= CAN_LEGACY_RXFIFO_FRAME_AVAILABLE; \
                     u32intType--)
                {
                    if (FlexCAN_GetBuffStatusFlag(pBase, u32intType) != 0U)
                    {
                        FlexCAN_IRQHandlerRxFIFO(u8Instance, u32intType);
                    }
                }
            }

            timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
            if (timeElapsed >= mS2Ticks)
            {
                eResult = FLEXCAN_STATUS_TIMEOUT;
                break;
            }
        }

        if ((FLEXCAN_STATUS_TIMEOUT == eResult) && (FLEXCAN_RXFIFO_USING_POLLING != pState->transferType))
        {
            /* Disable RX FIFO interrupts*/
            (void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, (boolean)FALSE, pState->isIntActive);
            (void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_WARNING, (boolean)FALSE, pState->isIntActive);
            (void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_OVERFLOW, (boolean)FALSE, pState->isIntActive);
#if FEATURE_CAN_HAS_DMA_ENABLE
            /* Check if transfer is done over DMA and stop transfer */
            if ((FLEXCAN_MB_RX_BUSY == pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state) && (FLEXCAN_RXFIFO_USING_DMA == pState->transferType))
            {
                /* This function always return status success */
                (void)Dma_Ip_SetLogicChannelCommand(pState->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
            }
#endif
        }

        switch (pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state)
        {
            case FLEXCAN_MB_RX_BUSY:
                pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
                break;
            case FLEXCAN_MB_IDLE:
                eResult = FLEXCAN_STATUS_SUCCESS;
                break;
#if FEATURE_CAN_HAS_DMA_ENABLE
            case FLEXCAN_MB_DMA_ERROR:
                eResult = FLEXCAN_STATUS_ERROR;
                break;
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
            default:
                eResult = FLEXCAN_STATUS_ERROR;
                break;
        }

    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_StartRxMessageBufferData
 * Description   : Initiate (start) a receive by beginning the process of
 * receiving data and enabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageBufferData(uint8 instance,
                                                 uint8 mb_idx,
                                                 Flexcan_Ip_MsgBuffType * data,
                                                 boolean isPolling)
{

    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#endif
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);

    if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(base, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
    {
        result = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
    }
    else
    {
#endif
        /* Start receiving mailbox */
        if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
        {
            result = FLEXCAN_STATUS_BUSY;
        }
        else
        {
            state->mbs[mb_idx].state = FLEXCAN_MB_RX_BUSY;
            state->mbs[mb_idx].pMBmessage = data;
            state->mbs[mb_idx].isPolling = isPolling;
        }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    }
#endif
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_StartSendData
 * Description   : Initiate (start) a transmit by beginning the process of
 * sending data.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_StartSendData(uint8 Flexcan_Ip_u8Instance,
                                                  uint8 mb_idx,
                                                  const Flexcan_Ip_DataInfoType * tx_info,
                                                  uint32 msg_id,
                                                  const uint8 * mb_data)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_MsbuffCodeStatusType cs;
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[Flexcan_Ip_u8Instance];
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[Flexcan_Ip_u8Instance];
    /* aici e ilogic ca nu are rost sa faci checkul dupa ce ai alocat aiurea */
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(Flexcan_Ip_u8Instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(tx_info != NULL_PTR);

    if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(base, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
    {
        eResult = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
    }
    else
    {
#endif
        if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
        {
            eResult = FLEXCAN_STATUS_BUSY;
        }
        else
        {
            /* Clear message buffer flag */
            FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

            state->mbs[mb_idx].state = FLEXCAN_MB_TX_BUSY;
            state->mbs[mb_idx].time_stamp = 0U;
            state->mbs[mb_idx].isPolling = tx_info->is_polling;
            state->mbs[mb_idx].isRemote = tx_info->is_remote;

            cs.dataLen = tx_info->data_length;
            cs.msgIdType = tx_info->msg_id_type;

        #if (FEATURE_CAN_HAS_FD == STD_ON)
            cs.fd_enable = tx_info->fd_enable;
            cs.fd_padding = tx_info->fd_padding;
            cs.enable_brs = tx_info->enable_brs;
        #endif

            if (tx_info->is_remote)
            {
                cs.code = (uint32)FLEXCAN_TX_REMOTE;
            }
            else
            {
                cs.code = (uint32)FLEXCAN_TX_DATA;
            }

            FlexCAN_SetTxMsgBuff(base, mb_idx, &cs, msg_id, mb_data, FALSE);
        }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    }
#endif
    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_StartRxMessageFifoData
 * Description   : Initiate (start) a receive by beginning the process of
 * receiving data and enabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageFifoData(uint8 instance,
                                                          Flexcan_Ip_MsgBuffType * data)
{

    FLEXCAN_Type * base = NULL_PTR;
    Flexcan_Ip_StateType * state = NULL_PTR;
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    base = g_Flexcan_Ip_aBase[instance];
    state = g_flexcan_Ip_StatePtr[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    /* Check if RxFIFO feature is enabled */
    if (state->bIsLegacyFifoEn == FALSE)
    {
        eResult = FLEXCAN_STATUS_ERROR;
    }
    else
    {
#endif

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
    {
        if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_DMA_ERROR)
        {
            /* Check if FIFO has Pending Request that generated error,
            * the RxFIFO need to be empty to activate DMA */
        #if ((STD_ON == FLEXCAN_ENABLE_USER_MODE_SUPPORT) && (STD_OFF == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE))
            OsIf_Trusted_Call1param(FlexCAN_ClearOutputLegacyFIFO, base);
        #else
            FlexCAN_ClearOutputLegacyFIFO(base);
        #endif
            /* Change status of MB to be reconfigured with DMA transfer */
            state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
        }
    }
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */

    /* Start receiving fifo */
    if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state != FLEXCAN_MB_IDLE)
    {
        eResult = FLEXCAN_STATUS_BUSY;
    }
    else
    {
    state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_RX_BUSY;
    if (state->transferType == FLEXCAN_RXFIFO_USING_POLLING)
    {
        state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isPolling = TRUE;
    }

    /* This will get filled by the interrupt handler */
    state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage = data;

    if (state->transferType == FLEXCAN_RXFIFO_USING_INTERRUPTS)
    {
        state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isPolling = FALSE;
        /* Enable RX FIFO interrupts*/
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_WARNING, TRUE, state->isIntActive);
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_OVERFLOW, TRUE, state->isIntActive);
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, TRUE, state->isIntActive);
    }
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
    {
        Dma_Ip_ReturnType edmaStatus;

        Dma_Ip_LogicChannelTransferListType trasfer[CAN_TRASNFER_DIMENSION_LIST] = {
                {
                    .Param = DMA_IP_CH_SET_SOURCE_ADDRESS,
                    .Value = (uint32)FlexCAN_GetMsgBuffRegion(base, FLEXCAN_MB_HANDLE_RXFIFO)
                },
                {
                    .Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET ,
                    .Value = 4,
                },
                {
                    .Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE,
                    .Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
                },
                {
                    .Param = DMA_IP_CH_SET_DESTINATION_ADDRESS,
                    .Value = (uint32)(state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage)
                },
                {
                        .Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET,
                        .Value = 4,
                },
                {
                        .Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE,
                        .Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
                },
                {
                        .Param = DMA_IP_CH_SET_MINORLOOP_SIZE,
                        .Value = 16,
                },
                {
                        .Param = DMA_IP_CH_SET_MAJORLOOP_COUNT,
                        .Value = 1,
                },
                {
                        .Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT,
                        .Value = 1,
                },
                {
                        .Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST,
                        .Value = 1,
                },
        };
        edmaStatus = Dma_Ip_SetLogicChannelTransferList(state->rxFifoDMAChannel, &trasfer[0], CAN_TRASNFER_DIMENSION_LIST);

        if (edmaStatus != DMA_IP_STATUS_SUCCESS)
        {
            state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;

            eResult = FLEXCAN_STATUS_ERROR;
        }
        else
        {
        edmaStatus = Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
        if (edmaStatus != DMA_IP_STATUS_SUCCESS)
        {
            state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;

            eResult = FLEXCAN_STATUS_ERROR;
        }
        }
    }

#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    }
#endif
    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_IRQHandlerRxMB
 * Description   : Process IRQHandler in case of Rx MessageBuffer selection
 * for CAN interface.
 *
 * This is not a public API as it is called whenever an interrupt and receive
 * individual MB occurs
 *END**************************************************************************/
static void FlexCAN_IRQHandlerRxMB(uint8 instance,
                                   uint32 mb_idx)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    Flexcan_Ip_MsgBuffType data;
    boolean bCurrentIntStat = (boolean)FALSE;

    /* If use pass NULL_PTR, they can get data in callback function by getting state->mbs[mb_idx].pMBmessage  */
    if (NULL_PTR == state->mbs[mb_idx].pMBmessage)
    {
        state->mbs[mb_idx].pMBmessage = &data;
    }

    /* Lock RX message buffer and RX FIFO*/
    FlexCAN_LockRxMsgBuff(base, mb_idx);

    /* Get RX MB field values*/
    FlexCAN_GetMsgBuff(base, mb_idx, state->mbs[mb_idx].pMBmessage);

    FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

    /* Unlock RX message buffer and RX FIFO*/
    FlexCAN_UnlockRxMsgBuff(base);

    state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;

    bCurrentIntStat = state->mbs[mb_idx].isPolling;

    /* Invoke callback */
    if (state->callback != NULL_PTR)
    {
        state->callback(instance, FLEXCAN_EVENT_RX_COMPLETE, mb_idx, state);
    }

    if ((FLEXCAN_MB_IDLE == state->mbs[mb_idx].state) && ((boolean)FALSE == state->mbs[mb_idx].isPolling))
    {
        /* callback is not called, need to reset to default value */
        state->mbs[mb_idx].isPolling = (boolean)TRUE;
        /* Disable the transmitter data register empty interrupt for case: mb is interrupt (it was not use in above callback with the same index) */
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, FALSE, state->isIntActive);
    }
    else if (((boolean)FALSE == bCurrentIntStat) && ((boolean)TRUE == state->mbs[mb_idx].isPolling))
    {
        /* Disable the transmitter data register empty interrupt for case: switch from interrupt to polling for the same MB (called in above callback with same mb index) */
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, FALSE, state->isIntActive);
    }
    else
    {
        /* Prevent misra */
        /* When processing type change from POLL->POLL or INTERRUPT -> INTERRUPT(this Mb is used continously in callback), no need to disable interrupt in the ISR */
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_IRQHandlerTxMB
 * Description   : Process IRQHandler in case of Tx MessageBuffer selection
 * for CAN interface.
 * note: just using in interrupt mode
 * This is not a public API as it is called whenever an interrupt and receive
 * individual MB occurs
 *END**************************************************************************/
static void FlexCAN_IRQHandlerTxMB(uint8 u8Instance, uint32 u32MbIdx)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    Flexcan_Ip_StateType * pState = g_flexcan_Ip_StatePtr[u8Instance];
    Flexcan_Ip_MsgBuffType mb;
    boolean bCurrentIntStat = (boolean)FALSE;

    if (pState->mbs[u32MbIdx].isRemote)
    {
        FlexCAN_LockRxMsgBuff(pBase, u32MbIdx);
        FlexCAN_GetMsgBuff(pBase, u32MbIdx, &mb);
        FlexCAN_UnlockRxMsgBuff(pBase);
        pState->mbs[u32MbIdx].time_stamp = mb.time_stamp;
        /* If the frame was a remote frame, clear the flag only if the response was
        * not received yet. If the response was received, leave the flag set in order
        * to be handled when the user calls FLEXCAN_DRV_RxMessageBuffer. */
        if (((mb.cs & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_RX_EMPTY)
        {
            FlexCAN_ClearMsgBuffIntStatusFlag(pBase, u32MbIdx);
        }
    }
    else
    {
        pState->mbs[u32MbIdx].time_stamp = FlexCAN_GetMsgBuffTimestamp(pBase, u32MbIdx);
        FlexCAN_UnlockRxMsgBuff(pBase);
        FlexCAN_ClearMsgBuffIntStatusFlag(pBase, u32MbIdx);
    }

    pState->mbs[u32MbIdx].state = FLEXCAN_MB_IDLE;

    bCurrentIntStat = pState->mbs[u32MbIdx].isPolling;

    /* Invoke callback */
    if (pState->callback != NULL_PTR)
    {
        pState->callback(u8Instance, FLEXCAN_EVENT_TX_COMPLETE, u32MbIdx, pState);
    }

    if ((FLEXCAN_MB_IDLE == pState->mbs[u32MbIdx].state) && ((boolean)FALSE == pState->mbs[u32MbIdx].isPolling))
    {
        /* callback is not called, need to reset to default value */
        pState->mbs[u32MbIdx].isPolling = (boolean)TRUE;
        /* Disable the transmitter data register empty interrupt for case: mb is interrupt (it was not use in above callback with the same index) */
        (void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, u32MbIdx, FALSE, pState->isIntActive);
    }
    else if (((boolean)FALSE == bCurrentIntStat) && ((boolean)TRUE == pState->mbs[u32MbIdx].isPolling))
    {
        /* Disable the transmitter data register empty interrupt for case: switch from interrupt to polling for the same MB (called in above callback with same mb index) */
        (void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, u32MbIdx, FALSE, pState->isIntActive);
    }
    else
    {
        /* Prevent misra */
        /* When processing type change from POLL->POLL or INTERRUPT -> INTERRUPT(this Mb is used continously in callback), no need to disable interrupt in the ISR */
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_IRQHandlerRxFIFO
 * Description   : Process IRQHandler in case of RxFIFO mode selection for CAN interface.
 *
 *END**************************************************************************/
static inline void FlexCAN_IRQHandlerRxFIFO(uint8 instance,
                                            uint32 mb_idx)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    Flexcan_Ip_MsgBuffType data;

    /* If use pass NULL_PTR, they can get data in callback function by getting state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage  */
    if (NULL_PTR == state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage)
    {
        state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage = &data;
    }
    switch (mb_idx)
    {
        case CAN_LEGACY_RXFIFO_FRAME_AVAILABLE:
            if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_RX_BUSY)
            {
                /* Get RX FIFO field values */
                FlexCAN_ReadRxFifo(base, state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage);

                FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

                state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;

                /* Invoke callback */
                if (state->callback != NULL_PTR)
                {
                    state->callback(instance, FLEXCAN_EVENT_RXFIFO_COMPLETE, FLEXCAN_MB_HANDLE_RXFIFO, state);
                }

                if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_IDLE)
                {
                    /* reset to default value */
                    state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isPolling = (boolean)TRUE;
                    /* Complete receive data */
                    FlexCAN_CompleteRxMessageFifoData(instance);
                }
            }

            break;
        case CAN_LEGACY_RXFIFO_WARNING:
            FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

            /* Invoke callback */
            if (state->callback != NULL_PTR)
            {
                state->callback(instance, FLEXCAN_EVENT_RXFIFO_WARNING, FLEXCAN_MB_HANDLE_RXFIFO, state);
            }

            break;
        case CAN_LEGACY_RXFIFO_OVERFLOW:
            FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

            /* Invoke callback */
            if (state->callback != NULL_PTR)
            {
                state->callback(instance, FLEXCAN_EVENT_RXFIFO_OVERFLOW, FLEXCAN_MB_HANDLE_RXFIFO, state);
            }

            break;
        default:
            /* Do Nothing */
            break;
    }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_ProcessSpuriousInterruptMB
 * Description   : clear Iflag when spurious interrupt occurred.
 * note: just use in FlexCAN_IRQHandler
 *END**************************************************************************/
static inline void FlexCAN_ProcessSpuriousInterruptMB(uint8 instance, uint32 startMbIdx, uint32 endMbIdx)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    uint32 mb_idx = 0U;
    uint32 u32MbHandle = 0U;

    /* Process spurious interrupt */
    for (mb_idx = startMbIdx; mb_idx <= endMbIdx; mb_idx++)
    {
        if (((uint8)0U != FlexCAN_GetBuffStatusFlag(base, mb_idx)) && ((uint8)0U == FlexCAN_GetBuffStatusImask(base, mb_idx)))
        {
                u32MbHandle = mb_idx;
                if (((boolean)TRUE == state->bIsLegacyFifoEn) && (mb_idx <= CAN_LEGACY_RXFIFO_OVERFLOW))
                {
                    u32MbHandle = (uint32)FLEXCAN_MB_HANDLE_RXFIFO;
                }
                if (((boolean)FALSE == state->mbs[u32MbHandle].isPolling))
                {
                    /* clear the MB flag */
                    FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
                    if (FLEXCAN_MB_TX_BUSY == state->mbs[u32MbHandle].state)
                    {
                        /* reset to default state */
                        state->mbs[u32MbHandle].state = FLEXCAN_MB_IDLE;
                        state->mbs[u32MbHandle].isPolling = (boolean)TRUE;
                    }
                }
        }
    }
}

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_ProcessIRQHandlerEnhancedRxFIFO
 * Description   : Process IRQHandler in case of Enhanced RxFIFO mode selection for CAN interface.
 * note: just use in FlexCAN_IRQHandler
 *END**************************************************************************/
static inline boolean FlexCAN_ProcessIRQHandlerEnhancedRxFIFO(uint8 u8Instance, boolean bIsSpuriousIntPrevious)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[u8Instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
    uint32 u32intType = 0U;
    boolean bIsSpuriousInt = bIsSpuriousIntPrevious;

            /* Get the interrupts that are enabled and ready */
            for (u32intType = CAN_ENHANCED_RXFIFO_UNDERFLOW; u32intType >= CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE; u32intType--)
            {
                if ((uint8)0U != FlexCAN_GetEnhancedRxFIFOStatusFlag(base, u32intType))
                {
                    if ((uint8)0U != FlexCAN_GetEnhancedRxFIFOIntStatusFlag(base, u32intType))
                    {
                        FlexCAN_IRQHandlerEnhancedRxFIFO(u8Instance, u32intType);
                        bIsSpuriousInt = (boolean)FALSE;
                    }
                    /* just process spurious interrupt when no real interrupt at all */
                    else if (((boolean)TRUE == bIsSpuriousInt) && ((boolean)FALSE == state->enhancedFifoOutput.isPolling))
                    {
                            /* Process spurious interrupt */
                            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, u32intType);
                    }
                    else
                    {
                        /* prevent misra */
                    }
                }
            }

    return bIsSpuriousInt;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_IRQHandlerEnhancedRxFIFO
 * Description   : Process IRQHandler in case of Enhanced RxFIFO mode selection for CAN interface.
 *
 * Implements    : FLEXCAN_IRQHandlerEnyhancedRxFIFO_Activity
 *END**************************************************************************/
static void FlexCAN_IRQHandlerEnhancedRxFIFO(uint8 instance,
                                      uint32 intType)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    Flexcan_Ip_MsgBuffType data;

    switch (intType)
    {
        case CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE:
            if (state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY)
            {
                /* If use pass NULL_PTR, they can get data in callback function by getting state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage  */
                if (NULL_PTR == state->enhancedFifoOutput.pMBmessage)
                {
                    state->enhancedFifoOutput.pMBmessage = &data;
                }

                /* Get Enhanced RX FIFO field values */
                FlexCAN_ReadEnhancedRxFifo(base, state->enhancedFifoOutput.pMBmessage);

                FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);
                FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_WATERMARK);
                FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_OVERFLOW);
                state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;

                /* Invoke callback */
                if (state->callback != NULL_PTR)
                {
                    state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_COMPLETE, FLEXCAN_MB_ENHANCED_RXFIFO, state);
                }

                if (state->enhancedFifoOutput.state == FLEXCAN_MB_IDLE)
                {
                    /* Complete receive data */
                    FlexCAN_CompleteRxMessageEnhancedFifoData(instance);
                }
            }

            break;
        case CAN_ENHANCED_RXFIFO_WATERMARK:
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);

            /* Invoke callback */
            if (state->callback != NULL_PTR)
            {
                state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_WATERMARK, FLEXCAN_MB_ENHANCED_RXFIFO, state);
            }

            break;
        case CAN_ENHANCED_RXFIFO_OVERFLOW:
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);

            /* Invoke callback */
            if (state->callback != NULL_PTR)
            {
                state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_OVERFLOW, FLEXCAN_MB_ENHANCED_RXFIFO, state);
            }

            break;
        case CAN_ENHANCED_RXFIFO_UNDERFLOW:
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);

            /* Invoke callback */
            if (state->callback != NULL_PTR)
            {
                state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_UNDERFLOW, FLEXCAN_MB_ENHANCED_RXFIFO, state);
            }

            break;
        default:
            /* Do Nothing */
            break;
    }
}

#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
static void DMA_Can_Callback(uint8 instance)
{
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
    {
        if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
        {
            /* Need to add handler for Enhaced RxFifoDataDMA */
            FlexCAN_CompleteRxMessageEnhancedFifoData(instance);
        }
        else
        {
            FlexCAN_CompleteRxMessageFifoData(instance);
        }
    }
    else
#endif
    {
        FlexCAN_CompleteRxMessageFifoData(instance);
    }
}
#endif

#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_SetUserAccessAllowed
 * Description   : Sets the UAA bit in REG_PROT to make the instance accessible
 * in user mode.
 *
 * This is not a public API as it is called from other driver functions.
 *END**************************************************************************/
static void FlexCAN_SetUserAccessAllowed(const FLEXCAN_Type * pBase)
{
    SET_USER_ACCESS_ALLOWED((uint32)pBase, FLEXCAN_PROT_MEM_U32);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_ClrUserAccessAllowed
 * Description   : Clears the UAA bit in REG_PROT to make the instance accessible
 * in user mode.
 *
 * This is not a public API as it is called from other driver functions.
 *END**************************************************************************/
static void FlexCAN_ClrUserAccessAllowed(const FLEXCAN_Type * pBase)
{
    CLR_USER_ACCESS_ALLOWED((uint32)pBase, FLEXCAN_PROT_MEM_U32);
}
#endif /* (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE) */

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_AbortTxTransfer
 * Description   : Abort transfer for Tx buffer.
 *
 * This is not a public API as it is called from other driver functions.
 *END**************************************************************************/
static Flexcan_Ip_StatusType FlexCAN_AbortTxTransfer(uint8 u8Instance, uint8 mb_idx)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;

    uint32 timeStart = 0U;
    uint32 timeElapsed = 0U;
    uint32 flexcan_mb_config = 0;
    uint32 uS2Ticks = 0U;
    volatile uint32 * flexcan_mb = NULL_PTR;

    flexcan_mb = FlexCAN_GetMsgBuffRegion(pBase, mb_idx);
    flexcan_mb_config = * flexcan_mb;
    /* Reset the code */
    flexcan_mb_config &= (~CAN_CS_CODE_MASK);
    flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_TX_ABORT & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
    *flexcan_mb = flexcan_mb_config;

    /* Wait to finish abort operation */
    uS2Ticks = OsIf_MicrosToTicks(CAN_TIMEOUT_DURATION, CAN_SERVICE_TIMEOUT_TYPE);
    timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
    while (FlexCAN_GetBuffStatusFlag(pBase, mb_idx) == 0U)
    {
        timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
        if (timeElapsed >= uS2Ticks)
        {
            result = FLEXCAN_STATUS_TIMEOUT;
            break;
        }
    }
    if (result != FLEXCAN_STATUS_TIMEOUT)
    {
        flexcan_mb_config = *flexcan_mb;
        /* Check if the MBs have been safely Inactivated */
        if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_INACTIVE)
        {
            /* Transmission have occurred */
            result = FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
        }

        if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_ABORT)
        {
            /* Transmission have been aborted */
            result = FLEXCAN_STATUS_SUCCESS;
        }
    }
    /* Clear message buffer flag */
    FlexCAN_ClearMsgBuffIntStatusFlag(pBase, mb_idx);
    state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_AbortRxTransfer
 * Description   : Abort transfer for Rx normal or legacy fifo if enabled.
 *
 * This is not a public API as it is called from other driver functions.
 *END**************************************************************************/
static void FlexCAN_AbortRxTransfer(uint8 u8Instance,
                                                uint8 mb_idx)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
    uint32 val1 = 0U;
    uint32 val2 = 0U;
    uint32 flexcan_mb_config = 0;
    volatile uint32 * flexcan_mb = NULL_PTR;

    state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
    /* Check if fifo enabled */
    if ((boolean)TRUE == state->bIsLegacyFifoEn)
    {
        /* Get the number of RX FIFO Filters*/
        val1 = (((pBase->CTRL2) & FLEXCAN_CTRL2_RFFN_MASK) >> FLEXCAN_CTRL2_RFFN_SHIFT);
        /* Get the number if MBs occupied by RX FIFO and ID filter table*/
        /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
        /* Every number of RFFN means 8 number of RX FIFO filters*/
        /* and every 4 number of RX FIFO filters occupied one MB*/
        val2 = RxFifoOcuppiedLastMsgBuff(val1);
        if (mb_idx > val2)
        {
            /* This operation is not allowed for MB that are part of RxFIFO */
            flexcan_mb = FlexCAN_GetMsgBuffRegion(pBase, mb_idx);
            flexcan_mb_config = * flexcan_mb;
            /* Reset the code and unlock the MB */
            flexcan_mb_config &= (uint32)(~CAN_CS_CODE_MASK);
            flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_INACTIVE & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
            *flexcan_mb = flexcan_mb_config;
            /* Reconfigure The MB as left by RxMBconfig */
            flexcan_mb_config &= (~CAN_CS_CODE_MASK);
            flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_EMPTY & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
            *flexcan_mb = flexcan_mb_config;
        }
        if (FLEXCAN_MB_HANDLE_RXFIFO == mb_idx)
        {
            FLEXCAN_ClearMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, state->isIntActive);
        #if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
            if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
            {
                (void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
            }
        #endif
        }
    }
    else
    {
        /* This operation is not allowed for MB that are part of RxFIFO */
        flexcan_mb = FlexCAN_GetMsgBuffRegion(pBase, mb_idx);
        flexcan_mb_config = * flexcan_mb;
        /* Reset the code and unlock the MB */
        flexcan_mb_config &= (~CAN_CS_CODE_MASK);
        flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_INACTIVE & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
        *flexcan_mb = flexcan_mb_config;
        /* Reconfigure The MB as left by RxMBconfig */
        flexcan_mb_config &= (~CAN_CS_CODE_MASK);
        flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_EMPTY & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
        *flexcan_mb = flexcan_mb_config;
    }
    /* Clear message buffer flag */
    FlexCAN_ClearMsgBuffIntStatusFlag(pBase, mb_idx);
}
/*==================================================================================================
*                                       GLOBAL FUNCTIONS
==================================================================================================*/
/* implements FlexCAN_Ip_Init_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_Init_Privileged(uint8 Flexcan_Ip_u8Instance,
                                      Flexcan_Ip_StateType * Flexcan_Ip_pState,
                                      const Flexcan_Ip_ConfigType * Flexcan_Ip_pData)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[Flexcan_Ip_u8Instance];
    uint32 i;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(Flexcan_Ip_u8Instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(Flexcan_Ip_pData != NULL_PTR);
#endif

#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
    /* Set the UAA bit in REG_PROT to make the instance accessible in user mode */
    if (Flexcan_Ip_u8Instance < FLEXCAN_CTRL_REG_PROT_SUPPORT_U8)
    {
        OsIf_Trusted_Call1param(FlexCAN_SetUserAccessAllowed, pBase);
    }
#endif

    eResult = FlexCAN_InitController(pBase, Flexcan_Ip_pData);
    if (FLEXCAN_STATUS_SUCCESS == eResult)
    {
    /* Enable the use of extended bit time definitions */
    FlexCAN_EnableExtCbt(pBase, Flexcan_Ip_pData->fd_enable);

    if(Flexcan_Ip_pData->enhCbtEnable)
    {
        /* Start critical section: implementation depends on integrator */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();
        /* Enable Enhanced CBT time segments */
        pBase->CTRL2 |= FLEXCAN_CTRL2_BTE_MASK;
        FlexCAN_SetEnhancedNominalTimeSegments(pBase, &Flexcan_Ip_pData->bitrate);
#if (FEATURE_CAN_HAS_FD == STD_ON)
        if (Flexcan_Ip_pData->fd_enable)
        {
            FlexCAN_SetEnhancedDataTimeSegments(pBase, &Flexcan_Ip_pData->bitrate_cbt);
        }
#endif
        /* End critical section: implementation depends on integrator */
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
    }
    else
    {
        /* Start critical section: implementation depends on integrator */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();
        /* Disable Enhanced CBT time segments */
        pBase->CTRL2 &= ~FLEXCAN_CTRL2_BTE_MASK;
#if (FEATURE_CAN_HAS_FD == STD_ON)
        /* Set bit rate. */
        if (Flexcan_Ip_pData->fd_enable)
        {
            /* Write Normal bit time configuration to CBT register */
            FlexCAN_SetExtendedTimeSegments(pBase, &Flexcan_Ip_pData->bitrate);
            /* Write Data bit time configuration to FDCBT register */
            FlexCAN_SetFDTimeSegments(pBase, &Flexcan_Ip_pData->bitrate_cbt);
        }
        else
        {
            /* Write Normal bit time configuration to CTRL1 register */
            FlexCAN_SetTimeSegments(pBase, &Flexcan_Ip_pData->bitrate);
        }
#endif
        /* End critical section: implementation depends on integrator */
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
    }

    /* Select mode */
    FlexCAN_SetOperationMode(pBase, Flexcan_Ip_pData->flexcanMode);

#if (STD_ON == FLEXCAN_ENABLE_USER_MODE_SUPPORT)
    #if (STD_ON == FEATURE_CAN_HAS_SUPV)
    pBase->MCR = (pBase->MCR & ~FLEXCAN_MCR_SUPV_MASK) | FLEXCAN_MCR_SUPV(0U);
    #endif
#endif

    /* Leave driver in FreezMode if successfully initialized */
    eResult  = FlexCAN_EnterFreezeMode(pBase);
    if (FLEXCAN_STATUS_SUCCESS == eResult)
    {
#if (FEATURE_CAN_HAS_HR_TIMER == STD_ON)
    FlexCAN_ConfigTimestamp(pBase, (Flexcan_Ip_TimeStampConfigType *)&Flexcan_Ip_pData->time_stamp);
#endif   /* (FEATURE_CAN_HAS_HR_TIMER == STD_ON) */

    for (i = 0; i < (uint8)FEATURE_CAN_MAX_MB_NUM; i++)
    {
        /* Check if blocking need to be any more present in sync\async discussions */
        /* Sync up isPolling status with hw (Imask), at the begining all Imask = 0 => isPolling = TRUE */
        Flexcan_Ip_pState->mbs[i].isPolling = (boolean)TRUE;
        Flexcan_Ip_pState->mbs[i].pMBmessage = NULL_PTR;
        Flexcan_Ip_pState->mbs[i].state = FLEXCAN_MB_IDLE;
        Flexcan_Ip_pState->mbs[i].time_stamp = 0U;
    }
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    /* Sync up isPolling status with hw (Imask), at the begining all Imask = 0 => isPolling = TRUE */
    Flexcan_Ip_pState->enhancedFifoOutput.isPolling = (boolean)TRUE;
    Flexcan_Ip_pState->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
#endif

    Flexcan_Ip_pState->transferType = Flexcan_Ip_pData->transfer_type;
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    Flexcan_Ip_pState->rxFifoDMAChannel = Flexcan_Ip_pData->rxFifoDMAChannel;
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    Flexcan_Ip_pState->u32NumOfMbTransferByDMA = Flexcan_Ip_pData->num_enhanced_watermark;
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
#endif

    /* Clear Callbacks in case of autovariables garbage */
    Flexcan_Ip_pState->callback = Flexcan_Ip_pData->Callback;
    Flexcan_Ip_pState->callbackParam = NULL_PTR;
    Flexcan_Ip_pState->error_callback = Flexcan_Ip_pData->ErrorCallback;
    Flexcan_Ip_pState->errorCallbackParam = NULL_PTR;
    Flexcan_Ip_pState->bIsLegacyFifoEn = Flexcan_Ip_pData->is_rx_fifo_needed;
    Flexcan_Ip_pState->u32MaxMbNum = Flexcan_Ip_pData->max_num_mb;
    Flexcan_Ip_pState->isIntActive = TRUE;
    /* Save runtime structure pointers so irq handler can point to the correct state structure */
    g_flexcan_Ip_StatePtr[Flexcan_Ip_u8Instance] = Flexcan_Ip_pState;
    }
    }
    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_DRV_Send
 * Description   : This function sends a CAN frame using a configured message
 * buffer. The function returns immediately. If a callback is installed, it will
 * be invoked after the frame was sent.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_Send_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_Send(uint8 instance,
                          uint8 mb_idx,
                          const Flexcan_Ip_DataInfoType * tx_info,
                          uint32 msg_id,
                          const uint8 * mb_data)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
#else
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#endif

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(tx_info != NULL_PTR);
#endif
    if(!FlexCAN_IsListenOnlyModeEnabled(base))
    {
        result = FlexCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data);
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
        if ((FLEXCAN_STATUS_SUCCESS ==  result) && (FALSE == tx_info->is_polling))
        {
            /* Enable message buffer interrupt*/
            result = FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, TRUE, state->isIntActive);
        }
#endif
    }
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ConfigMb
 * Description   : Configure a Rx message buffer.
 * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
 * the function will make sure if the MB requested is not occupied by RX FIFO
 * and ID filter table. Then this function will set up the message buffer fields,
 * configure the message buffer code for Rx message buffer as NOT_USED, enable
 * the Message Buffer interrupt, configure the message buffer code for Rx
 * message buffer as INACTIVE, copy user's buffer into the message buffer data
 * area, and configure the message buffer code for Rx message buffer as EMPTY.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_ConfigRxMb_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigRxMb(uint8 instance,
                               uint8 mb_idx,
                               const Flexcan_Ip_DataInfoType * rx_info,
                               uint32 msg_id)
{
    Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_MsbuffCodeStatusType cs;
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(rx_info != NULL_PTR);

    if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(base, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
    {
        eResult = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
    }
    else
    {
#endif
        /* Clear the message buffer flag if previous remained triggered */
        FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

        cs.dataLen = rx_info->data_length;
        cs.msgIdType = rx_info->msg_id_type;
    #if (FEATURE_CAN_HAS_FD == STD_ON)
        cs.fd_enable = rx_info->fd_enable;
    #endif

        /* Initialize rx mb*/
        cs.code = (uint32)FLEXCAN_RX_NOT_USED;
        FlexCAN_SetRxMsgBuff(base, mb_idx, &cs, msg_id);

        /* Initialize receive MB*/
        cs.code = (uint32)FLEXCAN_RX_INACTIVE;
        FlexCAN_SetRxMsgBuff(base, mb_idx, &cs, msg_id);

        /* Set up FlexCAN message buffer fields for receiving data*/
        cs.code = (uint32)FLEXCAN_RX_EMPTY;
        FlexCAN_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    }
#endif
    return eResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_Receive
 * Description   : This function receives a CAN frame into a configured message
 * buffer. The function returns immediately. If a callback is installed, it will
 * be invoked after the frame was received and read into the specified buffer.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_Receive_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_Receive(uint8 instance,
                                       uint8 mb_idx,
                                       Flexcan_Ip_MsgBuffType * data,
                                       boolean isPolling)
{

    Flexcan_Ip_StatusType result;
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
#endif
    #if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    #endif

    result = FlexCAN_StartRxMessageBufferData(instance, mb_idx, data, isPolling);
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
    if ((result == FLEXCAN_STATUS_SUCCESS) && (FALSE == isPolling))
    {
        /* Enable MB interrupt*/
        result = FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, TRUE, state->isIntActive);
    }
#endif
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ReceiveBlocking
 * Description   : This function receives a CAN frame into a configured message
 * buffer. The function blocks until either a frame was received, or the
 * specified timeout expired.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_ReceiveBlocking_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ReceiveBlocking(uint8 instance,
                                                 uint8 mb_idx,
                                                 Flexcan_Ip_MsgBuffType * data,
                                                 boolean isPolling,
                                                 uint32 u32TimeoutMs)
{
    Flexcan_Ip_StatusType result;
    uint32 timeStart = 0U;
    uint32 timeElapsed = 0U;
    uint32 mS2Ticks = OsIf_MicrosToTicks((u32TimeoutMs * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#else
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#endif
    result = FlexCAN_StartRxMessageBufferData(instance, mb_idx, data, isPolling);
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
    if ((result == FLEXCAN_STATUS_SUCCESS) && (FALSE == isPolling))
    {
        /* Enable MB interrupt*/
        result = FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, TRUE, state->isIntActive);
    }
#endif
    if (FLEXCAN_STATUS_SUCCESS == result)
    {
        timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
        while (FLEXCAN_MB_RX_BUSY == state->mbs[mb_idx].state)
        {
            if (TRUE == isPolling)
            {
                if (FlexCAN_GetBuffStatusFlag(base, mb_idx) != 0U)
                {
                    FlexCAN_IRQHandlerRxMB(instance, mb_idx);
                }
            }
            timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
            if (timeElapsed >= mS2Ticks)
            {
                result = FLEXCAN_STATUS_TIMEOUT;
                break;
            }
        }
    }

    if ((FLEXCAN_STATUS_TIMEOUT == result) && (FALSE == isPolling))
    {
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
        /* Disable Mb interrupt*/
       (void)FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, (boolean)FALSE, state->isIntActive);
#endif
    }

    if ((FLEXCAN_STATUS_BUFF_OUT_OF_RANGE != result) && (FLEXCAN_STATUS_BUSY != result))
    {
        if ((FLEXCAN_MB_IDLE == state->mbs[mb_idx].state))
        {
            result = FLEXCAN_STATUS_SUCCESS;
        }
        else
        {
            state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
            result = FLEXCAN_STATUS_TIMEOUT;
        }
    }
    return result;
}

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)

void DMA_Can_Callback0(void)
{ DMA_Can_Callback(0U); }

#if FLEXCAN_INSTANCE_COUNT > 1U
void DMA_Can_Callback1(void)
{ DMA_Can_Callback(1U); }
#endif
#if FLEXCAN_INSTANCE_COUNT > 2U
void DMA_Can_Callback2(void)
{ DMA_Can_Callback(2U); }
#endif
#if FLEXCAN_INSTANCE_COUNT > 3U
void DMA_Can_Callback3(void)
{ DMA_Can_Callback(3U); }
#endif
#if FLEXCAN_INSTANCE_COUNT > 4U
void DMA_Can_Callback4(void)
{ DMA_Can_Callback(4U); }
#endif
#if FLEXCAN_INSTANCE_COUNT > 5U
void DMA_Can_Callback5(void)
{ DMA_Can_Callback(5U); }
#endif
#if FLEXCAN_INSTANCE_COUNT > 6U
void DMA_Can_Callback6(void)
{ DMA_Can_Callback(6U); }
#endif


#endif /* FEATURE_CAN_HAS_DMA_ENABLE */



/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_RxFifo
 * Description   : This function receives a CAN frame using the Rx FIFO or
 * Enhanced Rx FIFO (if available and enabled). If use Enhanced Rx FIFO, the size of
 * the data array will be considered the same as the configured FIFO watermark.
 * The function returns immediately. If a callback is installed, it will be invoked
 * after the frame was received and read into the specified buffer.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_RxFifo_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_RxFifo(uint8 instance,
                                        Flexcan_Ip_MsgBuffType * data)
{
#ifdef MCAL_ENABLE_FAULT_INJECTION
    /* Fault injection point to test dma error event */
    MCAL_FAULT_INJECTION_POINT(CAN_FIP_0_DMA_ERROR_EVENT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
    {
        if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
        {
            result = FlexCAN_StartRxMessageEnhancedFifoData(instance, data);
        }
        else
        {
            result = FlexCAN_StartRxMessageFifoData(instance, data);
        }
    }
    else
#endif /*FEATURE_CAN_HAS_ENHANCED_RX_FIFO*/
    {
        result = FlexCAN_StartRxMessageFifoData(instance, data);
    }
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_RxFifoBlocking
 * Description   : This function receives a CAN frame using the Rx FIFO or
 * Enhanced Rx FIFO (if available and enabled). If use Enhanced Rx FIFO, the size of
 * the data array will be considered the same as the configured FIFO watermark.
 * The function blocks until either a frame was received, or the specified timeout expired.
 *
 *END**************************************************************************/

/* implements FlexCAN_Ip_RxFifoBlocking_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_RxFifoBlocking(uint8 instance, Flexcan_Ip_MsgBuffType *data, uint32 timeout)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)

    if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
    {
        if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
        {
            result = FlexCAN_StartRxMessageEnhancedFifoData(instance, data);
            if (FLEXCAN_STATUS_SUCCESS == result)
            {
                result = FlexCAN_ProccessEnhancedRxFifo(instance, timeout);
            }
        }
        else
        {
            result = FlexCAN_StartRxMessageFifoData(instance, data);
            if (FLEXCAN_STATUS_SUCCESS == result)
            {
                result = FlexCAN_ProccessLegacyRxFIFO(instance, timeout);
            }
        }
    }
    else
#endif /*FEATURE_CAN_HAS_ENHANCED_RX_FIFO*/
    {
        result = FlexCAN_StartRxMessageFifoData(instance, data);
        if (FLEXCAN_STATUS_SUCCESS == result)
        {
            result = FlexCAN_ProccessLegacyRxFIFO(instance, timeout);
        }
    }
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ConfigRxFifo
 * Description   : Confgure RX FIFO ID filter table elements.
 * This function will confgure RX FIFO ID filter table elements, and enable RX
 * FIFO interrupts.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_ConfigRxFifo_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigRxFifo_Privileged(uint8 instance,
                              Flexcan_Ip_RxFifoIdElementFormatType id_format,
                              const Flexcan_Ip_IdTableType * id_filter_table)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);
    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        /* Initialize rx fifo*/
        FlexCAN_SetRxFifoFilter(pBase, id_format, id_filter_table);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ConfigEnhancedRxFifo
 * Description   : Confgure Enhanced RX FIFO ID filter table elements.
 * This function will confgure Enhanced RX FIFO ID filter table elements, and enable Enhanced RX
 * FIFO interrupts.
 *END**************************************************************************/
/* implements FlexCAN_Ip_ConfigEnhancedRxFifo_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigEnhancedRxFifo_Privileged(uint8 instance,
                                                 const Flexcan_Ip_EnhancedIdTableType * id_filter_table)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(FlexCAN_IsEnhancedRxFifoAvailable(pBase));
    DevAssert(id_filter_table != NULL_PTR);
#endif

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);
    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        /* Initialize rx fifo*/
        FlexCAN_SetEnhancedRxFifoFilter(pBase, id_filter_table);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ConfigRemoteResponseMb
 * Description   : Configures a transmit message buffer for remote frame
 * response. This function will first check if RX FIFO is enabled. If RX FIFO is
 * enabled, the function will make sure if the MB requested is not occupied by
 * the RX FIFO and ID filter table. Then this function will set up the message
 * buffer fields, configure the message buffer code for Tx buffer as RX_RANSWER,
 * and enable the Message Buffer interrupt if required by user.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_ConfigRemoteResponseMb_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigRemoteResponseMb(uint8 instance,
                                                        uint8 mb_idx,
                                                        const Flexcan_Ip_DataInfoType *tx_info,
                                                        uint32 msg_id,
                                                        const uint8 *mb_data)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_MsbuffCodeStatusType cs;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * const state = g_flexcan_Ip_StatePtr[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(tx_info != NULL_PTR);

    if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(pBase, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
    {
        result = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
    }
#endif
    if (FLEXCAN_STATUS_SUCCESS == result)
    {
        /* Initialize transmit mb*/
        cs.dataLen = tx_info->data_length;
        cs.msgIdType = tx_info->msg_id_type;
        cs.code = (uint32)FLEXCAN_RX_RANSWER;
#if (FEATURE_CAN_HAS_FD == STD_ON)
        cs.fd_enable = (boolean)FALSE;
#endif
        FlexCAN_ClearMsgBuffIntStatusFlag(pBase, mb_idx);
        FlexCAN_SetTxMsgBuff(pBase, mb_idx, &cs, msg_id, mb_data, tx_info->is_remote);
        if (tx_info->is_polling == FALSE)
        {
            /* Enable MB interrupt*/
            result = FlexCAN_SetMsgBuffIntCmd(pBase, instance, mb_idx, TRUE, state->isIntActive);
        }
    }
    return result;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetTransferStatus
 * Description   : This function returns whether the previous FLEXCAN receive is
 *                 completed.
 * When performing a non-blocking receive, the user can call this function to
 * ascertain the state of the current receive progress: in progress (or busy)
 * or complete (success). In case Enhanced Rx Fifo, mb_idx will be 255.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetTransferStatus_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_GetTransferStatus(uint8 instance,
                                                 uint8 mb_idx)
{

    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_ERROR;


#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert((mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM) || (mb_idx == 255u));
#endif

    if (mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM)
    {
        if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
        {
            status = FLEXCAN_STATUS_SUCCESS;
        }

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
        else if (state->mbs[mb_idx].state == FLEXCAN_MB_DMA_ERROR)
        {
            status = FLEXCAN_STATUS_ERROR;
        }
#endif
        else
        {
            status = FLEXCAN_STATUS_BUSY;
        }
    }

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    else
    {
        if (state->enhancedFifoOutput.state == FLEXCAN_MB_IDLE)
        {
            status = FLEXCAN_STATUS_SUCCESS;
        }

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
        else if (state->enhancedFifoOutput.state == FLEXCAN_MB_DMA_ERROR)
        {
            status = FLEXCAN_STATUS_ERROR;
        }
#endif
        else
        {
            status = FLEXCAN_STATUS_BUSY;
        }
    }
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */

    return status;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_CompleteRxMessageFifoData
 * Description   : Finish up a receive by completing the process of receiving
 * data and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void FlexCAN_CompleteRxMessageFifoData(uint8 instance)
{

    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    if (state->transferType == FLEXCAN_RXFIFO_USING_INTERRUPTS)
    {
        /* Disable RX FIFO interrupts*/
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, FALSE, state->isIntActive);
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_WARNING, FALSE, state->isIntActive);
        (void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_OVERFLOW, FALSE, state->isIntActive);
    }

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    else if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
    {
        Dma_Ip_LogicChannelStatusType dmaStatus;
        Dma_Ip_GetLogicChannelStatus(state->rxFifoDMAChannel, &dmaStatus);
        
        if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
        {
            (void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_ERROR);

            state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_DMA_ERROR;
        }

        (void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);

        if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state != FLEXCAN_MB_DMA_ERROR)
        {
            Flexcan_Ip_MsgBuffType * fifo_message = state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage;
            uint32 * msgData_32 = (uint32 *)fifo_message->data;

            /* Adjust the ID if it is not extended */
            if (((fifo_message->cs) & CAN_CS_IDE_MASK) == 0U)
            {
                fifo_message->msgId = fifo_message->msgId >> CAN_ID_STD_SHIFT;
            }

            /* Extract the data length */
            fifo_message->dataLen = (uint8)((fifo_message->cs & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
            /* Extract the IDHIT */
            fifo_message->id_hit = (uint8)((fifo_message->cs & CAN_CS_IDHIT_MASK) >> CAN_CS_IDHIT_SHIFT);
            /* Extract the Time Stamp */
            fifo_message->time_stamp = (uint32)((fifo_message->cs & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
            /* Reverse the endianness */
            FlexcanSwapBytesInWord(msgData_32[0], msgData_32[0]);
            FlexcanSwapBytesInWord(msgData_32[1], msgData_32[1]);
        }
    }
    else
    {
        /* do nothing when transferType is POLLING */
    }
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
    /* Clear fifo message*/
    state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage = NULL_PTR;

#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state != FLEXCAN_MB_DMA_ERROR)
    {
        state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
        if ((state->callback != NULL_PTR) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
        {
            state->callback(instance, FLEXCAN_EVENT_DMA_COMPLETE, FLEXCAN_MB_HANDLE_RXFIFO, state);
        }
    }
    else
    {
        if (state->callback != NULL_PTR)
        {
            state->callback(instance, FLEXCAN_EVENT_DMA_ERROR, FLEXCAN_MB_HANDLE_RXFIFO, state);
        }
    }

#else
    state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_IRQHandler
 * Description   : Interrupt handler for FLEXCAN.
 * This handler read data from MB or FIFO, and then clear the interrupt flags.
 * This is not a public API as it is called whenever an interrupt occurs.
 * Spurious interrupt implementation:
 * This handler will process only one Normal Buffers (tx or rx or legacy fifo)
 * and Enhance FIFO(if supported). The processing of spurious interrupt will be
 * done when there is no real interrupt(both IF and IE are set) at all.
 * If a spurious interrupt found:
 *  - for Rx (Rx normal, Legacy FIFO, Enhanced FIFO): Just clear IF and exit,
 *    the Buffer is still ready to receive a new Frame.
 *  - for Tx: Clear IF and reset the Buffer to default state to ready to use in next time.
 *END**************************************************************************/
/* implements CAN_X_MB_Y_ISR_Activity */
void FlexCAN_IRQHandler
(
    uint8 instance,
    uint32 startMbIdx,
    uint32 endMbIdx
    #if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    ,boolean bEnhancedFifoExisted
    #endif
)
{
    uint32 u32MbHandle = 0U;
    uint32 flag_reg = 0;
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    boolean bIsSpuriousInt = (boolean)TRUE;
    /* Get the interrupts that are enabled and ready */
    uint32 mb_idx = endMbIdx;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(endMbIdx < (uint8)FEATURE_CAN_MAX_MB_NUM);
#endif
    /* Check if instance initialized */
    if (NULL_PTR != state)
    {
        flag_reg = FlexCAN_GetMsgBuffIntStatusFlag(base, mb_idx);

        while ((0U == flag_reg) && (mb_idx > startMbIdx))
        {
            mb_idx--;
            flag_reg = FlexCAN_GetMsgBuffIntStatusFlag(base, mb_idx);
        }

        /* Check Tx/Rx interrupt flag and clear the interrupt */
        if (flag_reg != 0U)
        {
            /* At least one real interrupt -> no process spurious interurpt */
            bIsSpuriousInt = (boolean)FALSE;

            /* For legacy fifo, mb handler is FLEXCAN_MB_HANDLE_RXFIFO(0) */
            u32MbHandle = mb_idx;

            if (((boolean)TRUE == state->bIsLegacyFifoEn) && (mb_idx <= CAN_LEGACY_RXFIFO_OVERFLOW))
            {
                FlexCAN_IRQHandlerRxFIFO(instance, mb_idx);
                u32MbHandle = (uint32)FLEXCAN_MB_HANDLE_RXFIFO;
            }
            else
            {
                /* Check mailbox completed reception */
                if (state->mbs[u32MbHandle].state == FLEXCAN_MB_RX_BUSY)
                {
                    FlexCAN_IRQHandlerRxMB(instance, mb_idx);
                }
            }

            /* Check mailbox completed transmission */
            if (state->mbs[u32MbHandle].state == FLEXCAN_MB_TX_BUSY)
            {
                FlexCAN_IRQHandlerTxMB(instance, mb_idx);
            }

            /* Check for spurious interrupt */
            if (FlexCAN_GetMsgBuffIntStatusFlag(base, mb_idx) != 0U)
            {
                if (state->mbs[u32MbHandle].state == FLEXCAN_MB_IDLE)
                {
                    /* In case of desynchronized status of the MB to avoid trapping in ISR
                    * clear the MB flag */
                    FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
                }
            }
        }

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
        if ((boolean)TRUE == bEnhancedFifoExisted)
        {
            if (((boolean)TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base)) && (FLEXCAN_RXFIFO_USING_INTERRUPTS == state->transferType))
            {
                bIsSpuriousInt = FlexCAN_ProcessIRQHandlerEnhancedRxFIFO(instance, bIsSpuriousInt);
            }
        }
#endif /* End of (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */

        /* continue processing spurious interrupt for normal Mb only if enhance fifo interrupt is not existed on ISR or no enhance fifo interrupts occurred */
        /* Expectation is that ISR just process one Object (Tx, Rx normal, Rx legacy fifo, Rx enhance fifo) when ISR triggered */
        if ((boolean)TRUE == bIsSpuriousInt)
        {
            FlexCAN_ProcessSpuriousInterruptMB(instance, startMbIdx, endMbIdx);
        }
    }
    else
    {
        /* Clear all interrupt flags when driver is not initialized */
        /* Process spurious interrupt */
        for (mb_idx = startMbIdx; mb_idx <= endMbIdx; mb_idx++)
        {
            /* clear the MB flag */
            FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
        }
    #if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
        /* Check if Enhance fifo interrupt existed on the ISR! */
        if ((boolean)TRUE == bEnhancedFifoExisted)
        {
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE);
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_WATERMARK);
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_OVERFLOW);
            FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_UNDERFLOW);
        }
    #endif /* End of (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ClearErrorStatus
 * Description   : Clears various error conditions detected in the reception and
 *                 transmission of a CAN frame.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_ClearErrorStatus_Activity */
void FlexCAN_Ip_ClearErrorStatus(uint8 instance, uint32 error)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    base->ESR1 = error;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetErrorStatus
 * Description   : Reports various error conditions detected in the reception and
 *                 transmission of a CAN frame and some general status of the device.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetErrorStatus_Activity */
uint32 FlexCAN_Ip_GetErrorStatus(uint8 instance)
{

    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    return (uint32)(base->ESR1);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetControllerTxErrorCounter
 * Description   : Reports Transmit error counter for all errors detected in
 *                 transmitted messages.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetControllerTxErrorCounter_Activity */
uint8 FlexCAN_Ip_GetControllerTxErrorCounter(uint8 instance)
{

    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    return (uint8)((base->ECR & FLEXCAN_ECR_TXERRCNT_MASK) >> FLEXCAN_ECR_TXERRCNT_SHIFT);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetControllerRxErrorCounter
 * Description   : Reports Receive error counter for all errors detected in
 *                 received messages.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetControllerRxErrorCounter_Activity */
uint8 FlexCAN_Ip_GetControllerRxErrorCounter(uint8 instance)
{

    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    return (uint8)((base->ECR & FLEXCAN_ECR_RXERRCNT_MASK) >> FLEXCAN_ECR_RXERRCNT_SHIFT);
}


#if (FEATURE_CAN_BUSOFF_ERROR_INTERRUPT_UNIFIED == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Busoff_Error_IRQHandler
 * Description   : BusOff and Error interrupt handler for FLEXCAN.
 * This is not a public API as it is called whenever an interrupt occurs.
 *
 *END**************************************************************************/
/* implements  CAN_X_BUSOFF_ERROR_ISR_Activity */
void FlexCAN_Busoff_Error_IRQHandler(uint8 instance)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    uint32 u32ErrStatus = 0U;
    boolean isSpuriousInt = (boolean)TRUE;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    /* Check if the instance initialized */
    if (NULL_PTR != state)
    {
        /* Get error status to get value updated */
        u32ErrStatus = pBase->ESR1;

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_ERRMSK_MASK))))
        {
            pBase->ESR1 = FLEXCAN_ESR1_ERRINT_MASK;
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_ERROR, u32ErrStatus, state);
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = pBase->ESR1;
            }
            isSpuriousInt = (boolean)FALSE;
        }

    #if (FEATURE_CAN_HAS_FD == STD_ON)
        /* Check if this is spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_FAST_MASK))) && ((uint32)0U != (pBase->CTRL2 & ((uint32)FLEXCAN_CTRL2_ERRMSK_FAST_MASK))))
        {
            pBase->ESR1 = FLEXCAN_ESR1_ERRINT_FAST_MASK;
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_ERROR_FAST, u32ErrStatus, state);
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = pBase->ESR1;
            }
            isSpuriousInt = (boolean)FALSE;
        }
    #endif /* FEATURE_CAN_HAS_FD */

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_TWRNINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_TWRNMSK_MASK))))
        {
            pBase->ESR1 = FLEXCAN_ESR1_TWRNINT_MASK;
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_TX_WARNING, u32ErrStatus, state);
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = pBase->ESR1;
            }
            isSpuriousInt = (boolean)FALSE;
        }

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_RWRNINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_RWRNMSK_MASK))))
        {
            pBase->ESR1 = FLEXCAN_ESR1_RWRNINT_MASK;
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_RX_WARNING, u32ErrStatus, state);
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = pBase->ESR1;
            }
            isSpuriousInt = (boolean)FALSE;
        }

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_BOFFINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_BOFFMSK_MASK))))
        {
            pBase->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK;
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_BUSOFF, u32ErrStatus, state);
            }
            isSpuriousInt = (boolean)FALSE;
        }
    }

    if ((boolean)TRUE == isSpuriousInt)
    {
        pBase->ESR1 = FLEXCAN_ALL_INT;
    }
}
#else /* (FEATURE_CAN_BUSOFF_ERROR_INTERRUPT_UNIFIED == STD_OFF) */
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_Error_IRQHandler
 * Description   : Error interrupt handler for FLEXCAN.
 * This is not a public API as it is called whenever an interrupt occurs.
 *
 *END**************************************************************************/
/* implements  CAN_X_ERROR_ISR_Activity */
void FlexCAN_Error_IRQHandler(uint8 instance)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    uint32 u32ErrStatus = 0U;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    /* Check if the instance initialized */
    if (NULL_PTR != state)
    {
        /* Get error status to get value updated */
        u32ErrStatus = pBase->ESR1;

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_ERRMSK_MASK))))
        {
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_ERROR, u32ErrStatus, state);
            #if (FEATURE_CAN_HAS_FD == STD_ON)
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = pBase->ESR1;
            #endif /* FEATURE_CAN_HAS_FD */
            }
        }

    #if (FEATURE_CAN_HAS_FD == STD_ON)
        /* Check if this is spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_FAST_MASK))) && ((uint32)0U != (pBase->CTRL2 & ((uint32)FLEXCAN_CTRL2_ERRMSK_FAST_MASK))))
        {
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_ERROR_FAST, u32ErrStatus, state);
            }
        }
    #endif /* FEATURE_CAN_HAS_FD */
    }
    /* Clear all other interrupts in ESR1 register (Error, Wakeup) */
    FlexCAN_ClearErrIntStatusFlag(pBase);
}


/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_BusOff_IRQHandler
 * Description   : BusOff and Tx/Rx Warning interrupt handler for FLEXCAN.
 * This handler only provides a error status report and invokes the user callback,
 * and then clears the interrupt flags.
 * This is not a public API as it is called whenever an interrupt occurs.
 *
 *END**************************************************************************/
/* implements CAN_X_BUSOFF_ISR_Activity */
void FlexCAN_BusOff_IRQHandler(uint8 instance)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    uint32 u32ErrStatus = 0U;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    /* Check If Driver initialized */
    if (NULL_PTR != state)
    {
        /* Get error status to get value updated */
        u32ErrStatus = base->ESR1;

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_TWRNINT_MASK))) && (0U != (base->CTRL1 & ((uint32)FLEXCAN_CTRL1_TWRNMSK_MASK))))
        {
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_TX_WARNING, u32ErrStatus, state);
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = base->ESR1;
            }
        }

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_RWRNINT_MASK))) && (0U != (base->CTRL1 & ((uint32)FLEXCAN_CTRL1_RWRNMSK_MASK))))
        {
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_RX_WARNING, u32ErrStatus, state);
                /* Get error status to get value updated due to user may handle ESR1 register */
                u32ErrStatus = base->ESR1;
            }
        }

        /* Check spurious interrupt */
        if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_BOFFINT_MASK))) && ((uint32)0U != (base->CTRL1 & ((uint32)FLEXCAN_CTRL1_BOFFMSK_MASK))))
        {
            /* Invoke callback */
            if (state->error_callback != NULL_PTR)
            {
                state->error_callback(instance, FLEXCAN_EVENT_BUSOFF, u32ErrStatus, state);
            }
        }
    }

    /* Clear all BusOff and Tx/Rx Warning interrupts in ESR1 register */
    FlexCAN_ClearBusOffIntStatusFlag(base);
}
#endif /* (FEATURE_CAN_BUSOFF_ERROR_INTERRUPT_UNIFIED) */
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SendBlocking
 * Description   : This function sends a CAN frame using a configured message
 * buffer. The function blocks until either the frame was sent, or the specified
 * timeout expired.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SendBlocking_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SendBlocking(uint8 instance,
                                  uint8 mb_idx,
                                  const Flexcan_Ip_DataInfoType * tx_info,
                                  uint32 msg_id,
                                  const uint8 * mb_data,
                                  uint32 timeout_ms)
{
    Flexcan_Ip_StatusType result;
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];

    uint32 timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
    uint32 timeElapsed = 0U;
    uint32 mS2Ticks = OsIf_MicrosToTicks((timeout_ms * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
    uint32 uS2Ticks = 0U;
    uint32 flexcan_mb_config = 0;

    volatile uint32 * flexcan_mb = NULL_PTR;
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(tx_info != NULL_PTR);
#endif

    result = FlexCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data);

    if (result == FLEXCAN_STATUS_SUCCESS)
    {
        while(FlexCAN_GetBuffStatusFlag(base, mb_idx) != 1U)
        {
            timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
            if (timeElapsed >= mS2Ticks)
            {
                result = FLEXCAN_STATUS_TIMEOUT;
                break;
            }
        }

        if ((result == FLEXCAN_STATUS_TIMEOUT) && (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE))
        {
                /* Clear message buffer flag */
                FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
                flexcan_mb = FlexCAN_GetMsgBuffRegion(base, mb_idx);
                flexcan_mb_config = * flexcan_mb;
                /* Reset the code */
                flexcan_mb_config &= (uint32)(~CAN_CS_CODE_MASK);
                flexcan_mb_config |= ((uint32)(((uint32)FLEXCAN_TX_ABORT & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK);
                *flexcan_mb = flexcan_mb_config;

                /* Wait to finish abort operation */
                uS2Ticks = OsIf_MicrosToTicks(CAN_TIMEOUT_DURATION, CAN_SERVICE_TIMEOUT_TYPE);
                timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
                 timeElapsed = 0U;
                while (FlexCAN_GetBuffStatusFlag(base, mb_idx) == 0U)
                {
                    timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
                    if (timeElapsed >= uS2Ticks)
                    {
                        result = FLEXCAN_STATUS_TIMEOUT;
                        break;
                    }
                }

                flexcan_mb_config = *flexcan_mb;
                /* Check if the MBs have been safely Inactivated */
                if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_INACTIVE)
                {
                    /* Transmission have occurred */
                    result = FLEXCAN_STATUS_SUCCESS;
                }

                if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_ABORT)
                {
                    /* Transmission have been aborted */
                    result = FLEXCAN_STATUS_TIMEOUT;
                }
        }

        /* Clear message buffer flag */
        FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);

        state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
    }
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetRxMbGlobalMask
 * Description   : Set Rx Message Buffer global mask as the mask value provided.
 *
 *END**************************************************************************/

/* implements FlexCAN_Ip_SetRxMbGlobalMask_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMbGlobalMask_Privileged(uint8 instance,
                                  uint32 mask)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FALSE;
#endif

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif
    if (result == FLEXCAN_STATUS_SUCCESS)
    {
        FlexCAN_SetRxMsgBuffGlobalMask(pBase, mask);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_EnterFreezeMode
 * Description   : Enter Driver In freeze Mode.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_EnterFreezeMode_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_EnterFreezeMode_Privileged(uint8 instance)
{
        FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
        return FlexCAN_EnterFreezeMode(base);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ExitFreezeMode
 * Description   : Exit Driver from freeze Mode.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_ExitFreezeMode_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ExitFreezeMode_Privileged(uint8 instance)
{
        FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
        return FlexCAN_ExitFreezeMode(base);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetRxIndividualMask
 * Description   : Set Rx individual mask as absolute value provided by mask parameter
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetRxIndividualMask_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxIndividualMask_Privileged(uint8 instance,
                                                     uint8 mb_idx,
                                                     uint32 mask)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FALSE;
#endif

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    if ((mb_idx > (((pBase->MCR) & FLEXCAN_MCR_MAXMB_MASK) >> FLEXCAN_MCR_MAXMB_SHIFT)) || (mb_idx >= FLEXCAN_RXIMR_COUNT))
    {
        result = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
    }
    else
    {
#endif

    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif
    if (result == FLEXCAN_STATUS_SUCCESS)
    {
        FlexCAN_SetRxIndividualMask(pBase, mb_idx, mask);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    }
#endif
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetRxFifoGlobalMask
 * Description   : Set RxFifo Global Mask.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetRxFifoGlobalMask_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxFifoGlobalMask_Privileged(uint8 instance,
                                                      uint32 mask)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);
    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        FlexCAN_SetRxFifoGlobalMask(pBase, mask);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_Deinit
 * Description   : Shutdown a FlexCAN module.
 * This function will disable all FlexCAN interrupts, and disable the FlexCAN.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_Deinit_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_Deinit_Privileged(uint8 instance)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    /* Enter Freeze Mode Required before to enter Disabled Mode */
    result = FlexCAN_EnterFreezeMode(base);
    if (FLEXCAN_STATUS_SUCCESS == result)
    {
        /* Reset registers */
        FlexCAN_SetRegDefaultVal(base);
        /* wait for disable */
        (void)FlexCAN_Disable(base);
        /* Clear state pointer that is checked by FLEXCAN_DRV_Init */
        g_flexcan_Ip_StatePtr[instance] = NULL_PTR;

    #if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
        /* Clear the UAA bit in REG_PROT to reset the elevation requirement */
        OsIf_Trusted_Call1param(FlexCAN_ClrUserAccessAllowed, base);
    #endif
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_MainFunctionRead
 * Description   : Process received Rx MessageBuffer or RxFifo.
 * This function read the messages received as pulling or if the Interrupts are disabled.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_MainFunctionRead_Activity */
void FlexCAN_Ip_MainFunctionRead(uint8 instance, uint8 mb_idx)
{
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    #if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    DevAssert((mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM) || (mb_idx == FLEXCAN_MB_ENHANCED_RXFIFO));
    #else
    DevAssert(mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM);
    #endif
#endif

#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    if ((uint8)FLEXCAN_MB_ENHANCED_RXFIFO == mb_idx)
    {
        if ((boolean)TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
        {
            if((boolean)TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
            {
                if (FlexCAN_GetEnhancedRxFIFOStatusFlag(base, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE) != 0U)
                {
                    FlexCAN_IRQHandlerEnhancedRxFIFO(instance, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE);
                }
            }
        }
    }
    else
    {
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
        if (((boolean)TRUE == state->bIsLegacyFifoEn) && (mb_idx <= CAN_LEGACY_RXFIFO_OVERFLOW))
        {
            /* just process available legacy fifo event only */
            if ((uint8)FLEXCAN_MB_HANDLE_RXFIFO == mb_idx)
            {
                if (FlexCAN_GetBuffStatusFlag(base, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE) != 0U)
                {
                    FlexCAN_IRQHandlerRxFIFO(instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE);
                }
            }
        }
        else
        {
            if (FlexCAN_GetBuffStatusFlag(base, mb_idx) != 0U)
            {
                /* Check mailbox completed reception */
                if (FLEXCAN_MB_RX_BUSY == state->mbs[mb_idx].state)
                {
                    FlexCAN_IRQHandlerRxMB(instance, mb_idx);
                }
            }
        }
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
    }
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_MainFunctionBusOff
 * Description   : Check if BusOff occurred
 * This function check the bus off event.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_MainFunctionBusOff_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_MainFunctionBusOff_Privileged(uint8 instance)
{
    Flexcan_Ip_StatusType eRetVal = FLEXCAN_STATUS_ERROR;
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
    uint32 u32ErrStatus = 0U;

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    /* Get error status */
    u32ErrStatus = base->ESR1;

    if(0U != (u32ErrStatus & FLEXCAN_ESR1_BOFFINT_MASK))
    {
        /* Invoke callback */
        if (state->error_callback != NULL_PTR)
        {
            state->error_callback(instance, FLEXCAN_EVENT_BUSOFF, u32ErrStatus, state);
        }
        /* Clear BusOff Status Flag */
        base->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK;
        eRetVal = FLEXCAN_STATUS_SUCCESS;
    }
    return eRetVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_MainFunctionWrite
 * Description   : Process transmitted Tx MessageBuffer
 * This function check the message if have been sent.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_MainFunctionWrite_Activity */
void FlexCAN_Ip_MainFunctionWrite(uint8 instance, uint8 mb_idx)
{
    FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif

    if (FlexCAN_GetBuffStatusFlag(base, mb_idx) != 0U)
    {
        state->mbs[mb_idx].time_stamp = FlexCAN_GetMsgBuffTimestamp(base, mb_idx);
        FlexCAN_UnlockRxMsgBuff(base);

        /* Clear message buffer flag */
        FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
        state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetStopMode
 * Description   : Check if the FlexCAN instance is STOPPED.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetStopMode_Activity */
boolean FlexCAN_Ip_GetStopMode_Privileged(uint8 instance)
{
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    return (((base->MCR & FLEXCAN_MCR_LPMACK_MASK) == FLEXCAN_MCR_LPMACK_MASK) ? TRUE : FALSE);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetStartMode
 * Description   : Check if the FlexCAN instance is STARTED.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetStartMode_Activity */
boolean FlexCAN_Ip_GetStartMode_Privileged(uint8 instance)
{
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    return (((base->MCR & (FLEXCAN_MCR_LPMACK_MASK | FLEXCAN_MCR_FRZACK_MASK)) == 0U) ? TRUE : FALSE);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetStartMode
 * Description   : Set the FlexCAN instance in START mode.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetStartMode_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetStartMode_Privileged(uint8 instance)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    /* Enable Flexcan Module */
    pBase->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
    return (FlexCAN_ExitFreezeMode(pBase));
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetStopMode
 * Description   : Set the FlexCAN instance in STOP mode.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetStopMode_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetStopMode_Privileged(uint8 instance)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    Flexcan_Ip_StatusType status;
    status = FlexCAN_EnterFreezeMode(pBase);
    if (status == FLEXCAN_STATUS_SUCCESS)
    {
        /* TODO: deactivate all pending tx, this should be move to IPW */

        /* TODO:Clear all flag */

        /* TODO: reset MB status */

        /* TODO: disable all interrupt */

        status = FlexCAN_Disable(pBase);
    }
    return status;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetRxMaskType
 * Description   : Set RX masking type.
 * This function will set RX masking type as RX global mask or RX individual
 * mask.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetRxMaskType_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMaskType_Privileged(uint8 instance,
                               Flexcan_Ip_RxMaskType type)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        FlexCAN_SetRxMaskType(pBase, type);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetBitrate
 * Description   : Set FlexCAN baudrate.
 * This function will set up all the time segment values for classical frames or the
 * extended time segments. Those time segment values are passed in by the user and
 * are based on the required baudrate.
 *
 *END**************************************************************************/

/* implements  FlexCAN_Ip_SetBitrate_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetBitrate_Privileged(uint8 instance, const Flexcan_Ip_TimeSegmentType * bitrate, boolean enhExt)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(bitrate != NULL_PTR);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        /* Start critical section: implementation depends on integrator */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_14();
        /* Enable the use of extended bit time definitions */
        FlexCAN_EnhCbtEnable(pBase, enhExt);

        if (enhExt == TRUE)
        {
            /* Set extended time segments*/
            FlexCAN_SetEnhancedNominalTimeSegments(pBase, bitrate);
        }
        else
        {
            if (FlexCAN_IsExCbtEnabled(pBase) == TRUE)
            {
                FlexCAN_SetExtendedTimeSegments(pBase, bitrate);
            }
            else
            {
                FlexCAN_SetTimeSegments(pBase, bitrate);
            }
        }
        /* End critical section: implementation depends on integrator */
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_14();
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetBitrate
 * Description   : Get FlexCAN Baudrate.
 * This function will be return the current bit rate settings for classical frames
 * or the arbitration phase of FD frames.
 *
 *END**************************************************************************/
 /* implements   FlexCAN_Ip_GetBitrate_Activity */
boolean FlexCAN_Ip_GetBitrate(uint8 instance,
                              Flexcan_Ip_TimeSegmentType * bitrate)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(bitrate != NULL_PTR);
#endif
    const FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean enhCbt = FALSE;
    enhCbt = FlexCAN_IsEnhCbtEnabled(pBase);
    if (enhCbt == TRUE)
    {
        FlexCAN_GetEnhancedNominalTimeSegments(pBase, bitrate);
    }
    else
    {
        if (TRUE == FlexCAN_IsExCbtEnabled(pBase))
        {
            /* Get the Extended time segments*/
            FlexCAN_GetExtendedTimeSegments(pBase, bitrate);
        }
        else
        {
            /* Get the time segments*/
            FlexCAN_GetTimeSegments(pBase, bitrate);
        }
    }
    return enhCbt;
}

#if (FEATURE_CAN_HAS_FD == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ClearTDCFail
 * Description   : This function clear the TDC Fail flag.
 *
 *END**************************************************************************/
/* implements   FlexCAN_Ip_ClearTDCFail_Activity */
void FlexCAN_Ip_ClearTDCFail_Privileged(uint8 u8Instance)
{
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
#endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);
    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
    if (result == FLEXCAN_STATUS_SUCCESS)
    {
        /* Check if enhaced CBT is Enabled */
        if (FlexCAN_IsEnhCbtEnabled(pBase) == TRUE)
        {
            pBase->ETDC |=  FLEXCAN_ETDC_ETDCFAIL_MASK;
        }
        else
        {
            pBase->FDCTRL |= FLEXCAN_FDCTRL_TDCFAIL_MASK;
        }
    }
    if (disabled == TRUE)
    {
        (void)FlexCAN_Disable(pBase);
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetTDCFail
 * Description   : This function get the value of the TDC Fail flag.
 *
 *END**************************************************************************/

/* implements    FlexCAN_Ip_GetTDCFail_Activity */
boolean FlexCAN_Ip_GetTDCFail_Privileged(uint8 u8Instance)
{
    boolean value=FALSE;
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
#endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);
    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
    if (result == FLEXCAN_STATUS_SUCCESS)
    {
        /* Check if enhaced CBT is Enabled */
        if (FlexCAN_IsEnhCbtEnabled(pBase) == TRUE)
        {
            value = ((pBase->ETDC & FLEXCAN_ETDC_ETDCFAIL_MASK) == FLEXCAN_ETDC_ETDCFAIL_MASK) ? TRUE : FALSE;
        }
        else
        {
            value = ((pBase->FDCTRL & FLEXCAN_FDCTRL_TDCFAIL_MASK) == FLEXCAN_FDCTRL_TDCFAIL_MASK) ? TRUE : FALSE;
        }
    }
    if (disabled == TRUE)
    {
        (void)FlexCAN_Disable(pBase);
    }
    return value;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetTDCValue
 * Description   : This function get the value of the Transceiver Delay Compensation.
 *
 *END**************************************************************************/

/* implements FlexCAN_Ip_GetTDCValue_Activity */
uint8 FlexCAN_Ip_GetTDCValue_Privileged(uint8 u8Instance)
{
    uint8 value = 0;
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
#endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);
    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
    if (result == FLEXCAN_STATUS_SUCCESS)
    {
        /* Check if enhaced CBT is Enabled */
        if (FlexCAN_IsEnhCbtEnabled(pBase) == TRUE)
        {
            value = (uint8)((pBase->ETDC& FLEXCAN_ETDC_ETDCVAL_MASK) >> FLEXCAN_ETDC_ETDCVAL_SHIFT);
        }
        else
        {
            value = (uint8)((pBase->FDCTRL & FLEXCAN_FDCTRL_TDCVAL_MASK) >> FLEXCAN_FDCTRL_TDCVAL_SHIFT);
        }
    }
    if (disabled == TRUE)
    {
        (void)FlexCAN_Disable(pBase);
    }
    return value;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetBitrateCbt
 * Description   : Set FlexCAN bitrate.
 * This function will set up all the time segment values for the data phase of
 * FD frames. Those time segment values are passed in by the user and are based
 * on the required baudrate.
 *
 *END**************************************************************************/

/* implements  FlexCAN_Ip_SetBitrateCbt_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetBitrateCbt_Privileged(uint8 instance, const Flexcan_Ip_TimeSegmentType * bitrate,
                                               boolean bitRateSwitch)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(bitrate != NULL_PTR);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);
    boolean fd_enable = FlexCAN_IsFDEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)

    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((fd_enable == FALSE) || ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS)))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        boolean enhCbt = FlexCAN_IsEnhCbtEnabled(pBase);
        /* Start critical section: implementation depends on integrator */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_15();
        FlexCAN_SetFDEnabled(pBase, fd_enable, bitRateSwitch);

        if (enhCbt == TRUE)
        {
            FlexCAN_SetEnhancedDataTimeSegments(pBase, bitrate);
        }
        else
        {
            /* Set time segments*/
            FlexCAN_SetFDTimeSegments(pBase, bitrate);
        }
        /* End critical section: implementation depends on integrator */
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_15();
    }

    if ((boolean)TRUE == disabled)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetBitrateFD
 * Description   : Get FlexCAN baudrate.
 * This function will be return the current bit rate settings for the data phase
 * of FD frames.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetBitrateFD_Activity */
boolean FlexCAN_Ip_GetBitrateFD(uint8 instance,
                              Flexcan_Ip_TimeSegmentType * bitrate)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
    DevAssert(bitrate != NULL_PTR);
#endif
    const FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean enhCbt = FlexCAN_IsEnhCbtEnabled(pBase);

    if (enhCbt == TRUE)
    {
        FlexCAN_GetEnhancedDataTimeSegments(pBase, bitrate);
    }
    else
    {
        /* Get the time segments*/
        FlexCAN_GetFDTimeSegments(pBase, bitrate);
    }
    return enhCbt;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetTDCOffset
 * Description   : Enables/Disables the Transceiver Delay Compensation feature and sets
 * the Transceiver Delay Compensation Offset.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetTDCOffset_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetTDCOffset_Privileged(uint8 instance,
                                              boolean enable,
                                              uint8 offset)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        /* Check if enhaced CBT is Enabled */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_16();
        /* End critical section: implementation depends on integrator */
        if ((pBase->CTRL2 & FLEXCAN_CTRL2_BTE_MASK) == FLEXCAN_CTRL2_BTE_MASK)
        {
            FlexCAN_SetEnhancedTDCOffset(pBase, enable, offset);
        }
        else
        {
            /* Enable/Disable TDC and set the TDC Offset */
            FlexCAN_SetTDCOffset(pBase, enable, offset);
        }
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_16();
        /* Check if enhaced CBT is Enabled */
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }
    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetTxArbitrationStartDelay
 * Description   : Set FlexCAN Tx Arbitration Start Delay.
 * This function will set how many CAN bits the Tx arbitration process start point can
 * be delayed from the first bit of CRC field on CAN bus.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetTxArbitrationStartDelay_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetTxArbitrationStartDelay_Privileged(uint8 instance,  uint8 value)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        /* Start critical section: implementation depends on integrator */
        SchM_Enter_Can_CAN_EXCLUSIVE_AREA_17();
        FlexCAN_SetTxArbitrationStartDelay(pBase, value);
        /* End critical section: implementation depends on integrator */
        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_17();
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetBuffStatusFlag
 * Description   : Get FlexCAN Message Buffer Status Flag for an operation.
 * In case of a complete operation this flag is set.
 * In case msgBuff is 255 will return Enhanced Overflow Status Flag.
 *END**************************************************************************/
/* implements FlexCAN_Ip_GetBuffStatusFlag_Activity */
boolean FlexCAN_Ip_GetBuffStatusFlag(uint8 instance, uint8 msgBuffIdx)
{
    boolean returnResult = TRUE;
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    const FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    if (msgBuffIdx == FLEXCAN_MB_ENHANCED_RXFIFO)
    {
        returnResult = ((FlexCAN_GetEnhancedRxFIFOStatusFlag(pBase, CAN_ENHANCED_RXFIFO_OVERFLOW) == 1U) ? TRUE : FALSE);
    }
    else
    {
        returnResult = ((FlexCAN_GetBuffStatusFlag(pBase, msgBuffIdx) == 1U) ? TRUE : FALSE);
    }
    return returnResult;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ClearBuffStatusFlag
 * Description   : Clear FlexCAN Message Buffer Status Flag.
 * In case msgBuff is 255 will clear Enhanced Overflow Status Flag.
 *END**************************************************************************/
/* implements FlexCAN_Ip_ClearBuffStatusFlag_Activity */
void FlexCAN_Ip_ClearBuffStatusFlag(uint8 instance, uint8 msgBuffIdx)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    if (msgBuffIdx == FLEXCAN_MB_ENHANCED_RXFIFO)
    {
        FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_OVERFLOW);
    }
    else
    {
        FlexCAN_ClearMsgBuffIntStatusFlag(pBase, msgBuffIdx);
    }
}

#endif

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_EnableInterrupts
 * Description   : Enable all mb interrupts configured.
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_EnableInterrupts_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_EnableInterrupts_Privileged(uint8 u8Instance)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
#endif

    if ((boolean)TRUE == FlexCAN_IsEnabled(pBase))
    {
        FlexCAN_EnableInterrupts(pBase, u8Instance);
    #if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
        if ((state->enhancedFifoOutput.isPolling == FALSE) && ( TRUE == FlexCAN_IsEnhancedRxFifoAvailable(pBase)))
        {   /* Check if Enabled Enhanced Fifo */
            if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(pBase))
            {
                FlexCAN_SetEnhancedRxFifoIntAll(pBase, TRUE);
            }
        }
    #endif
        state->isIntActive = (boolean)TRUE;
        result = FLEXCAN_STATUS_SUCCESS;
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_DisableInterrupts
 * Description   : Enable all interrupts configured.
 *
 *END**************************************************************************/
 /* implements FlexCAN_Ip_DisableInterrupts_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_DisableInterrupts_Privileged(uint8 u8Instance)
{
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
#endif

    if ((boolean)TRUE == FlexCAN_IsEnabled(pBase))
    {
        FlexCAN_DisableInterrupts(pBase);
        if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(pBase))
        {   /* Check if Enabled Enhanced Fifo */
            if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(pBase))
            {
                FlexCAN_SetEnhancedRxFifoIntAll(pBase, FALSE);
            }
        }
        state->isIntActive = (boolean)FALSE;
        result = FLEXCAN_STATUS_SUCCESS;
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetErrorInt
 * Description   : Enable\Disable Error or BusOff Interrupt
 *
 *END**************************************************************************/
/* implements FlexCAN_Ip_SetErrorInt_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetErrorInt_Privileged(uint8 u8Instance, Flexcan_Ip_ErrorIntType type, boolean enable)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

    if(FLEXCAN_STATUS_SUCCESS == result )
    {
        switch(type)
        {
        case FLEXCAN_IP_INT_BUSOFF:
        {
            FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_BUSOFF, enable);
            break;
        }
        case FLEXCAN_IP_INT_ERR:
        {
            FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_ERR, enable);
            break;
        }
        case FLEXCAN_IP_INT_ERR_FAST :
        {
            FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_ERR_FAST, enable);
            break;
        }
        case FLEXCAN_IP_INT_RX_WARNING :
        {
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
            if (TRUE != FlexCAN_IsFreezeMode(pBase))
            {
                result = FLEXCAN_STATUS_ERROR;
            }else
#endif
            {
                FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_RX_WARNING, enable);
            }
            break;
        }
        case FLEXCAN_IP_INT_TX_WARNING :
        {
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
            if (TRUE != FlexCAN_IsFreezeMode(pBase))
            {
                result = FLEXCAN_STATUS_ERROR;
            }else
#endif
            {
                FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_TX_WARNING, enable);
            }
            break;
        }
        default:
        {
            #if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
                DevAssert((boolean)FALSE);
                /* Should not get here */
            #endif
            break;
        }
        }
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_AbortTransfer
 * Description   : This function shuts down the FLEXCAN by disabling interrupts and
 *                 the transmitter/receiver.
 * This function disables the FLEXCAN interrupts, disables the transmitter and
 * receiver.
 *
 *END**************************************************************************/
/* implements    FlexCAN_Ip_AbortTransfer_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_AbortTransfer(uint8 u8Instance,
                                                uint8 mb_idx)
{
    #if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
        DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
        DevAssert((mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM) || (mb_idx == 255u));
    #endif
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
#if ((FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) && (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON))
    Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
#else
    const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) && (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON) */
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;

    if (mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM)
    {

    if (FLEXCAN_MB_IDLE == state->mbs[mb_idx].state)
    {
        result = FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
    }
    else
    {
        FLEXCAN_ClearMsgBuffIntCmd(pBase, u8Instance, mb_idx, state->isIntActive);
        if (FLEXCAN_MB_TX_BUSY == state->mbs[mb_idx].state)
        {
            result = FlexCAN_AbortTxTransfer(u8Instance, mb_idx);
        }

        if (FLEXCAN_MB_RX_BUSY == state->mbs[mb_idx].state)
        {
            FlexCAN_AbortRxTransfer(u8Instance, mb_idx);
        }
    }

    }
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
    else
    {
        /* Check if transfer is done over DMA and stop transfer */
        if ((state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
        {
            (void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
            if (state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY)
            {
                state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
            }
            else
            {
                return FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
            }
        }
        else
        {
            return FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
        }
    }
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
#endif /* if FEATURE_CAN_HAS_ENHANCED_RX_FIFO */

    return result;
}

/* implements    FlexCAN_Ip_SetRxMb14Mask_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMb14Mask_Privileged(uint8 instance, uint32 mask)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FALSE;
#endif
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif
    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        pBase->RX14MASK = mask;
    }
    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/* implements    FlexCAN_Ip_SetRxMb15Mask_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMb15Mask_Privileged(uint8 instance, uint32 mask)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FALSE;
#endif
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif
    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        pBase->RX15MASK = mask;
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_SetListenOnlyMode
 * Description   : Set FlexCAN Listen Only.
 * This function will enable or disable Listen Only mode.
 *
 *END**************************************************************************/
/* implements  FlexCAN_Ip_SetListenOnlyMode_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_SetListenOnlyMode_Privileged(uint8 instance, const boolean enable)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        FlexCAN_SetListenOnlyMode(pBase, enable);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_GetListenOnlyMode
 * Description   : Check if Listen Only mode is ENABLE.
 *
 *END**************************************************************************/
/* implements  FlexCAN_Ip_GetListenOnlyMode_Activity */
boolean FlexCAN_Ip_GetListenOnlyMode(uint8 instance)
{
    const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
    return FlexCAN_IsListenOnlyModeEnabled(base);
}

#if (FEATURE_CAN_HAS_HR_TIMER == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : FlexCAN_Ip_ConfigTimeStamp_Privileged
 * Description   : Timestamp configuration
 *
 *END**************************************************************************/
/* implements  FlexCAN_Ip_ConfigTimeStamp_Activity */
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigTimeStamp_Privileged(uint8 instance, Flexcan_Ip_TimeStampConfigType * time_stamp)
{
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
#endif
    Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
    Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
    FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
    boolean disabled = !FlexCAN_IsEnabled(pBase);

    if (disabled == TRUE)
    {
        result = FlexCAN_Enable(pBase);
    }

#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
    boolean freeze = FlexCAN_IsFreezeMode(pBase);

    if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
    {
        result = FLEXCAN_STATUS_ERROR;
    }
#endif

    if (result == FLEXCAN_STATUS_SUCCESS )
    {
        FlexCAN_ConfigTimestamp(pBase, time_stamp);
        FlexCAN_ConfigTimestampModule(time_stamp);
    }

    if (disabled == TRUE)
    {
        status = FlexCAN_Disable(pBase);
        if (FLEXCAN_STATUS_SUCCESS != status)
        {
            result = status;
        }
    }

    return result;
}
#endif

#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

/** @} */
