TMS320F280039: F280039的CAN通信问题

Part Number: TMS320F280039

/**
 * main.c
 */

#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"
#include "myMCAN.h"
#include "cla.h"
#include "epwms.h"
#include "ADCS.h"
#include "interrupt.h"
#include "global.h"
#include "oled.h"
#include "led.h"
#include "printf.h"
#include <math.h>
#include "hw_ints.h"

void main(void)

{

    InitSysCtrl();
    InitGpio();
    PWM1_Init(2999);
    PWM2_Init(2999);
    led_Init();

    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    EALLOW;
    PieVectTable.MCANA_1_INT = &MCANIntr1ISR;
    EDIS;
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // 使能 PIE 向量表读取
    PieCtrlRegs.PIEIER9.bit.INTx10 = 1;   // 使能 PIE 组 9 的第 10个中断(对应 MCAN0_INT1)
    IER |= M_INT9;
    EINT;  // 使能全局中断
    ERTM;  // 使能实时调试中断
    McanInit();
    while(1)
   {

       DEVICE_DELAY_US(1000000); // 延时 1 秒
       txMsg[loopCnt].data[0] = (txMsg[loopCnt].data[0] + 1) % 0xFF;

       // 【关键】将更新后的报文写入 TX Buffer
       MCAN_writeMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, loopCnt,
                        &txMsg[loopCnt]);
       // 【关键】触发发送请求(启动报文发送)
       MCAN_txBufAddReq(MCANA_DRIVER_BASE, (1U << loopCnt));


   }


}

#include "myMCAN.h"
#include "inc/hw_types_mcan.h"


MCAN_TxBufElement txMsg[NUM_OF_MSG];
int32_t loopCnt = 0U;
int32_t     error = 0;
MCAN_RxBufElement rxMsg[NUM_OF_MSG], rxMsg1;
//
// Defines
//
#define MCAN_EXT_ID_AND_MASK            (0x1FFFFFFFU)
#define MCAN_MSG_INT                    (0x81200)

//
// Global Variables.
//
volatile uint32_t isrIntr0Flag = 1U;
volatile uint32_t isrIntr1Flag = 1U;
volatile unsigned long msgCount = 0;
//volatile unsigned long error = 0;


__interrupt void MCANIntr0ISR(void);
__interrupt void MCANIntr1ISR(void);
void McanInit()
{
    int i = 0;
    txMsg[loopCnt].id       = ((uint32_t)(0x15A)<<18);
    txMsg[loopCnt].rtr      = 0U;
    txMsg[loopCnt].xtd      = 0U;
    txMsg[loopCnt].esi      = 0U;
    txMsg[loopCnt].dlc      = 1U;
    txMsg[loopCnt].brs      = 0U;
    txMsg[loopCnt].fdf      = 0U;
    txMsg[loopCnt].efc      = 1U;
    txMsg[loopCnt].mm       = 0xAAU;
    txMsg[loopCnt].data[i]  = 0x1;

    EALLOW;

    PinMux_init1();
    myMCAN0_init();
//    INTERRUPT_init();
    EDIS;

    MCAN_writeMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, loopCnt,
                     &txMsg[loopCnt]);

}

 

void PinMux_init1()
{
    //
    // PinMux for modules assigned to CPU1
    //

    //
    // MCAN -> myMCAN0 Pinmux
    //
    GPIO_setPinConfig(myMCAN0_MCANRX_PIN_CONFIG);
    // AGPIO -> GPIO mode selected
    // On 100PZ package for F28003x, if "B5, GPIO20" is used in peripheral signal digital mode,
    // then "B5" can be used for ADC
    // On 100PZ package for F28003x, if "B11, GPIO21" is used in peripheral signal digital mode,
    // then "B11" can be used for ADC
    GPIO_setAnalogMode(21, GPIO_ANALOG_DISABLED);
    GPIO_setPadConfig(myMCAN0_MCANRX_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(myMCAN0_MCANRX_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(myMCAN0_MCANTX_PIN_CONFIG);
    // AGPIO -> GPIO mode selected
    // On 100PZ package for F28003x, if "B5, GPIO20" is used in peripheral signal digital mode,
    // then "B5" can be used for ADC
    // On 100PZ package for F28003x, if "B11, GPIO21" is used in peripheral signal digital mode,
    // then "B11" can be used for ADC
    GPIO_setAnalogMode(20, GPIO_ANALOG_DISABLED);
    GPIO_setPadConfig(myMCAN0_MCANTX_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(myMCAN0_MCANTX_GPIO, GPIO_QUAL_ASYNC);


}
//*****************************************************************************
//
// INTERRUPT Configurations
//
//*****************************************************************************
void INTERRUPT_init(){
//    Interrupt_initModule();
//    Interrupt_initVectorTable();
    // Interrupt Setings for INT_myMCAN0_1
    Interrupt_register(INT_myMCAN0_1, &MCANIntr1ISR);
    Interrupt_enable(INT_myMCAN0_1);

    // Interrupt Setings for INT_myMCAN0_0
//    Interrupt_register(INT_myMCAN0_0, &MCANIntr0ISR);
//    Interrupt_enable(INT_myMCAN0_0);
    Interrupt_enableGlobal();

}
//*****************************************************************************
//
// MCAN Configurations
//
//*****************************************************************************
void MCAN_SYSCFG_init(){
    myMCAN0_init();
}

void myMCAN0_init(){
    SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_3);
    MCAN_RevisionId revid_myMCAN0;
    MCAN_InitParams initParams_myMCAN0;
    MCAN_MsgRAMConfigParams    msgRAMConfigParams_myMCAN0;
    MCAN_StdMsgIDFilterElement stdFiltelem_myMCAN0;
    MCAN_BitTimingParams       bitTimes_myMCAN0;
    //
    // Initialize MCAN Init parameters.

    initParams_myMCAN0.fdMode            = false;   // 禁用 CAN FD
    initParams_myMCAN0.brsEnable         = false;   // 禁用位速率切换
    initParams_myMCAN0.txpEnable         = false;   // 禁用发送暂停
    initParams_myMCAN0.efbi              = false;   // 禁用边沿滤波(使用默认)
    initParams_myMCAN0.pxhddisable       = false;   // 启用协议异常处理
    initParams_myMCAN0.darEnable         = false;   // 启用自动重传
    initParams_myMCAN0.wkupReqEnable     = false;   // 禁用唤醒请求
    initParams_myMCAN0.autoWkupEnable    = false;   // 禁用自动唤醒
    initParams_myMCAN0.emulationEnable   = false;   // 禁用仿真暂停
    initParams_myMCAN0.tdcEnable         = false;   // 禁用发送延迟补偿
    initParams_myMCAN0.wdcPreload        = 0;       // 看门狗预装值 0
    //
    // Transmitter Delay Compensation parameters.
    //
    initParams_myMCAN0.tdcConfig.tdcf    = 10;
    initParams_myMCAN0.tdcConfig.tdco    = 6;
    //
    // Initialize Message RAM Sections Configuration Parameters.
    //
    msgRAMConfigParams_myMCAN0.flssa                = myMCAN0_MCAN_STD_ID_FILT_START_ADDR;
    //
    // Standard ID Filter List Start Address.
    //
    msgRAMConfigParams_myMCAN0.lss                  = myMCAN0_MCAN_STD_ID_FILTER_NUM;
    //
    // List Size: Standard ID.
    //
    msgRAMConfigParams_myMCAN0.flesa                = myMCAN0_MCAN_EXT_ID_FILT_START_ADDR;
    //
    // Extended ID Filter List Start Address.
    //
    msgRAMConfigParams_myMCAN0.lse                  = myMCAN0_MCAN_EXT_ID_FILTER_NUM;
    //
    // List Size: Extended ID.
    //
    msgRAMConfigParams_myMCAN0.txStartAddr          = myMCAN0_MCAN_TX_BUFF_START_ADDR;
    //
    // Tx Buffers Start Address.
    //
    msgRAMConfigParams_myMCAN0.txBufNum             = myMCAN0_MCAN_TX_BUFF_SIZE;
    //
    // Number of Dedicated Transmit Buffers.
    //
    msgRAMConfigParams_myMCAN0.txFIFOSize           = 0;
    msgRAMConfigParams_myMCAN0.txBufMode            = 0;
    msgRAMConfigParams_myMCAN0.txBufElemSize        = MCAN_ELEM_SIZE_64BYTES;
    //
    // Tx Buffer Element Size.
    //
    msgRAMConfigParams_myMCAN0.txEventFIFOStartAddr = myMCAN0_MCAN_TX_EVENT_START_ADDR;
    //
    // Tx Event FIFO Start Address.
    //
    msgRAMConfigParams_myMCAN0.txEventFIFOSize      = myMCAN0_MCAN_TX_EVENT_SIZE;
    //
    // Event FIFO Size.
    //
    msgRAMConfigParams_myMCAN0.txEventFIFOWaterMark = 3;
    //
    // Level for Tx Event FIFO watermark interrupt.
    //
    //msgRAMConfigParams_myMCAN0.rxFIFO0startAddr     = myMCAN0_MCAN_FIFO_0_START_ADDR;
    //
    // Rx FIFO0 Start Address.
    //
    //msgRAMConfigParams_myMCAN0.rxFIFO0size          = myMCAN0_MCAN_FIFO_0_NUM;
    //
    // Number of Rx FIFO elements.
    //
    //msgRAMConfigParams_myMCAN0.rxFIFO0waterMark     = 3; // Rx FIFO0 Watermark.
    //msgRAMConfigParams_myMCAN0.rxFIFO0OpMode        = 0;
    //msgRAMConfigParams_myMCAN0.rxFIFO1startAddr     = myMCAN0_MCAN_FIFO_1_START_ADDR;
    //
    // Rx FIFO1 Start Address.
    //
    //msgRAMConfigParams_myMCAN0.rxFIFO1size          = myMCAN0_MCAN_FIFO_1_NUM;
    //
    // Number of Rx FIFO elements.
    //
   // msgRAMConfigParams_myMCAN0.rxFIFO1waterMark     = 3; // Level for Rx FIFO 1
                                                  // watermark interrupt.
    //msgRAMConfigParams_myMCAN0.rxFIFO1OpMode        = 0; // FIFO blocking mode.
    msgRAMConfigParams_myMCAN0.rxBufStartAddr       = myMCAN0_MCAN_RX_BUFF_START_ADDR;

    //
    // Rx Buffer Start Address.
    //
    msgRAMConfigParams_myMCAN0.rxBufElemSize        = MCAN_ELEM_SIZE_64BYTES;
//    //
//    // Rx Buffer Element Size.
//    //
//    msgRAMConfigParams_myMCAN0.rxFIFO0ElemSize      = MCAN_ELEM_SIZE_64BYTES;
//    //
//    // Rx FIFO0 Element Size.
//    //
//    msgRAMConfigParams_myMCAN0.rxFIFO1ElemSize      = MCAN_ELEM_SIZE_64BYTES;
    //
    // Rx FIFO1 Element Size.
    //
    //
    // Initialize bit timings.
    //
    bitTimes_myMCAN0.nomRatePrescalar   = 3; // Nominal Baud Rate Pre-scaler.
    bitTimes_myMCAN0.nomTimeSeg1        = 9; // Nominal Time segment before sample point.
    bitTimes_myMCAN0.nomTimeSeg2        = 8; // Nominal Time segment after sample point.
    bitTimes_myMCAN0.nomSynchJumpWidth  = 8; // Nominal (Re)Synchronization Jump Width Range.
    bitTimes_myMCAN0.dataRatePrescalar  = 3; // Data Baud Rate Pre-scaler.
    bitTimes_myMCAN0.dataTimeSeg1       = 4; // Data Time segment before sample point.
    bitTimes_myMCAN0.dataTimeSeg2       = 3; // Data Time segment after sample point.
    bitTimes_myMCAN0.dataSynchJumpWidth = 3; // Data (Re)Synchronization Jump Width.
    //
    //单个tq时长:1/(120MHz/3)=25ns
    //位时间总 TQ 数计算:同步段(Sync_Seg,固定1tq) + 时间段1(nomTimeSeg1) + 时间段2(nomTimeSeg2)
    //                 1+9+8=18
    //单位时间总时长:18×25ns=450ns
    //标称波特率:1/450ns=2.2Mbps
    //
    // Initialize bit timings.
    //
//    bitTimes_myMCAN0.nomRatePrescalar   = 0x3U; // Nominal Baud Rate Pre-scaler
//    bitTimes_myMCAN0.nomTimeSeg1        = 0x9U; // Nominal Time segment before SP
//    bitTimes_myMCAN0.nomTimeSeg2        = 0x8U; // Nominal Time segment after SP
//    bitTimes_myMCAN0.nomSynchJumpWidth  = 0x8U; // Nominal SJW
//    bitTimes_myMCAN0.dataRatePrescalar  = 0x1U; // Data Baud Rate Pre-scaler
//    bitTimes_myMCAN0.dataTimeSeg1       = 0x9U; // Data Time segment before SP
//    bitTimes_myMCAN0.dataTimeSeg2       = 0x8U; // Data Time segment after SP
//    bitTimes_myMCAN0.dataSynchJumpWidth = 0x8U; // Data SJW

    //
    // Get MCANSS Revision ID.
    //
    MCAN_getRevisionId(myMCAN0_BASE, &revid_myMCAN0);
    //
    // Wait for Memory initialization to be completed.
    //
    while(0 == MCAN_isMemInitDone(myMCAN0_BASE));
    //
    // Put MCAN in SW initialization mode.
    //
    MCAN_setOpMode(myMCAN0_BASE, MCAN_OPERATION_MODE_SW_INIT);
    //
    // Wait till MCAN is not initialized.
    //
    while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(myMCAN0_BASE));
    //
    // Initialize MCAN module.
    //
    MCAN_init(myMCAN0_BASE, &initParams_myMCAN0);
    //
    // Configure Bit timings.
    //
    MCAN_setBitTime(myMCAN0_BASE, &bitTimes_myMCAN0);
    //
    // Configure Message RAM Sections
    //
    MCAN_msgRAMConfig(myMCAN0_BASE, &msgRAMConfigParams_myMCAN0);
    stdFiltelem_myMCAN0.sft = MCAN_STDFILT_RANGE;
    stdFiltelem_myMCAN0.sfec = MCAN_STDFILTEC_RXBUFF;
    stdFiltelem_myMCAN0.sfid1 = 0x15AU;
    stdFiltelem_myMCAN0.sfid2 = 0x0U;

    MCAN_addStdMsgIDFilter(myMCAN0_BASE, 0U, &stdFiltelem_myMCAN0);
   // stdFiltelem_myMCAN0.sft = MCAN_STDFILT_RANGE;

    stdFiltelem_myMCAN0.sfid1 = 0x5U;
    stdFiltelem_myMCAN0.sfid2 = 0x1U;
    MCAN_addStdMsgIDFilter(myMCAN0_BASE, 1U, &stdFiltelem_myMCAN0);
    //
    // Configure Standard ID filter element 1
    //

    //
    // Internal loopback mode
    //

//    MCAN_lpbkModeEnable(myMCAN0_BASE, MCAN_LPBK_MODE_EXTERNAL, false);
    MCAN_lpbkModeEnable(myMCAN0_BASE, MCAN_LPBK_MODE_INTERNAL, false);
    //
    // Take MCAN out of the SW initialization mode
    //
    MCAN_setOpMode(myMCAN0_BASE, MCAN_OPERATION_MODE_NORMAL);
    while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(myMCAN0_BASE));
    //
    // Enable MCAN Interrupts
    //
    MCAN_enableIntr(MCANA_DRIVER_BASE, MCAN_INTR_MASK_ALL, 1U);
    MCAN_selectIntrLine(MCANA_DRIVER_BASE, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_1);
    MCAN_enableIntrLine(MCANA_DRIVER_BASE, MCAN_INTR_LINE_NUM_1, 1U);
}

__interrupt void MCANIntr1ISR(void)
{
    uint32_t intrStatus;
    MCAN_RxNewDataStatus newData;

    intrStatus = MCAN_getIntrStatus(MCANA_DRIVER_BASE);

 


    //
    //  Check to see if the interrupt is caused by a message being
    //  received in dedicated RX Buffers
    //
    if((MCAN_IR_DRX_MASK & intrStatus) == MCAN_IR_DRX_MASK)
    {
        //
        // Read the NewData registers
        //
        MCAN_getNewDataStatus(MCANA_DRIVER_BASE, &newData);

        //  If message is received in buffer element 0
        if((newData.statusLow & (1UL << 0U)) != 0)
        {
            MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U,
                          0, &rxMsg1);

            rxMsg[loopCnt] = rxMsg1;
        }
        if((newData.statusLow & (1UL << 1U)) != 0)
        {
            MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 1U,
                          0, &rxMsg1);

            rxMsg[loopCnt] = rxMsg1;
        }


        //
        //  Clearing the NewData registers
        //
        MCAN_clearNewDataStatus(MCANA_DRIVER_BASE, &newData);
    }
    else
    {
        error++;

        //
        //  Interrupt handling for other interrupt sources goes here
        //

    }

    McanaSsRegs.MCANSS_STAT.bit.RESET = 1;

    // Clear the interrupt Status.

             MCAN_clearIntrStatus(MCANA_DRIVER_BASE, intrStatus);
       //
       //  Clearing the interrupt lineNum
       //
       //PieCtrlRegs.PIEACK.all=PIEACK_GROUP9;//清除应答,复位应答响应寄存器

       HW_WR_FIELD32(MCANA_DRIVER_BASE + MCAN_MCANSS_EOI, MCAN_MCANSS_EOI, 0x2);

 


    //
    // Acknowledge this interrupt located in group 9
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

/*
 * MCAN.h
 *
 *  Created on: 2024年2月26日
 *      Author: 20695
 */

#ifndef INC_MYMCAN_H_
#define INC_MYMCAN_H_

#include "driverlib.h"
#include "device.h"
//*****************************************************************************
//
// PinMux Configurations
//
//*****************************************************************************


#define NUM_OF_MSG                      (1U)
//
// MCAN -> myMCAN0 Pinmux
//
//
// MCAN_RX - GPIO Settings
//
#define GPIO_PIN_MCAN_RX 21
#define myMCAN0_MCANRX_GPIO 21
#define myMCAN0_MCANRX_PIN_CONFIG GPIO_21_MCAN_RX
//
// MCAN_TX - GPIO Settings
//
#define GPIO_PIN_MCAN_TX 20
#define myMCAN0_MCANTX_GPIO 20
#define myMCAN0_MCANTX_PIN_CONFIG GPIO_20_MCAN_TX

//*****************************************************************************
//
// INTERRUPT Configurations
//
//*****************************************************************************

// Interrupt Settings for INT_myMCAN0_1
#define INT_myMCAN0_1 INT_MCANA_1
#define INT_myMCAN0_1_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP9
__interrupt void MCANIntr1ISR(void);

// Interrupt Settings for INT_myMCAN0_0
#define INT_myMCAN0_0 INT_MCANA_0
#define INT_myMCAN0_0_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP9
__interrupt void MCANIntr0ISR(void);

extern __interrupt void MCANIntr1ISR(void);
//*****************************************************************************
//
// MCAN Configurations
//
//*****************************************************************************
#define myMCAN0_BASE MCANA_DRIVER_BASE
#define NUM_OF_MSG                      (1U)
#define MCAN_STD_ID_FILTER_NUM          (1U)
#define MCAN_EXT_ID_FILTER_NUM          (0U)
#define MCAN_FIFO_0_NUM                 (0U)
#define MCAN_FIFO_0_ELEM_SIZE           (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_FIFO_1_NUM                 (0U)
#define MCAN_FIFO_1_ELEM_SIZE           (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_RX_BUFF_NUM                (10U)
#define MCAN_RX_BUFF_ELEM_SIZE          (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_TX_BUFF_SIZE               (0U)
#define MCAN_TX_BUFF_ELEM_SIZE          (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_TX_EVENT_SIZE              (0U)

//
// Defines
//
#define myMCAN0_MCAN_STD_ID_FILT_START_ADDR     (0)
#define myMCAN0_MCAN_STD_ID_FILTER_NUM          (4)
#define myMCAN0_MCAN_EXT_ID_FILT_START_ADDR     (myMCAN0_MCAN_STD_ID_FILT_START_ADDR + ((MCAN_STD_ID_FILTER_NUM * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U)))
#define myMCAN0_MCAN_EXT_ID_FILTER_NUM          (1)
#define myMCAN0_MCAN_TX_BUFF_START_ADDR         (148)
#define myMCAN0_MCAN_TX_BUFF_SIZE               (10)
#define myMCAN0_MCAN_FIFO_1_START_ADDR          (myMCAN0_MCAN_FIFO_0_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_0_ELEM_SIZE) * 4U * MCAN_FIFO_0_NUM))
#define myMCAN0_MCAN_FIFO_1_NUM                 (10)
#define myMCAN0_MCAN_TX_EVENT_START_ADDR        (255)
#define myMCAN0_MCAN_TX_EVENT_SIZE              (10)
#define myMCAN0_MCAN_RX_BUFF_START_ADDR         (myMCAN0_MCAN_FIFO_1_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_1_ELEM_SIZE) * 4U * MCAN_FIFO_1_NUM))
#define myMCAN0_MCAN_FIFO_0_START_ADDR          (myMCAN0_MCAN_EXT_ID_FILT_START_ADDR + ((MCAN_EXT_ID_FILTER_NUM * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U)))
#define myMCAN0_MCAN_FIFO_0_NUM                 (10)

void McanInit();
void PinMux_init1();
void myMCAN0_init();
void MCAN_SYSCFG_init();
void INTERRUPT_init();
extern int32_t loopCnt;
extern MCAN_TxBufElement txMsg[NUM_OF_MSG];
#endif /* INC_MYMCAN_H_ */

/*
 *   Copyright (c) Texas Instruments Incorporated 2016
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 *  \file     mcan.c
 *
 *  \brief    This file contains the implementation of the APIs present in the
 *            device abstraction layer file of MCAN.
 *            This also contains some related macros.
 */

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */

#include <stdint.h>
#include "inc/stw_types.h"
#include "inc/stw_dataTypes.h"
#include "inc/hw_types_mcan.h"
#include "mcan.h"
#include "debug.h"

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

/**
 * \brief  Mask and shift for Tx Buffers elements.
 */
#define MCANSS_TX_BUFFER_ELEM_ID_SHIFT                           (0U)
#define MCANSS_TX_BUFFER_ELEM_ID_MASK                            (0x1FFFFFFFU)
#define MCANSS_TX_BUFFER_ELEM_RTR_SHIFT                          (29U)
#define MCANSS_TX_BUFFER_ELEM_RTR_MASK                           (0x20000000U)
#define MCANSS_TX_BUFFER_ELEM_XTD_SHIFT                          (30U)
#define MCANSS_TX_BUFFER_ELEM_XTD_MASK                           (0x40000000U)
#define MCANSS_TX_BUFFER_ELEM_ESI_SHIFT                          (31U)
#define MCANSS_TX_BUFFER_ELEM_ESI_MASK                           (0x80000000U)
#define MCANSS_TX_BUFFER_ELEM_DLC_SHIFT                          (16U)
#define MCANSS_TX_BUFFER_ELEM_DLC_MASK                           (0x000F0000U)
#define MCANSS_TX_BUFFER_ELEM_BRS_SHIFT                          (20U)
#define MCANSS_TX_BUFFER_ELEM_BRS_MASK                           (0x00100000U)
#define MCANSS_TX_BUFFER_ELEM_FDF_SHIFT                          (21U)
#define MCANSS_TX_BUFFER_ELEM_FDF_MASK                           (0x00200000U)
#define MCANSS_TX_BUFFER_ELEM_EFC_SHIFT                          (23U)
#define MCANSS_TX_BUFFER_ELEM_EFC_MASK                           (0x00800000U)
#define MCANSS_TX_BUFFER_ELEM_MM_SHIFT                           (24U)
#define MCANSS_TX_BUFFER_ELEM_MM_MASK                            (0xFF000000U)

/**
 * \brief  Mask and shift for Rx Buffers elements.
 */
#define MCANSS_RX_BUFFER_ELEM_ID_SHIFT                           (0U)
#define MCANSS_RX_BUFFER_ELEM_ID_MASK                            (0x1FFFFFFFU)
#define MCANSS_RX_BUFFER_ELEM_RTR_SHIFT                          (29U)
#define MCANSS_RX_BUFFER_ELEM_RTR_MASK                           (0x20000000U)
#define MCANSS_RX_BUFFER_ELEM_XTD_SHIFT                          (30U)
#define MCANSS_RX_BUFFER_ELEM_XTD_MASK                           (0x40000000U)
#define MCANSS_RX_BUFFER_ELEM_ESI_SHIFT                          (31U)
#define MCANSS_RX_BUFFER_ELEM_ESI_MASK                           (0x80000000U)
#define MCANSS_RX_BUFFER_ELEM_RXTS_SHIFT                         (0U)
#define MCANSS_RX_BUFFER_ELEM_RXTS_MASK                          (0x0000FFFFU)
#define MCANSS_RX_BUFFER_ELEM_DLC_SHIFT                          (16U)
#define MCANSS_RX_BUFFER_ELEM_DLC_MASK                           (0x000F0000U)
#define MCANSS_RX_BUFFER_ELEM_BRS_SHIFT                          (20U)
#define MCANSS_RX_BUFFER_ELEM_BRS_MASK                           (0x00100000U)
#define MCANSS_RX_BUFFER_ELEM_FDF_SHIFT                          (21U)
#define MCANSS_RX_BUFFER_ELEM_FDF_MASK                           (0x00200000U)
#define MCANSS_RX_BUFFER_ELEM_FIDX_SHIFT                         (24U)
#define MCANSS_RX_BUFFER_ELEM_FIDX_MASK                          (0x7F000000U)
#define MCANSS_RX_BUFFER_ELEM_ANMF_SHIFT                         (31U)
#define MCANSS_RX_BUFFER_ELEM_ANMF_MASK                          (0x80000000U)

/**
 * \brief  Mask and shift for Standard Message ID Filter Elements.
 */
#define MCANSS_STD_ID_FILTER_SFID2_SHIFT                         (0U)
#define MCANSS_STD_ID_FILTER_SFID2_MASK                          (0x000003FFU)
#define MCANSS_STD_ID_FILTER_SFID1_SHIFT                         (16U)
#define MCANSS_STD_ID_FILTER_SFID1_MASK                          (0x03FF0000U)
#define MCANSS_STD_ID_FILTER_SFEC_SHIFT                          (27U)
#define MCANSS_STD_ID_FILTER_SFEC_MASK                           (0x38000000U)
#define MCANSS_STD_ID_FILTER_SFT_SHIFT                           (30U)
#define MCANSS_STD_ID_FILTER_SFT_MASK                            (0xC0000000U)

/**
 * \brief  Extended Message ID Filter Element.
 */
#define MCANSS_EXT_ID_FILTER_EFID2_SHIFT                        (0U)
#define MCANSS_EXT_ID_FILTER_EFID2_MASK                         (0x1FFFFFFFU)
#define MCANSS_EXT_ID_FILTER_EFID1_SHIFT                        (0U)
#define MCANSS_EXT_ID_FILTER_EFID1_MASK                         (0x1FFFFFFFU)
#define MCANSS_EXT_ID_FILTER_EFEC_SHIFT                         (29U)
#define MCANSS_EXT_ID_FILTER_EFEC_MASK                          (0xE0000000U)
#define MCANSS_EXT_ID_FILTER_EFT_SHIFT                          (30U)
#define MCANSS_EXT_ID_FILTER_EFT_MASK                           (0xC0000000U)

/**
 * \brief  Mask and shift for Tx Event FIFO elements.
 */
#define MCANSS_TX_EVENT_FIFO_ELEM_ID_SHIFT                      (0U)
#define MCANSS_TX_EVENT_FIFO_ELEM_ID_MASK                       (0x1FFFFFFFU)
#define MCANSS_TX_EVENT_FIFO_ELEM_RTR_SHIFT                     (29U)
#define MCANSS_TX_EVENT_FIFO_ELEM_RTR_MASK                      (0x20000000U)
#define MCANSS_TX_EVENT_FIFO_ELEM_XTD_SHIFT                     (30U)
#define MCANSS_TX_EVENT_FIFO_ELEM_XTD_MASK                      (0x40000000U)
#define MCANSS_TX_EVENT_FIFO_ELEM_ESI_SHIFT                     (31U)
#define MCANSS_TX_EVENT_FIFO_ELEM_ESI_MASK                      (0x80000000U)

#define MCANSS_TX_EVENT_FIFO_ELEM_TXTS_SHIFT                    (0U)
#define MCANSS_TX_EVENT_FIFO_ELEM_TXTS_MASK                     (0x0000FFFFU)
#define MCANSS_TX_EVENT_FIFO_ELEM_DLC_SHIFT                     (16U)
#define MCANSS_TX_EVENT_FIFO_ELEM_DLC_MASK                      (0x000F0000U)
#define MCANSS_TX_EVENT_FIFO_ELEM_BRS_SHIFT                     (20U)
#define MCANSS_TX_EVENT_FIFO_ELEM_BRS_MASK                      (0x00100000U)
#define MCANSS_TX_EVENT_FIFO_ELEM_FDF_SHIFT                     (21U)
#define MCANSS_TX_EVENT_FIFO_ELEM_FDF_MASK                      (0x00200000U)
#define MCANSS_TX_EVENT_FIFO_ELEM_ET_SHIFT                      (22U)
#define MCANSS_TX_EVENT_FIFO_ELEM_ET_MASK                       (0x00C00000U)
#define MCANSS_TX_EVENT_FIFO_ELEM_MM_SHIFT                      (24U)
#define MCANSS_TX_EVENT_FIFO_ELEM_MM_MASK                       (0xFF000000U)

/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                 Internal Function Declarations                             */
/* ========================================================================== */

/**
 * \brief   This API will unblock write access to write protected registers.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  None.
 */
static void MCAN_writeProtectedRegAccessUnlock(uint32_t baseAddr);

/**
 * \brief   This API will block write access to write protected registers.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  None.
 */
static void MCAN_writeProtectedRegAccessLock(uint32_t baseAddr);

/**
 * \brief   This API will load the register from ECC memory bank.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   regOffset       Offset of the register to read.
 *
 * \return  None.
 */
static void MCAN_eccLoadRegister(uint32_t baseAddr, uint32_t regOffset);

/**
 * \brief   This API will read the message object from Message RAM.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   elemAddr        Address of the message object.
 * \param   elem            Message Object.
 *                          Refer struct #MCAN_RxBufElement.
 *
 * \return  None.
 */
static void MCAN_readMsg(uint32_t           baseAddr,
                         uint32_t           elemAddr,
                         MCAN_RxBufElement *elem);

/**
 * \brief   This API will write the message object to Message RAM.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   elemAddr        Address of the message object.
 * \param   elem            Message Object.
 *                          Refer struct #MCAN_TxBufElement.
 *
 * \return  None.
 */
static void MCAN_writeMsg(uint32_t                 baseAddr,
                          uint32_t                 elemAddr,
                          const MCAN_TxBufElement *elem);

/**
 * \brief   This API will return payload depending on 'dlc'  field.
 *
 * \param   dlc             Data Length Code.
 *
 * \return  data size       Size of the payload.
 */
static uint32_t MCAN_getDataSize(uint32_t dlc);

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */

void MCAN_selectClockSource(uint32_t baseAddr, MCAN_ClockSource source)
{
    //
    // Determine the CAN controller and set specified clock source
    //
    EALLOW;

    switch(baseAddr)
    {
        case MCANA_DRIVER_BASE:
            HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) =
                    (HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL2) &
                    ~SYSCTL_CLKSRCCTL2_MCANABCLKSEL_M) | 
                    ((uint16_t)source << SYSCTL_CLKSRCCTL2_MCANABCLKSEL_S);   
            break;


        default:

            //
            // Do nothing. Not a valid mode value.
            //
            break;
    }

    EDIS;

}

uint32_t MCAN_isInReset(uint32_t baseAddr)
{
    uint32_t reset;
    uint32_t state;

    reset = HW_RD_FIELD32(baseAddr + MCAN_MCANSS_STAT,
                          MCAN_MCANSS_STAT_RESET);
    if(1U == reset)
    {
        state = (uint32_t) TRUE;
    }
    else
    {
        state = (uint32_t) FALSE;
    }
    return state;
}

uint32_t MCAN_isFDOpEnable(uint32_t baseAddr)
{
    uint32_t fdoe;
    uint32_t state;

    fdoe = HW_RD_FIELD32(baseAddr + MCAN_MCANSS_STAT,
                         MCAN_MCANSS_STAT_ENABLE_FDOE);
    if(1U == fdoe)
    {
        state = (uint32_t) TRUE;
    }
    else
    {
        state = (uint32_t) FALSE;
    }
    return state;
}

uint32_t MCAN_isMemInitDone(uint32_t baseAddr)
{
    uint32_t memInit;
    uint32_t state;

    memInit = HW_RD_FIELD32(baseAddr + MCAN_MCANSS_STAT,
                            MCAN_MCANSS_STAT_MEM_INIT_DONE);
    if(1U == memInit)
    {
        state = (uint32_t) TRUE;
    }
    else
    {
        state = (uint32_t) FALSE;
    }
    return state;
}

void MCAN_setOpMode(uint32_t baseAddr, uint32_t mode)
{
    HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_INIT, mode);
}

uint32_t MCAN_getOpMode(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_INIT));
}

int32_t MCAN_init(uint32_t baseAddr, const MCAN_InitParams *initParams)
{
    int32_t  status;
    uint32_t regVal;

    /* Configure MCAN wakeup and clock stop controls */
    regVal = HW_RD_REG32(baseAddr + MCAN_MCANSS_CTRL);
    HW_SET_FIELD32(regVal,
                   MCAN_MCANSS_CTRL_WAKEUPREQEN,
                   initParams->wkupReqEnable);
    HW_SET_FIELD32(regVal,
                   MCAN_MCANSS_CTRL_AUTOWAKEUP,
                   initParams->autoWkupEnable);
    HW_SET_FIELD32(regVal,
                   MCAN_MCANSS_CTRL_EMUEN,
                   initParams->emulationEnable);

    HW_WR_REG32(baseAddr + MCAN_MCANSS_CTRL, regVal);

    MCAN_writeProtectedRegAccessUnlock(baseAddr);

    /* Configure MCAN mode(FD vs Classic CAN operation) and controls */
    regVal = HW_RD_REG32(baseAddr + MCAN_CCCR);
    HW_SET_FIELD32(regVal,
                   MCAN_CCCR_FDOE,
                   initParams->fdMode);
    HW_SET_FIELD32(regVal,
                   MCAN_CCCR_BRSE,
                   initParams->brsEnable);
    HW_SET_FIELD32(regVal,
                   MCAN_CCCR_TXP,
                   initParams->txpEnable);
    HW_SET_FIELD32(regVal,
                   MCAN_CCCR_EFBI,
                   initParams->efbi);
    HW_SET_FIELD32(regVal,
                   MCAN_CCCR_PXHD,
                   initParams->pxhddisable);
    HW_SET_FIELD32(regVal,
                   MCAN_CCCR_DAR,
                   initParams->darEnable);
    HW_WR_REG32(baseAddr + MCAN_CCCR, regVal);

    if((MCAN_TDCR_TDCF_MAX >= initParams->tdcConfig.tdcf) &&
        (MCAN_TDCR_TDCO_MAX >= initParams->tdcConfig.tdco) &&
        (MCAN_RWD_WDC_MAX >= initParams->wdcPreload))
    {
        /* Configure Transceiver Delay Compensation */
        HW_WR_FIELD32(baseAddr + MCAN_TDCR,
                      MCAN_TDCR_TDCF,
                      initParams->tdcConfig.tdcf);
        HW_WR_FIELD32(baseAddr + MCAN_TDCR,
                      MCAN_TDCR_TDCO,
                      initParams->tdcConfig.tdco);
        /* Configure MSG RAM watchdog counter preload value */
        HW_WR_FIELD32(baseAddr + MCAN_RWD,
                      MCAN_RWD_WDC,
                      initParams->wdcPreload);
        /* Enable/Disable Transceiver Delay Compensation */
        HW_WR_FIELD32(baseAddr + MCAN_DBTP,
                      MCAN_DBTP_TDC,
                      initParams->tdcEnable);
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }

    MCAN_writeProtectedRegAccessLock(baseAddr);

    return status;
}

int32_t MCAN_config(uint32_t baseAddr, const MCAN_ConfigParams *configParams)
{
    int32_t status;

    MCAN_writeProtectedRegAccessUnlock(baseAddr);

    /* Configure MCAN control registers */
    HW_WR_FIELD32(baseAddr + MCAN_CCCR,
                  MCAN_CCCR_MON,
                  configParams->monEnable);
    HW_WR_FIELD32(baseAddr + MCAN_CCCR,
                  MCAN_CCCR_ASM,
                  configParams->asmEnable);
    /* Configure Global Filter */
    HW_WR_FIELD32(baseAddr + MCAN_GFC,
                  MCAN_GFC_RRFE,
                  configParams->filterConfig.rrfe);
    HW_WR_FIELD32(baseAddr + MCAN_GFC,
                  MCAN_GFC_RRFS,
                  configParams->filterConfig.rrfs);
    HW_WR_FIELD32(baseAddr + MCAN_GFC,
                  MCAN_GFC_ANFE,
                  configParams->filterConfig.anfe);
    HW_WR_FIELD32(baseAddr + MCAN_GFC,
                  MCAN_GFC_ANFS,
                  configParams->filterConfig.anfs);

    if((MCAN_TSCC_TCP_MAX >= configParams->tsPrescalar) &&
        (MCAN_TOCC_TOP_MAX >= configParams->timeoutPreload))
    {
        /* Configure Time-stamp counter */
        HW_WR_FIELD32(baseAddr + MCAN_TSCC,
                      MCAN_TSCC_TSS,
                      configParams->tsSelect);
        HW_WR_FIELD32(baseAddr + MCAN_TSCC,
                      MCAN_TSCC_TCP,
                      (configParams->tsPrescalar - 1U));
        /* Configure Time-out counter */
        HW_WR_FIELD32(baseAddr + MCAN_TOCC,
                      MCAN_TOCC_TOS,
                      configParams->timeoutSelect);
        HW_WR_FIELD32(baseAddr + MCAN_TOCC,
                      MCAN_TOCC_TOP,
                      configParams->timeoutPreload);
        /* Enable Time-out counter */
        HW_WR_FIELD32(baseAddr + MCAN_TOCC,
                      MCAN_TOCC_ETOC,
                      configParams->timeoutCntEnable);
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }

    MCAN_writeProtectedRegAccessLock(baseAddr);

    return status;
}

void MCAN_eccConfig(uint32_t                    baseAddr,
                    const MCAN_ECCConfigParams *configParams)
{
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_CONTROL);
    HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_CONTROL,
                  MCAN_ECC_AGGR_CONTROL_ECC_CHECK,
                  configParams->enableChk);
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_CONTROL);
    HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_CONTROL,
                  MCAN_ECC_AGGR_CONTROL_ECC_ENABLE,
                  configParams->enable);
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_CONTROL);
    HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_CONTROL,
                  MCAN_ECC_AGGR_CONTROL_ENABLE_RMW,
                  configParams->enableRdModWr);
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_CONTROL);

}

int32_t MCAN_setBitTime(uint32_t                    baseAddr,
                        const MCAN_BitTimingParams *configParams)
{
    int32_t status;

    MCAN_writeProtectedRegAccessUnlock(baseAddr);

    if((MCAN_NBTP_NSJW_MAX >= configParams->nomSynchJumpWidth) &&
        (MCAN_NBTP_NTSEG2_MAX >= configParams->nomTimeSeg2) &&
        (MCAN_NBTP_NTSEG1_MAX >= configParams->nomTimeSeg1) &&
        (MCAN_NBTP_NBRP_MAX >= configParams->nomRatePrescalar))
    {
        HW_WR_FIELD32(baseAddr + MCAN_NBTP,
                      MCAN_NBTP_NSJW,
                      configParams->nomSynchJumpWidth);
        HW_WR_FIELD32(baseAddr + MCAN_NBTP,
                      MCAN_NBTP_NTSEG2,
                      configParams->nomTimeSeg2);
        HW_WR_FIELD32(baseAddr + MCAN_NBTP,
                      MCAN_NBTP_NTSEG1,
                      configParams->nomTimeSeg1);
        HW_WR_FIELD32(baseAddr + MCAN_NBTP,
                      MCAN_NBTP_NBRP,
                      configParams->nomRatePrescalar);
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }
    if(STW_SOK == status)
    {
        if((MCAN_DBTP_DSJW_MAX >= configParams->dataSynchJumpWidth) &&
            (MCAN_DBTP_DTSEG2_MAX >= configParams->dataTimeSeg2) &&
            (MCAN_DBTP_DTSEG1_MAX >= configParams->dataTimeSeg1) &&
            (MCAN_DBTP_DBRP_MAX >= configParams->dataRatePrescalar))
        {
            HW_WR_FIELD32(baseAddr + MCAN_DBTP,
                          MCAN_DBTP_DSJW,
                          configParams->dataSynchJumpWidth);
            HW_WR_FIELD32(baseAddr + MCAN_DBTP,
                          MCAN_DBTP_DTSEG2,
                          configParams->dataTimeSeg2);
            HW_WR_FIELD32(baseAddr + MCAN_DBTP,
                          MCAN_DBTP_DTSEG1,
                          configParams->dataTimeSeg1);
            HW_WR_FIELD32(baseAddr + MCAN_DBTP,
                          MCAN_DBTP_DBRP,
                          configParams->dataRatePrescalar);
            status = STW_SOK;
        }
        else
        {
            status = STW_EFAIL;
        }
    }

    MCAN_writeProtectedRegAccessLock(baseAddr);
    return status;
}

int32_t MCAN_msgRAMConfig(uint32_t                       baseAddr,
                          const MCAN_MsgRAMConfigParams *msgRAMConfigParams)
{
    int32_t  status;
    uint32_t elemNum = 0U;

    MCAN_writeProtectedRegAccessUnlock(baseAddr);

    /* Configure Message Filters section */
    if(0U != msgRAMConfigParams->lss)
    {
        HW_WR_FIELD32(baseAddr + MCAN_SIDFC,
                      MCAN_SIDFC_FLSSA,
                      (msgRAMConfigParams->flssa >> 2U));
        HW_WR_FIELD32(baseAddr + MCAN_SIDFC,
                      MCAN_SIDFC_LSS,
                      msgRAMConfigParams->lss);
    }
    if(0U != msgRAMConfigParams->lse)
    {
        HW_WR_FIELD32(baseAddr + MCAN_XIDFC,
                      MCAN_XIDFC_FLESA,
                      (msgRAMConfigParams->flesa >> 2U));
        HW_WR_FIELD32(baseAddr + MCAN_XIDFC,
                      MCAN_XIDFC_LSE,
                      msgRAMConfigParams->lse);
    }
    /* Configure Rx FIFO 0 section */
    if(0U != msgRAMConfigParams->rxFIFO0size)
    {
        HW_WR_FIELD32(baseAddr + MCAN_RXF0C,
                      MCAN_RXF0C_F0SA,
                      (msgRAMConfigParams->rxFIFO0startAddr >> 2U));
        HW_WR_FIELD32(baseAddr + MCAN_RXF0C,
                      MCAN_RXF0C_F0S,
                      msgRAMConfigParams->rxFIFO0size);
        HW_WR_FIELD32(baseAddr + MCAN_RXF0C,
                      MCAN_RXF0C_F0WM,
                      msgRAMConfigParams->rxFIFO0waterMark);
        HW_WR_FIELD32(baseAddr + MCAN_RXF0C,
                      MCAN_RXF0C_F0OM,
                      msgRAMConfigParams->rxFIFO0OpMode);
        /* Configure Rx FIFO0 elements size */
        HW_WR_FIELD32(baseAddr + MCAN_RXESC,
                      MCAN_RXESC_F0DS,
                      msgRAMConfigParams->rxFIFO0ElemSize);
    }
    /* Configure Rx FIFO 1 section */
    if(0U != msgRAMConfigParams->rxFIFO1size)
    {
        HW_WR_FIELD32(baseAddr + MCAN_RXF1C,
                      MCAN_RXF1C_F1SA,
                      (msgRAMConfigParams->rxFIFO1startAddr >> 2U));
        HW_WR_FIELD32(baseAddr + MCAN_RXF1C,
                      MCAN_RXF1C_F1S,
                      msgRAMConfigParams->rxFIFO1size);
        HW_WR_FIELD32(baseAddr + MCAN_RXF1C,
                      MCAN_RXF1C_F1WM,
                      msgRAMConfigParams->rxFIFO1waterMark);
        HW_WR_FIELD32(baseAddr + MCAN_RXF1C,
                      MCAN_RXF1C_F1OM,
                      msgRAMConfigParams->rxFIFO1OpMode);
        /* Configure Rx FIFO1 elements size */
        HW_WR_FIELD32(baseAddr + MCAN_RXESC,
                      MCAN_RXESC_F1DS,
                      msgRAMConfigParams->rxFIFO1ElemSize);
    }
    /* Configure Rx Buffer Start Address */
    HW_WR_FIELD32(baseAddr + MCAN_RXBC,
                  MCAN_RXBC_RBSA,
                  (msgRAMConfigParams->rxBufStartAddr >> 2U));
    /* Configure Rx Buffer elements size */
    HW_WR_FIELD32(baseAddr + MCAN_RXESC,
                  MCAN_RXESC_RBDS,
                  msgRAMConfigParams->rxBufElemSize);
    /* Configure Tx Event FIFO section */
    if(0U != msgRAMConfigParams->txEventFIFOSize)
    {
        HW_WR_FIELD32(baseAddr + MCAN_TXEFC,
                      MCAN_TXEFC_EFSA,
                      (msgRAMConfigParams->txEventFIFOStartAddr >> 2U));
        HW_WR_FIELD32(baseAddr + MCAN_TXEFC,
                      MCAN_TXEFC_EFS,
                      msgRAMConfigParams->txEventFIFOSize);
        HW_WR_FIELD32(baseAddr + MCAN_TXEFC,
                      MCAN_TXEFC_EFWM,
                      msgRAMConfigParams->txEventFIFOWaterMark);
    }
    /* Configure Tx Buffer and FIFO/Q section */
    elemNum = msgRAMConfigParams->txBufNum + msgRAMConfigParams->txFIFOSize;
    if((MCANSS_TX_BUFFER_MAX >= elemNum) &&
        ((0U != msgRAMConfigParams->txBufNum) ||
         (0U != msgRAMConfigParams->txFIFOSize)))
    {
        HW_WR_FIELD32(baseAddr + MCAN_TXBC,
                      MCAN_TXBC_TBSA,
                      (msgRAMConfigParams->txStartAddr >> 2U));
        HW_WR_FIELD32(baseAddr + MCAN_TXBC,
                      MCAN_TXBC_NDTB,
                      msgRAMConfigParams->txBufNum);
        HW_WR_FIELD32(baseAddr + MCAN_TXBC,
                      MCAN_TXBC_TFQS,
                      msgRAMConfigParams->txFIFOSize);
        HW_WR_FIELD32(baseAddr + MCAN_TXBC,
                      MCAN_TXBC_TFQM,
                      msgRAMConfigParams->txBufMode);
        /* Configure Tx Buffer/FIFO0/FIFO1 elements size */
        HW_WR_FIELD32(baseAddr + MCAN_TXESC,
                      MCAN_TXESC_TBDS,
                      msgRAMConfigParams->txBufElemSize);
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }

    MCAN_writeProtectedRegAccessLock(baseAddr);

    return status;
}

int32_t MCAN_setExtIDAndMask(uint32_t baseAddr, uint32_t idMask)
{
    int32_t status;

    if(MCAN_XIDAM_EIDM_MAX >= idMask)
    {
        MCAN_writeProtectedRegAccessUnlock(baseAddr);

        HW_WR_FIELD32(baseAddr + MCAN_XIDAM,
                      MCAN_XIDAM_EIDM,
                      idMask);

        MCAN_writeProtectedRegAccessLock(baseAddr);
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }
    return status;
}

void MCAN_writeMsgRam(uint32_t                 baseAddr,
                      uint32_t                 memType,
                      uint32_t                 bufNum,
                      const MCAN_TxBufElement *elem)
{
    uint32_t startAddr = 0U, elemSize = 0U, elemAddr = 0U;
    uint32_t idx       = 0U, enableMod = 0U;

    if((uint32_t)MCAN_MEM_TYPE_BUF == memType)
    {
        idx       = bufNum;
        enableMod = 1U;
    }
    if((uint32_t)MCAN_MEM_TYPE_FIFO == memType)
    {
        idx       = HW_RD_FIELD32(baseAddr + MCAN_TXFQS, MCAN_TXFQS_TFQPI);
        enableMod = 1U;
    }
    if(1U == enableMod)
    {
        startAddr = HW_RD_FIELD32(baseAddr + MCAN_TXBC,
                                  MCAN_TXBC_TBSA);
        elemSize = HW_RD_FIELD32(baseAddr + MCAN_TXESC,
                                 MCAN_TXESC_TBDS);
        startAddr = (uint32_t) (startAddr << 2U);
        elemSize  = MCAN_getMsgObjSize(elemSize);
        elemSize *= 4U;
        elemAddr  = startAddr + (elemSize * idx);
        elemAddr += MCAN_MCAN_MSG_MEM;
        MCAN_writeMsg(baseAddr, elemAddr, elem);
    }
}

int32_t MCAN_txBufAddReq(uint32_t baseAddr, uint32_t bufNum)
{
    int32_t  status;
    uint32_t regVal;

    if(MCANSS_TX_BUFFER_MAX > bufNum)
    {
        regVal  = HW_RD_REG32(baseAddr + MCAN_TXBAR);
        regVal |= ((uint32_t) 1U << bufNum);

        // For writing to TXBAR CCE bit should be '0'. This need not be
        // reverted because for other qualified writes this is locked state
        // and can't be written.
        MCAN_writeProtectedRegAccessLock(baseAddr);
        HW_WR_REG32(baseAddr + MCAN_TXBAR, regVal);

        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }
    return status;
}

void  MCAN_getNewDataStatus(uint32_t              baseAddr,
                            MCAN_RxNewDataStatus *newDataStatus)
{
    newDataStatus->statusLow  = HW_RD_REG32(baseAddr + MCAN_NDAT1);
    newDataStatus->statusHigh = HW_RD_REG32(baseAddr + MCAN_NDAT2);
}

void  MCAN_clearNewDataStatus(uint32_t                    baseAddr,
                              const MCAN_RxNewDataStatus *newDataStatus)
{
    HW_WR_REG32(baseAddr + MCAN_NDAT1, newDataStatus->statusLow);
    HW_WR_REG32(baseAddr + MCAN_NDAT2, newDataStatus->statusHigh);
}

void MCAN_readMsgRam(uint32_t           baseAddr,
                     uint32_t           memType,
                     uint32_t           bufNum,
                     uint32_t           fifoNum,
                     MCAN_RxBufElement *elem)
{
    uint32_t startAddr = 0U, elemSize = 0U, elemAddr = 0U;
    uint32_t enableMod = 0U, idx = 0U;

    if((uint32_t)MCAN_MEM_TYPE_BUF == memType)
    {
        startAddr = HW_RD_FIELD32(baseAddr + MCAN_RXBC,
                                  MCAN_RXBC_RBSA);
        elemSize = HW_RD_FIELD32(baseAddr + MCAN_RXESC,
                                 MCAN_RXESC_RBDS);
        idx       = bufNum;
        enableMod = 1U;
    }
    if((uint32_t)MCAN_MEM_TYPE_FIFO == memType)
    {
        switch (fifoNum)
        {
            case MCAN_RX_FIFO_NUM_0:
                startAddr = HW_RD_FIELD32(baseAddr + MCAN_RXF0C,
                                          MCAN_RXF0C_F0SA);
                elemSize = HW_RD_FIELD32(baseAddr + MCAN_RXESC,
                                         MCAN_RXESC_F0DS);
                idx = HW_RD_FIELD32(baseAddr + MCAN_RXF0S,
                                    MCAN_RXF0S_F0GI);
                enableMod = 1U;
                break;
            case MCAN_RX_FIFO_NUM_1:
                startAddr = HW_RD_FIELD32(baseAddr + MCAN_RXF1C,
                                          MCAN_RXF1C_F1SA);
                elemSize = HW_RD_FIELD32(baseAddr + MCAN_RXESC,
                                         MCAN_RXESC_F1DS);
                idx = HW_RD_FIELD32(baseAddr + MCAN_RXF1S,
                                    MCAN_RXF1S_F1GI);
                enableMod = 1U;
                break;
            default:
                /* Invalid option */
                break;
        }
    }
    if(1U == enableMod)
    {
        startAddr = (uint32_t) (startAddr << 2U);
        elemSize  = MCAN_getMsgObjSize(elemSize);
        elemSize *= 4U;
        elemAddr  = startAddr + (elemSize * idx);
        elemAddr += MCAN_MCAN_MSG_MEM;
        MCAN_readMsg(baseAddr, elemAddr, elem);
    }
}

void MCAN_readTxEventFIFO(uint32_t           baseAddr,
                          MCAN_TxEventFIFOElement *txEventElem)
{
    uint32_t startAddr = 0U, elemSize = 0U, elemAddr = 0U;
    uint32_t idx = 0U, regVal;


    startAddr = HW_RD_FIELD32(baseAddr + MCAN_TXEFC,
                              MCAN_TXEFC_EFSA);
    elemSize = MCANSS_TX_EVENT_FIFO_SIZE_WORDS;
    idx = HW_RD_FIELD32(baseAddr + MCAN_TXEFS,
                        MCAN_TXEFS_EFGI);

    startAddr = (uint32_t) (startAddr << 2U);
    elemSize *= 4U;
    elemAddr  = startAddr + (elemSize * idx);
    elemAddr += MCAN_MCAN_MSG_MEM;

    regVal   = HW_RD_REG32(baseAddr + elemAddr);
    txEventElem->id = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_ID_MASK)
                           >> MCANSS_TX_EVENT_FIFO_ELEM_ID_SHIFT);
    txEventElem->rtr = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_RTR_MASK)
                            >> MCANSS_TX_EVENT_FIFO_ELEM_RTR_SHIFT);
    txEventElem->xtd = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_XTD_MASK)
                            >> MCANSS_TX_EVENT_FIFO_ELEM_XTD_SHIFT);
    txEventElem->esi = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_ESI_MASK)
                            >> MCANSS_TX_EVENT_FIFO_ELEM_ESI_SHIFT);
    elemAddr  += 4U;
    regVal     = HW_RD_REG32(baseAddr + elemAddr);
    txEventElem->txts = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_TXTS_MASK)
                             >> MCANSS_TX_EVENT_FIFO_ELEM_TXTS_SHIFT);
    txEventElem->dlc = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_DLC_MASK)
                            >> MCANSS_TX_EVENT_FIFO_ELEM_DLC_SHIFT);
    txEventElem->brs = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_BRS_MASK)
                            >> MCANSS_TX_EVENT_FIFO_ELEM_BRS_SHIFT);
    txEventElem->fdf = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_FDF_MASK)
                            >> MCANSS_TX_EVENT_FIFO_ELEM_FDF_SHIFT);
    txEventElem->et = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_ET_MASK)
                             >> MCANSS_TX_EVENT_FIFO_ELEM_ET_SHIFT);
    txEventElem->mm = (uint32_t) ((regVal & MCANSS_TX_EVENT_FIFO_ELEM_MM_MASK)
                             >> MCANSS_TX_EVENT_FIFO_ELEM_MM_SHIFT);
}

void MCAN_addStdMsgIDFilter(uint32_t                          baseAddr,
                            uint32_t                          filtNum,
                            const MCAN_StdMsgIDFilterElement *elem)
{
    uint32_t startAddr, elemAddr, regVal;

    startAddr = HW_RD_FIELD32(baseAddr + MCAN_SIDFC,
                              MCAN_SIDFC_FLSSA);
    startAddr = (uint32_t) (startAddr << 2U);
    elemAddr  = startAddr + (filtNum * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U);
    elemAddr += MCAN_MCAN_MSG_MEM;

    regVal  = 0U;
    regVal |= (uint32_t) (elem->sfid2 << MCANSS_STD_ID_FILTER_SFID2_SHIFT);
    regVal |= (uint32_t) (elem->sfid1 << MCANSS_STD_ID_FILTER_SFID1_SHIFT);
    regVal |= (uint32_t) (elem->sfec << MCANSS_STD_ID_FILTER_SFEC_SHIFT);
    regVal |= (uint32_t) (elem->sft << MCANSS_STD_ID_FILTER_SFT_SHIFT);
    HW_WR_REG32(baseAddr + elemAddr, regVal);
}

void MCAN_addExtMsgIDFilter(uint32_t                          baseAddr,
                            uint32_t                          filtNum,
                            const MCAN_ExtMsgIDFilterElement *elem)
{
    uint32_t startAddr, elemAddr, regVal;

    startAddr = HW_RD_FIELD32(baseAddr + MCAN_XIDFC,
                              MCAN_XIDFC_FLESA);
    startAddr = (uint32_t) (startAddr << 2U);
    elemAddr  = startAddr + (filtNum * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U);
    elemAddr += MCAN_MCAN_MSG_MEM;

    regVal  = 0U;
    regVal |= (uint32_t) (elem->efid1 << MCANSS_EXT_ID_FILTER_EFID1_SHIFT);
    regVal |= (uint32_t) (elem->efec << MCANSS_EXT_ID_FILTER_EFEC_SHIFT);
    HW_WR_REG32(baseAddr + elemAddr, regVal);

    elemAddr += 4U;
    regVal    = 0U;
    regVal   |= (uint32_t) (elem->efid2 << MCANSS_EXT_ID_FILTER_EFID2_SHIFT);
    regVal   |= (uint32_t) (elem->eft << MCANSS_EXT_ID_FILTER_EFT_SHIFT);
    HW_WR_REG32(baseAddr + elemAddr, regVal);
}

void MCAN_lpbkModeEnable(uint32_t baseAddr,
                         uint32_t lpbkMode,
                         uint32_t enable)
{
    MCAN_writeProtectedRegAccessUnlock(baseAddr);

    if(TRUE == enable)
    {
        HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_TEST, 0x1U);
        HW_WR_FIELD32(baseAddr + MCAN_TEST,
                      MCAN_TEST_LBCK,
                      enable);
        if((uint32_t)MCAN_LPBK_MODE_INTERNAL == lpbkMode)
        {
            HW_WR_FIELD32(baseAddr + MCAN_CCCR,
                          MCAN_CCCR_MON,
                          0x1U);
        }
    }
    else
    {
        HW_WR_FIELD32(baseAddr + MCAN_TEST,
                      MCAN_TEST_LBCK,
                      enable);
        HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_TEST, 0x0U);
        if((uint32_t)MCAN_LPBK_MODE_INTERNAL == lpbkMode)
        {
            HW_WR_FIELD32(baseAddr + MCAN_CCCR,
                          MCAN_CCCR_MON,
                          0x0U);
        }
    }
    MCAN_writeProtectedRegAccessLock(baseAddr);
}

void  MCAN_getErrCounters(uint32_t           baseAddr,
                          MCAN_ErrCntStatus *errCounter)
{
    errCounter->transErrLogCnt = HW_RD_FIELD32(baseAddr + MCAN_ECR,
                                               MCAN_ECR_TEC);
    errCounter->recErrCnt = HW_RD_FIELD32(baseAddr + MCAN_ECR,
                                          MCAN_ECR_REC);
    errCounter->rpStatus = HW_RD_FIELD32(baseAddr + MCAN_ECR,
                                         MCAN_ECR_RP);
    errCounter->canErrLogCnt = HW_RD_FIELD32(baseAddr + MCAN_ECR,
                                             MCAN_ECR_CEL);
}

void  MCAN_getProtocolStatus(uint32_t             baseAddr,
                             MCAN_ProtocolStatus *protStatus)
{
    uint32_t regVal;

    regVal = HW_RD_REG32(baseAddr + MCAN_PSR);
    protStatus->lastErrCode   = HW_GET_FIELD(regVal, MCAN_PSR_LEC);
    protStatus->act           = HW_GET_FIELD(regVal, MCAN_PSR_ACT);
    protStatus->errPassive    = HW_GET_FIELD(regVal, MCAN_PSR_EP);
    protStatus->warningStatus = HW_GET_FIELD(regVal, MCAN_PSR_EW);
    protStatus->busOffStatus  = HW_GET_FIELD(regVal, MCAN_PSR_BO);
    protStatus->dlec          = HW_GET_FIELD(regVal, MCAN_PSR_DLEC);
    protStatus->resi          = HW_GET_FIELD(regVal, MCAN_PSR_RESI);
    protStatus->rbrs          = HW_GET_FIELD(regVal, MCAN_PSR_RBRS);
    protStatus->rfdf          = HW_GET_FIELD(regVal, MCAN_PSR_RFDF);
    protStatus->pxe           = HW_GET_FIELD(regVal, MCAN_PSR_PXE);
    protStatus->tdcv          = HW_GET_FIELD(regVal, MCAN_PSR_TDCV);
}

void MCAN_enableIntr(uint32_t baseAddr, uint32_t intrMask, uint32_t enable)
{
    uint32_t regVal;

    if(TRUE == enable)
    {
        regVal  = HW_RD_REG32(baseAddr + MCAN_IE);
        regVal |= intrMask;
        HW_WR_REG32(baseAddr + MCAN_IE, regVal);
    }
    else
    {
        regVal  = HW_RD_REG32(baseAddr + MCAN_IE);
        regVal &= ~intrMask;
        HW_WR_REG32(baseAddr + MCAN_IE, regVal);
    }
}

void MCAN_selectIntrLine(uint32_t baseAddr,
                         uint32_t intrMask,
                         uint32_t lineNum)
{
    uint32_t regVal;

    if((uint32_t)MCAN_INTR_LINE_NUM_0 == lineNum)
    {
        regVal  = HW_RD_REG32(baseAddr + MCAN_ILS);
        regVal &= ~intrMask;
        HW_WR_REG32(baseAddr + MCAN_ILS, regVal);
    }
    else
    {
        regVal  = HW_RD_REG32(baseAddr + MCAN_ILS);
        regVal |= intrMask;
        HW_WR_REG32(baseAddr + MCAN_ILS, regVal);
    }
}

uint32_t MCAN_getIntrLineSelectStatus(uint32_t baseAddr)
{
    return(HW_RD_REG32(baseAddr + MCAN_ILS));
}

void MCAN_enableIntrLine(uint32_t baseAddr,
                         uint32_t lineNum,
                         uint32_t enable)
{
    uint32_t regVal;

    lineNum &= MCANSS_INTR_LINE_EN_MASK;
    regVal   = HW_RD_REG32(baseAddr + MCAN_ILE);
    regVal  &= ~((uint32_t) 0x1U << lineNum);
    regVal  |= (uint32_t) (enable << lineNum);
    HW_WR_REG32(baseAddr + MCAN_ILE, regVal);
}

uint32_t MCAN_getIntrStatus(uint32_t baseAddr)
{
    return(HW_RD_REG32(baseAddr + MCAN_IR));
}

void MCAN_clearIntrStatus(uint32_t baseAddr, uint32_t intrMask)
{
    HW_WR_REG32(baseAddr + MCAN_IR, intrMask);
}

void MCAN_clearInterrupt(uint32_t baseAddr, uint16_t intrNum)
{
    HW_WR_FIELD32(baseAddr + MCAN_MCANSS_EOI, MCAN_MCANSS_EOI, intrNum);
}

void  MCAN_getHighPriorityMsgStatus(uint32_t                  baseAddr,
                                    MCAN_HighPriorityMsgInfo *hpm)
{
    hpm->bufIdx = HW_RD_FIELD32(baseAddr + MCAN_HPMS,
                                MCAN_HPMS_BIDX);
    hpm->msi = HW_RD_FIELD32(baseAddr + MCAN_HPMS,
                             MCAN_HPMS_MSI);
    hpm->filterIdx = HW_RD_FIELD32(baseAddr + MCAN_HPMS,
                                   MCAN_HPMS_FIDX);
    hpm->filterList = HW_RD_FIELD32(baseAddr + MCAN_HPMS,
                                    MCAN_HPMS_FLST);
}

void MCAN_getRxFIFOStatus(uint32_t           baseAddr,
                          MCAN_RxFIFOStatus *fifoStatus)
{
    uint32_t regVal;

    switch (fifoStatus->num)
    {
        case MCAN_RX_FIFO_NUM_0:
            regVal = HW_RD_REG32(baseAddr + MCAN_RXF0S);
            fifoStatus->fillLvl  = HW_GET_FIELD(regVal, MCAN_RXF0S_F0FL);
            fifoStatus->getIdx   = HW_GET_FIELD(regVal, MCAN_RXF0S_F0GI);
            fifoStatus->putIdx   = HW_GET_FIELD(regVal, MCAN_RXF0S_F0PI);
            fifoStatus->fifoFull = HW_GET_FIELD(regVal, MCAN_RXF0S_F0F);
            fifoStatus->msgLost  = HW_GET_FIELD(regVal, MCAN_RXF0S_RF0L);
            break;
        case MCAN_RX_FIFO_NUM_1:
            regVal = HW_RD_REG32(baseAddr + MCAN_RXF1S);
            fifoStatus->fillLvl  = HW_GET_FIELD(regVal, MCAN_RXF1S_F1FL);
            fifoStatus->getIdx   = HW_GET_FIELD(regVal, MCAN_RXF1S_F1GI);
            fifoStatus->putIdx   = HW_GET_FIELD(regVal, MCAN_RXF1S_F1PI);
            fifoStatus->fifoFull = HW_GET_FIELD(regVal, MCAN_RXF1S_F1F);
            fifoStatus->msgLost  = HW_GET_FIELD(regVal, MCAN_RXF1S_RF1L);
            break;
        default:
            /* Invalid option */
            break;
    }
}

int32_t MCAN_writeRxFIFOAck(uint32_t baseAddr,
                            uint32_t fifoNum,
                            uint32_t idx)
{
    int32_t  status;
    uint32_t size;

    switch (fifoNum)
    {
        case MCAN_RX_FIFO_NUM_0:
            size = HW_RD_FIELD32(baseAddr + MCAN_RXF0C,
                                 MCAN_RXF0C_F0S);
            if(size >= idx)
            {
                HW_WR_FIELD32(baseAddr + MCAN_RXF0A,
                              MCAN_RXF0A_F0AI,
                              idx);
                status = STW_SOK;
            }
            else
            {
                status = STW_EFAIL;
            }
            break;
        case MCAN_RX_FIFO_NUM_1:
            size = HW_RD_FIELD32(baseAddr + MCAN_RXF1C,
                                 MCAN_RXF1C_F1S);
            if(size >= idx)
            {
                HW_WR_FIELD32(baseAddr + MCAN_RXF1A,
                              MCAN_RXF1A_F1AI,
                              idx);
                status = STW_SOK;
            }
            else
            {
                status = STW_EFAIL;
            }
            break;
        default:
            status = STW_EFAIL;
            break;
    }

    return status;
}

void MCAN_getTxFIFOQueStatus(uint32_t           baseAddr,
                             MCAN_TxFIFOStatus *fifoStatus)
{
    uint32_t regVal;

    regVal = HW_RD_REG32(baseAddr + MCAN_TXFQS);
    fifoStatus->freeLvl  = HW_GET_FIELD(regVal, MCAN_TXFQS_TFFL);
    fifoStatus->getIdx   = HW_GET_FIELD(regVal, MCAN_TXFQS_TFGI);
    fifoStatus->putIdx   = HW_GET_FIELD(regVal, MCAN_TXFQS_TFQPI);
    fifoStatus->fifoFull = HW_GET_FIELD(regVal, MCAN_TXFQS_TFQF);
}

uint32_t MCAN_getTxBufReqPend(uint32_t baseAddr)
{
    return(HW_RD_REG32(baseAddr + MCAN_TXBRP));
}

int32_t MCAN_txBufCancellationReq(uint32_t baseAddr, uint32_t buffNum)
{
    int32_t  status;
    uint32_t regVal;

    if(MCANSS_TX_BUFFER_MAX > buffNum)
    {
        regVal  = HW_RD_REG32(baseAddr + MCAN_TXBCR);
        regVal |= ((uint32_t) 1U << buffNum);

        // For writing to TXBCR CCE bit should be '0'. This need not be
        // reverted because for other qualified writes this is locked state
        // and can't be written.
        MCAN_writeProtectedRegAccessLock(baseAddr);
        HW_WR_REG32(baseAddr + MCAN_TXBCR, regVal);

        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }
    return status;
}

uint32_t MCAN_getTxBufTransmissionStatus(uint32_t baseAddr)
{
    return(HW_RD_REG32(baseAddr + MCAN_TXBTO));
}

uint32_t MCAN_txBufCancellationStatus(uint32_t baseAddr)
{
    return(HW_RD_REG32(baseAddr + MCAN_TXBCF));
}

int32_t MCAN_txBufTransIntrEnable(uint32_t baseAddr,
                                  uint32_t bufNum,
                                  uint32_t enable)
{
    int32_t  status;
    uint32_t regVal;

    if(MCANSS_TX_BUFFER_MAX > bufNum)
    {
        if(TRUE == enable)
        {
            regVal  = HW_RD_REG32(baseAddr + MCAN_TXBTIE);
            regVal |= ((uint32_t) 1U << bufNum);
            HW_WR_REG32(baseAddr + MCAN_TXBTIE, regVal);
        }
        else
        {
            regVal  = HW_RD_REG32(baseAddr + MCAN_TXBTIE);
            regVal &= ~((uint32_t) 0x1U << bufNum);
            HW_WR_REG32(baseAddr + MCAN_TXBTIE, regVal);
        }
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }
    return status;
}

int32_t MCAN_getTxBufCancellationIntrEnable(uint32_t baseAddr,
                                            uint32_t bufNum,
                                            uint32_t enable)
{
    int32_t  status;
    uint32_t regVal;

    if(MCANSS_TX_BUFFER_MAX > bufNum)
    {
        if(TRUE == enable)
        {
            regVal  = HW_RD_REG32(baseAddr + MCAN_TXBCIE);
            regVal |= ((uint32_t) 0x1U << bufNum);
            HW_WR_REG32(baseAddr + MCAN_TXBCIE, regVal);
        }
        else
        {
            regVal  = HW_RD_REG32(baseAddr + MCAN_TXBCIE);
            regVal &= ~((uint32_t) 0x1U << bufNum);
            HW_WR_REG32(baseAddr + MCAN_TXBCIE, regVal);
        }
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }
    return status;
}

void MCAN_getTxEventFIFOStatus(uint32_t                baseAddr,
                               MCAN_TxEventFIFOStatus *fifoStatus)
{
    uint32_t regVal;

    regVal = HW_RD_REG32(baseAddr + MCAN_TXEFS);
    fifoStatus->fillLvl  = HW_GET_FIELD(regVal, MCAN_TXEFS_EFFL);
    fifoStatus->getIdx   = HW_GET_FIELD(regVal, MCAN_TXEFS_EFGI);
    fifoStatus->putIdx   = HW_GET_FIELD(regVal, MCAN_TXEFS_EFPI);
    fifoStatus->fifoFull = HW_GET_FIELD(regVal, MCAN_TXEFS_EFF);
    fifoStatus->eleLost  = HW_GET_FIELD(regVal, MCAN_TXEFS_TEFL);
}

void MCAN_addClockStopRequest(uint32_t baseAddr, uint32_t enable)
{
    if(TRUE == enable)
    {
        HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_CSR, 0x1U);
    }
    else
    {
        HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_CSR, 0x0U);
    }
}

int32_t MCAN_writeTxEventFIFOAck(uint32_t baseAddr, uint32_t idx)
{
    int32_t  status;
    uint32_t size;

    size = HW_RD_FIELD32(baseAddr + MCAN_TXEFC,
                         MCAN_TXEFC_EFS);
    if(size >= idx)
    {
        HW_WR_FIELD32(baseAddr + MCAN_TXEFA,
                      MCAN_TXEFA_EFAI,
                      idx);
        status = STW_SOK;
    }
    else
    {
        status = STW_EFAIL;
    }

    return status;
}

void MCAN_eccForceError(uint32_t                      baseAddr,
                        const MCAN_ECCErrForceParams *eccErr)
{
    uint32_t regVal;

    if((eccErr->errType == (uint32_t)MCAN_ECC_ERR_TYPE_SEC) ||
       (eccErr->errType == (uint32_t)MCAN_ECC_ERR_TYPE_DED))
    {
        MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_ERROR_CTRL1);
        regVal = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_ERROR_CTRL1);
        HW_SET_FIELD32(regVal,
                       MCAN_ECC_AGGR_ERROR_CTRL1_ECC_ROW,
                       eccErr->rowNum);
        HW_WR_REG32(baseAddr + MCAN_ECC_AGGR_ERROR_CTRL1, regVal);
        MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_ERROR_CTRL2);
        regVal = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_ERROR_CTRL2);
        HW_SET_FIELD32(regVal,
                       MCAN_ECC_AGGR_ERROR_CTRL2_ECC_BIT1,
                       eccErr->bit1);
        HW_SET_FIELD32(regVal,
                       MCAN_ECC_AGGR_ERROR_CTRL2_ECC_BIT2,
                       eccErr->bit2);
        HW_WR_REG32(baseAddr + MCAN_ECC_AGGR_ERROR_CTRL2, regVal);
        MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_CONTROL);
        regVal = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_CONTROL);
        HW_SET_FIELD32(regVal,
                       MCAN_ECC_AGGR_CONTROL_FORCE_N_ROW,
                       eccErr->errForce);
        HW_SET_FIELD32(regVal,
                       MCAN_ECC_AGGR_CONTROL_ERROR_ONCE,
                       eccErr->errOnce);
        if(eccErr->errType == (uint32_t)MCAN_ECC_ERR_TYPE_SEC)
        {
            HW_SET_FIELD32(regVal,
                           MCAN_ECC_AGGR_CONTROL_FORCE_SEC,
                           0x1U);
        }
        else if(eccErr->errType == (uint32_t)MCAN_ECC_ERR_TYPE_DED)
        {
            HW_SET_FIELD32(regVal,
                           MCAN_ECC_AGGR_CONTROL_FORCE_DED,
                           0x1U);
        }
        else
        {
            /* MISRA C Compliance */
        }
        HW_WR_REG32(baseAddr + MCAN_ECC_AGGR_CONTROL, regVal);
        MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_CONTROL);
    }
}


void MCAN_eccGetErrorStatus(uint32_t           baseAddr,
                            MCAN_ECCErrStatus *eccErr)
{
    uint32_t regVal;

    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_ERROR_STATUS1);
    regVal = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_ERROR_STATUS1);
    eccErr->secErr = HW_GET_FIELD(regVal,
                                  MCAN_ECC_AGGR_ERROR_STATUS1_ECC_SEC);
    eccErr->dedErr = HW_GET_FIELD(regVal,
                                  MCAN_ECC_AGGR_ERROR_STATUS1_ECC_DED);
    eccErr->bit1 = HW_GET_FIELD(regVal,
                                MCAN_ECC_AGGR_ERROR_STATUS1_ECC_BIT1);
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_ERROR_STATUS2);
    regVal = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_ERROR_STATUS2);
    eccErr->row = HW_GET_FIELD(regVal,
                               MCAN_ECC_AGGR_ERROR_STATUS2_ECC_ROW);
}

void MCAN_eccClearErrorStatus(uint32_t baseAddr, uint32_t errType)
{
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_ERROR_STATUS1);
    switch (errType)
    {
        case MCAN_ECC_ERR_TYPE_SEC:
            HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_ERROR_STATUS1,
                          MCAN_ECC_AGGR_ERROR_STATUS1_CLR_ECC_SEC,
                          0x1U);
            break;
        case MCAN_ECC_ERR_TYPE_DED:
            HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_ERROR_STATUS1,
                          MCAN_ECC_AGGR_ERROR_STATUS1_CLR_ECC_DED,
                          0x1U);
            break;
        default:
            /* Invalid option */
            break;
    }
    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_ERROR_STATUS1);
}

void MCAN_eccWriteEOI(uint32_t baseAddr, uint32_t errType)
{
    switch (errType)
    {
        case MCAN_ECC_ERR_TYPE_SEC:
            HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_SEC_EOI_REG,
                          MCAN_ECC_AGGR_SEC_EOI_REG_WR,
                          0x1U);
            break;
        case MCAN_ECC_ERR_TYPE_DED:
            HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_DED_EOI_REG,
                          MCAN_ECC_AGGR_DED_EOI_REG_WR,
                          0x1U);
            break;
        default:
            /* Invalid option */
            break;
    }
}

void MCAN_eccEnableIntr(uint32_t baseAddr, uint32_t errType, uint32_t enable)
{
    if(TRUE == enable)
    {
        switch (errType)
        {
            case MCAN_ECC_ERR_TYPE_SEC:
                HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_SEC_ENABLE_SET_REG0,
                              MCAN_ECC_AGGR_SEC_ENABLE_SET_REG0_MSGMEM,
                              0x1U);
                break;
            case MCAN_ECC_ERR_TYPE_DED:
                HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_DED_ENABLE_SET_REG0,
                              MCAN_ECC_AGGR_DED_ENABLE_SET_REG0_MSGMEM,
                              0x1U);
                break;
            default:
                /* Invalid option */
                break;
        }
    }
    else
    {
        switch (errType)
        {
            case MCAN_ECC_ERR_TYPE_SEC:
                HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_SEC_ENABLE_CLR_REG0,
                              MCAN_ECC_AGGR_SEC_ENABLE_CLR_REG0_MSGMEM,
                              0x1U);
                break;
            case MCAN_ECC_ERR_TYPE_DED:
                HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_DED_ENABLE_CLR_REG0,
                              MCAN_ECC_AGGR_DED_ENABLE_CLR_REG0_MSGMEM,
                              0x1U);
                break;
            default:
                /* Invalid option */
                break;
        }
    }
}

uint32_t MCAN_eccGetIntrStatus(uint32_t baseAddr, uint32_t errType)
{
    uint32_t retVal = 0U;

    switch (errType)
    {
        case MCAN_ECC_ERR_TYPE_SEC:
            retVal = HW_RD_FIELD32(baseAddr + MCAN_ECC_AGGR_SEC_STATUS_REG0,
                                   MCAN_ECC_AGGR_SEC_STATUS_REG0_MSGMEM_PEND);
            break;
        case MCAN_ECC_ERR_TYPE_DED:
            retVal = HW_RD_FIELD32(baseAddr + MCAN_ECC_AGGR_DED_STATUS_REG0,
                                   MCAN_ECC_AGGR_DED_STATUS_REG0_MSGMEM_PEND);
            break;
        default:
            retVal = 0U;
            break;
    }
    return retVal;
}

void MCAN_eccClearIntrStatus(uint32_t baseAddr, uint32_t errType)
{
    switch (errType)
    {
        case MCAN_ECC_ERR_TYPE_SEC:
            HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_SEC_STATUS_REG0,
                          MCAN_ECC_AGGR_SEC_STATUS_REG0_MSGMEM_PEND,
                          0x1U);
            break;
        case MCAN_ECC_ERR_TYPE_DED:
            HW_WR_FIELD32(baseAddr + MCAN_ECC_AGGR_DED_STATUS_REG0,
                          MCAN_ECC_AGGR_DED_STATUS_REG0_MSGMEM_PEND,
                          0x1U);
            break;
        default:
            break;
    }
}

void MCAN_extTSCounterConfig(uint32_t baseAddr,
                             uint32_t prescalar)
{
    HW_WR_FIELD32(baseAddr + MCAN_MCANSS_EXT_TS_PRESCALER,
                  MCAN_MCANSS_EXT_TS_PRESCALER, prescalar);
}

void MCAN_extTSCounterEnable(uint32_t baseAddr, uint32_t enable)
{
    HW_WR_FIELD32(baseAddr + MCAN_MCANSS_CTRL,
                  MCAN_MCANSS_CTRL_EXT_TS_CNTR_EN,
                  enable);
}

void MCAN_extTSEnableIntr(uint32_t baseAddr, uint32_t enable)
{
    if(TRUE == enable)
    {
        HW_WR_FIELD32(baseAddr + MCAN_MCANSS_IE,
                      MCAN_MCANSS_IE_EXT_TS_CNTR_OVFL,
                      1U);
    }
    else
    {
        HW_WR_FIELD32(baseAddr + MCAN_MCANSS_IECS,
                      MCAN_MCANSS_IECS_EXT_TS_CNTR_OVFL,
                      1U);
    }
}

void MCAN_extTSWriteEOI(uint32_t baseAddr)
{
    HW_WR_FIELD32(baseAddr + MCAN_MCANSS_EOI,
                  MCAN_MCANSS_EOI,
                  0x1U);
}

uint32_t MCAN_extTSGetUnservicedIntrCount(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr +
                          MCAN_MCANSS_EXT_TS_UNSERVICED_INTR_CNTR,
                          MCAN_MCANSS_EXT_TS_UNSERVICED_INTR_CNTR));
}

/* ========================================================================== */
/*                          Advance Functions                                 */
/* ========================================================================== */

void MCAN_getRevisionId(uint32_t baseAddr, MCAN_RevisionId *revId)
{
    uint32_t regVal;

    regVal        = HW_RD_REG32(baseAddr + MCAN_MCANSS_PID);
    revId->minor  = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_MINOR);
    revId->custom = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_CUSTOM);
    revId->major  = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_MAJOR);
    revId->rtlRev = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_RTL);
    revId->modId  = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_MODULE_ID);
    revId->bu     = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_BU);
    revId->scheme = HW_GET_FIELD(regVal, MCAN_MCANSS_PID_SCHEME);

    regVal         = HW_RD_REG32(baseAddr + MCAN_CREL);
    revId->day     = HW_GET_FIELD(regVal, MCAN_CREL_DAY);
    revId->mon     = HW_GET_FIELD(regVal, MCAN_CREL_MON);
    revId->year    = HW_GET_FIELD(regVal, MCAN_CREL_YEAR);
    revId->subStep = HW_GET_FIELD(regVal, MCAN_CREL_SUBSTEP);
    revId->step    = HW_GET_FIELD(regVal, MCAN_CREL_STEP);
    revId->rel     = HW_GET_FIELD(regVal, MCAN_CREL_REL);
}

uint32_t MCAN_getClockStopAck(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_CSR));
}

void MCAN_extTSSetRawStatus(uint32_t baseAddr)
{
    HW_WR_FIELD32(baseAddr + MCAN_MCANSS_IRS,
                  MCAN_MCANSS_IRS_EXT_TS_CNTR_OVFL,
                  1U);
}

void MCAN_extTSClearRawStatus(uint32_t baseAddr)
{
    HW_WR_FIELD32(baseAddr + MCAN_MCANSS_ICS,
                  MCAN_MCANSS_ICS_EXT_TS_CNTR_OVFL,
                  1U);
}

uint32_t MCAN_getRxPinState(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_TEST, MCAN_TEST_RX));
}

void MCAN_setTxPinState(uint32_t baseAddr, uint32_t state)
{
    MCAN_writeProtectedRegAccessUnlock(baseAddr);

    HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_TEST, 0x1U);
    HW_WR_FIELD32(baseAddr + MCAN_TEST,
                  MCAN_TEST_TX,
                  state);

    MCAN_writeProtectedRegAccessLock(baseAddr);
}

uint32_t MCAN_getTxPinState(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_TEST, MCAN_TEST_TX));
}

uint32_t MCAN_getTSCounterVal(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_TSCV, MCAN_TSCV_TSC));
}

uint32_t MCAN_getClkStopAck(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_CSA));
}

void MCAN_getBitTime(uint32_t              baseAddr,
                     MCAN_BitTimingParams *configParams)
{
    configParams->nomSynchJumpWidth = HW_RD_FIELD32(baseAddr + MCAN_NBTP,
                                                    MCAN_NBTP_NSJW);
    configParams->nomTimeSeg2 = HW_RD_FIELD32(baseAddr + MCAN_NBTP,
                                              MCAN_NBTP_NTSEG2);
    configParams->nomTimeSeg1 = HW_RD_FIELD32(baseAddr + MCAN_NBTP,
                                              MCAN_NBTP_NTSEG1);
    configParams->nomRatePrescalar = HW_RD_FIELD32(baseAddr + MCAN_NBTP,
                                                   MCAN_NBTP_NBRP);

    configParams->dataSynchJumpWidth = HW_RD_FIELD32(baseAddr + MCAN_DBTP,
                                                     MCAN_DBTP_DSJW);
    configParams->dataTimeSeg2 = HW_RD_FIELD32(baseAddr + MCAN_DBTP,
                                               MCAN_DBTP_DTSEG2);
    configParams->dataTimeSeg1 = HW_RD_FIELD32(baseAddr + MCAN_DBTP,
                                               MCAN_DBTP_DTSEG1);
    configParams->dataRatePrescalar = HW_RD_FIELD32(baseAddr + MCAN_DBTP,
                                                    MCAN_DBTP_DBRP);
}

void MCAN_resetTSCounter(uint32_t baseAddr)
{
    HW_WR_FIELD32(baseAddr + MCAN_TSCV, MCAN_TSCV_TSC, 0x0U);
}

uint32_t MCAN_getTOCounterVal(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_TOCV, MCAN_TOCV_TOC));
}

void MCAN_eccAggrGetRevisionId(uint32_t baseAddr, MCAN_ECCAggrRevisionId *revId)
{
    uint32_t regVal;

    regVal        = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_REVISION);
    revId->minor  = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_REVMIN);
    revId->custom = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_CUSTOM);
    revId->major  = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_REVMAJ);
    revId->rtlRev = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_REVRTL);
    revId->modId  = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_MODULE_ID);
    revId->bu     = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_BU);
    revId->scheme = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_REVISION_SCHEME);
}

void MCAN_eccWrapGetRevisionId(uint32_t baseAddr, MCAN_ECCWrapRevisionId *revId)
{
    uint32_t regVal;

    MCAN_eccLoadRegister(baseAddr, MCAN_ECC_AGGR_WRAP_REVISION);
    regVal        = HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_WRAP_REVISION);
    revId->minor  = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_REVMIN);
    revId->custom = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_CUSTOM);
    revId->major  = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_REVMAJ);
    revId->rtlRev = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_REVRTL);
    revId->modId  = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_MODULE_ID);
    revId->bu     = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_BU);
    revId->scheme = HW_GET_FIELD(regVal, MCAN_ECC_AGGR_WRAP_REVISION_SCHEME);
}

uint32_t MCAN_extTSIsIntrEnable(uint32_t baseAddr)
{
    uint32_t status;

    if(1U == HW_RD_FIELD32(baseAddr + MCAN_MCANSS_IES,
                            MCAN_MCANSS_IES_EXT_TS_CNTR_OVFL))
    {
        status = (uint32_t) TRUE;
    }
    else
    {
        status = (uint32_t) FALSE;
    }

    return status;
}

uint32_t MCAN_getEndianVal(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_ENDN, MCAN_ENDN_ETV));
}

uint32_t MCAN_getExtIDANDMask(uint32_t baseAddr)
{
    return(HW_RD_FIELD32(baseAddr + MCAN_XIDAM, MCAN_XIDAM_EIDM));
}

/* ========================================================================== */
/*                          Internal Functions                                */
/* ========================================================================== */

static void MCAN_writeProtectedRegAccessUnlock(uint32_t baseAddr)
{
    HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_CCE, 0x1U);
}

static void MCAN_writeProtectedRegAccessLock(uint32_t baseAddr)
{
    HW_WR_FIELD32(baseAddr + MCAN_CCCR, MCAN_CCCR_CCE, 0x0U);
}

static void MCAN_eccLoadRegister(uint32_t baseAddr, uint32_t regOffset)
{
    uint32_t regVal = 0U, offset;

    offset  = regOffset & 0xFFU;
    regVal |= ((uint32_t)MCANSS_MSG_RAM_NUM << MCAN_ECC_AGGR_VECTOR_SHIFT);
    regVal |= (offset << MCAN_ECC_AGGR_VECTOR_RD_SVBUS_ADDRESS_SHIFT);
    regVal |= ((uint32_t)1U << MCAN_ECC_AGGR_VECTOR_RD_SVBUS_SHIFT);
    HW_WR_REG32(baseAddr + MCAN_ECC_AGGR_VECTOR, regVal);
    while(MCAN_ECC_AGGR_VECTOR_RD_SVBUS_DONE_MASK !=
           (HW_RD_REG32(baseAddr + MCAN_ECC_AGGR_VECTOR) &
            MCAN_ECC_AGGR_VECTOR_RD_SVBUS_DONE_MASK))
    {}
}

static void MCAN_readMsg(uint32_t           baseAddr,
                         uint32_t           elemAddr,
                         MCAN_RxBufElement *elem)
{
    uint32_t regVal = 0U, loopCnt = 0U;

    regVal   = HW_RD_REG32(baseAddr + elemAddr);
    elem->id = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_ID_MASK)
                           >> MCANSS_RX_BUFFER_ELEM_ID_SHIFT);
    elem->rtr = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_RTR_MASK)
                            >> MCANSS_RX_BUFFER_ELEM_RTR_SHIFT);
    elem->xtd = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_XTD_MASK)
                            >> MCANSS_RX_BUFFER_ELEM_XTD_SHIFT);
    elem->esi = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_ESI_MASK)
                            >> MCANSS_RX_BUFFER_ELEM_ESI_SHIFT);

    elemAddr  += 4U;
    regVal     = HW_RD_REG32(baseAddr + elemAddr);
    elem->rxts = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_RXTS_MASK)
                             >> MCANSS_RX_BUFFER_ELEM_RXTS_SHIFT);
    elem->dlc = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_DLC_MASK)
                            >> MCANSS_RX_BUFFER_ELEM_DLC_SHIFT);
    elem->brs = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_BRS_MASK)
                            >> MCANSS_RX_BUFFER_ELEM_BRS_SHIFT);
    elem->fdf = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_FDF_MASK)
                            >> MCANSS_RX_BUFFER_ELEM_FDF_SHIFT);
    elem->fidx = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_FIDX_MASK)
                             >> MCANSS_RX_BUFFER_ELEM_FIDX_SHIFT);
    elem->anmf = (uint32_t) ((regVal & MCANSS_RX_BUFFER_ELEM_ANMF_MASK)
                             >> MCANSS_RX_BUFFER_ELEM_ANMF_SHIFT);
    elemAddr += 4U;

    loopCnt = 0U;
    /* Reading words from message RAM and forming payload bytes out of it */
    while((4U <= (MCAN_getDataSize(elem->dlc) - loopCnt)) &&
           (0U != (MCAN_getDataSize(elem->dlc) - loopCnt)))
    {
        ASSERT((loopCnt + 3U) < MCAN_MAX_PAYLOAD_BYTES);
        regVal = HW_RD_REG32(baseAddr + elemAddr);
        elem->data[loopCnt]       = (uint16_t)(regVal & 0x000000FFU);
        elem->data[(loopCnt + 1U)] = (uint16_t)((regVal & 0x0000FF00U) >> 8U);
        elem->data[(loopCnt + 2U)] = (uint16_t)((regVal & 0x00FF0000U) >> 16U);
        elem->data[(loopCnt + 3U)] = (uint16_t)((regVal & 0xFF000000U) >> 24U);
        elemAddr += 4U;
        loopCnt  += 4U;
    }
    /* Reading remaining bytes from message RAM */
    if(0U < (MCAN_getDataSize(elem->dlc) - loopCnt))
    {
        ASSERT((loopCnt + 2U) < MCAN_MAX_PAYLOAD_BYTES);
        regVal = HW_RD_REG32(baseAddr + elemAddr);
        elem->data[loopCnt]       = (uint16_t)(regVal & 0x000000FFU);
        elem->data[(loopCnt + 1U)] = (uint16_t)((regVal & 0x0000FF00U) >> 8U);
        elem->data[(loopCnt + 2U)] = (uint16_t)((regVal & 0x00FF0000U) >> 16U);
    }
}

static void MCAN_writeMsg(uint32_t                 baseAddr,
                          uint32_t                 elemAddr,
                          const MCAN_TxBufElement *elem)
{
    uint32_t regVal = 0, loopCnt = 0U;

    regVal  = 0U;
    regVal |= (((uint32_t) (elem->id << MCANSS_TX_BUFFER_ELEM_ID_SHIFT)) |
               ((uint32_t) (elem->rtr << MCANSS_TX_BUFFER_ELEM_RTR_SHIFT)) |
               ((uint32_t) (elem->xtd << MCANSS_TX_BUFFER_ELEM_XTD_SHIFT)) |
               ((uint32_t) (elem->esi << MCANSS_TX_BUFFER_ELEM_ESI_SHIFT)));
    HW_WR_REG32(baseAddr + elemAddr, regVal);
    elemAddr += 4U;

    regVal  = 0U;
    regVal |= ((uint32_t) (elem->dlc << MCANSS_TX_BUFFER_ELEM_DLC_SHIFT)) |
              ((uint32_t) (elem->brs << MCANSS_TX_BUFFER_ELEM_BRS_SHIFT)) |
              ((uint32_t) (elem->fdf << MCANSS_TX_BUFFER_ELEM_FDF_SHIFT)) |
              ((uint32_t) (elem->efc << MCANSS_TX_BUFFER_ELEM_EFC_SHIFT)) |
              ((uint32_t) (elem->mm << MCANSS_TX_BUFFER_ELEM_MM_SHIFT));
    HW_WR_REG32(baseAddr + elemAddr, regVal);
    elemAddr += 4U;

    loopCnt = 0U;
    /* Framing words out of the payload bytes and writing it to message RAM */
    while((4U <= (MCAN_getDataSize(elem->dlc) - loopCnt)) &&
           (0U != (MCAN_getDataSize(elem->dlc) - loopCnt)))
    {
        ASSERT((loopCnt + 3U) < MCAN_MAX_PAYLOAD_BYTES);
        regVal  = 0U;
        regVal |= ((uint32_t)elem->data[loopCnt] |
                   ((uint32_t)elem->data[(loopCnt + 1U)] << 8U) |
                   ((uint32_t)elem->data[(loopCnt + 2U)] << 16U) |
                   ((uint32_t)elem->data[(loopCnt + 3U)] << 24U));
        HW_WR_REG32(baseAddr + elemAddr, regVal);
        elemAddr += 4U;
        loopCnt  += 4U;
    }
    /* Framing a word out of remaining payload bytes and writing it to
     * message RAM */
    if(0U < (MCAN_getDataSize(elem->dlc) - loopCnt))
    {
        ASSERT((loopCnt + 3U) < MCAN_MAX_PAYLOAD_BYTES);
        regVal  = 0U;
        regVal |= ((uint32_t)elem->data[loopCnt] |
                   ((uint32_t)elem->data[(loopCnt + 1U)] << 8U) |
                   ((uint32_t)elem->data[(loopCnt + 2U)] << 16U) |
                   ((uint32_t)elem->data[(loopCnt + 3U)] << 24U));
        HW_WR_REG32(baseAddr + elemAddr, regVal);
    }
}

static uint32_t MCAN_getDataSize(uint32_t dlc)
{
    uint32_t dataSize[16] = {0,  1,  2,  3,  4,  5,  6, 7, 8,
                             12, 16, 20, 24, 32, 48, 64};
    ASSERT(dlc < 16U);
    return(dataSize[dlc]);
}

uint32_t MCAN_getMsgObjSize(uint32_t elemSize)
{
    uint32_t objSize[8] = {4, 5, 6, 7, 8, 10, 14, 18};
    ASSERT(elemSize < 8U);
    return(objSize[elemSize]);
}

/*
 *   Copyright (c) Texas Instruments Incorporated 2016
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 *  \file     mcan.h
 *
 *  \brief    This file contains the prototypes of the APIs present in the
 *            device abstraction layer file of MCAN.
 *            This also contains some related macros.
 */

#ifndef MCAN_H_
#define MCAN_H_

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */

#include "inc/hw_mcanss.h"
#include "inc/hw_memmap.h"
#include "cpu.h"
#include "sysctl.h"

#ifdef __cplusplus
extern "C" {
#endif

//! \addtogroup mcan_api MCAN
//! @{

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

/**
 * \brief  MCAN MSG RAM BANK number for ECC AGGR.
 */
#define MCANSS_MSG_RAM_NUM                                       (0U)

/**
 * \brief  Maximum Number of Rx Buffers.
 */
#define MCANSS_RX_BUFFER_MAX                                     (64U)

/**
 * \brief  Maximum Number of Tx Buffers.
 */
#define MCANSS_TX_BUFFER_MAX                                     (32U)

/**
 * \brief  Macro for standard Message ID filter.
 */
#define MCANSS_STD_ID_FILTER_SIZE_WORDS                          (1U)

/**
 * \brief  Macro for extended Message ID filter.
 */
#define MCANSS_EXT_ID_FILTER_SIZE_WORDS                          (2U)

/**
 * \brief  Macro for Tx Event FIFO element size.
 */
#define MCANSS_TX_EVENT_FIFO_SIZE_WORDS                          (2U)

/**
 * \brief  Macro for Interrupt Line enable mask.
 */
#define MCANSS_INTR_LINE_EN_MASK   ((MCAN_ILE_EINT0_MASK | MCAN_ILE_EINT1_MASK))


/**
 * \brief  Macro defines mask for all the interrupts status for MCAN.
 */
#define MCAN_INTR_MASK_ALL   (MCAN_IR_RF0N_MASK |                              \
                              MCAN_IR_RF0W_MASK |                              \
                              MCAN_IR_RF0F_MASK |                              \
                              MCAN_IR_RF0L_MASK |                              \
                              MCAN_IR_RF1N_MASK |                              \
                              MCAN_IR_RF1W_MASK |                              \
                              MCAN_IR_RF1F_MASK |                              \
                              MCAN_IR_RF1L_MASK |                              \
                              MCAN_IR_HPM_MASK |                               \
                              MCAN_IR_TC_MASK |                                \
                              MCAN_IR_TCF_MASK |                               \
                              MCAN_IR_TFE_MASK |                               \
                              MCAN_IR_TEFN_MASK |                              \
                              MCAN_IR_TEFW_MASK |                              \
                              MCAN_IR_TEFF_MASK |                              \
                              MCAN_IR_TEFL_MASK |                              \
                              MCAN_IR_TSW_MASK |                               \
                              MCAN_IR_MRAF_MASK |                              \
                              MCAN_IR_TOO_MASK |                               \
                              MCAN_IR_DRX_MASK |                               \
                              MCAN_IR_BEC_MASK |                               \
                              MCAN_IR_BEU_MASK |                               \
                              MCAN_IR_ELO_MASK |                               \
                              MCAN_IR_EP_MASK |                                \
                              MCAN_IR_EW_MASK |                                \
                              MCAN_IR_BO_MASK |                                \
                              MCAN_IR_WDI_MASK |                               \
                              MCAN_IR_PEA_MASK |                               \
                              MCAN_IR_PED_MASK |                               \
                              MCAN_IR_ARA_MASK)

/**
 * \brief  Maximum payload supported by CAN-FD protocol in bytes.
 */
#define MCAN_MAX_PAYLOAD_BYTES                          (64U)

//*****************************************************************************
//
// These macro definitions are used to specify Standard Filter Types to
// set the sft values of the struct MCAN_StdMsgIDFilterElement
// used as a parameter in the function MCAN_addStdMsgIDFilter()
//
//*****************************************************************************

#define MCAN_STDFILT_RANGE                             (0U)
/**< Range Filter from SFID1 to SFID2 */
#define MCAN_STDFILT_DUAL                              (1U)
/**< Dual ID Filter for SFID1 or SFID2 */
#define MCAN_STDFILT_CLASSIC                           (2U)
/**< Classic Filter: SFID1 = filter, SFID2 = mask */
#define MCAN_STDFILT_DISABLED                          (3U)
/**< Filter Element Disabled */

//*****************************************************************************
//
// These macro definitions are used to specify Standard Filter Element
// Configurations to set the sfec values of the struct MCAN_StdMsgIDFilterElement
// used as a parameter in the function MCAN_addStdMsgIDFilter()
//
//*****************************************************************************

#define MCAN_STDFILTEC_DISABLE                          (0U)
/**< Filter Element Disabled */
#define MCAN_STDFILTEC_FIFO0                            (1U)
/**< Store in RX FIFO 0 if filter matches */
#define MCAN_STDFILTEC_FIFO1                            (2U)
/**< Store in RX FIFO 1 if filter matches */
#define MCAN_STDFILTEC_REJECT                           (3U)
/**< Reject ID if filter matches */
#define MCAN_STDFILTEC_PRI                              (4U)
/**< Set priority if filter matches */
#define MCAN_STDFILTEC_PRI_FIFO0                        (5U)
/**< Set priority and store in RX FIFO 0 if filter matches */
#define MCAN_STDFILTEC_PRI_FIFO1                        (6U)
/**< Set priority and store in RX FIFO 1 if filter matches */
#define MCAN_STDFILTEC_RXBUFF                           (7U)
/**< Store in RX Buffer */

/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */

/**
 *  \brief    Enum to select the MCAN interrupt lines
 */
typedef enum
{
    MCAN_INTR_LINE_NUM_0 = 0U,
    /**< MCAN interrupt line 0 */
    MCAN_INTR_LINE_NUM_1 = 1U
                           /**< MCAN interrupt line 1 */
}MCAN_IntrLineNum;

/**
 *  \brief    Enum to represent the MCAN Identifier Type
 */
typedef enum
{
    MCAN_ID_TYPE_11_BIT = 0U,
    /**< 11bit MCAN Identifier */
    MCAN_ID_TYPE_29_BIT = 1U
                          /**< 29bit MCAN Identifier */
}MCAN_IdType;

/**
 *  \brief    Enum to represent the MCAN mode of operation
 */
typedef enum
{
    MCAN_OPERATION_MODE_NORMAL = 0U,
    /**< MCAN normal mode */
    MCAN_OPERATION_MODE_SW_INIT = 1U
                                  /**< MCAN SW initialization mode */
}MCAN_OperationMode;

/**
 *  \brief    Enum to represent the MCAN Message RAM type.
 */
typedef enum
{
    MCAN_MEM_TYPE_BUF = 0U,
    /**< MCAN Msg RAM buffers */
    MCAN_MEM_TYPE_FIFO = 1U
                         /**< MCAN Msg RAM FIFO/Queue */
}MCAN_MemType;

/**
 *  \brief    Enum to represent the MCAN Rx FIFO number
 */
typedef enum
{
    MCAN_RX_FIFO_NUM_0 = 0U,
    /**< MCAN Rx FIFO 0 */
    MCAN_RX_FIFO_NUM_1 = 1U
                         /**< MCAN Rx FIFO 1 */
}MCAN_RxFIFONum;

/**
 *  \brief    Enum to represent the MCAN pin type
 */
typedef enum
{
    MCAN_PIN_TYPE_RX = 0U,
    /**< MCAN Rx Pin */
    MCAN_PIN_TYPE_TX = 1U
                       /**< MCAN Tx Pin */
}MCAN_PinType;

/**
 *  \brief    Enum to represent FIFO/Buffer element Size
 */
typedef enum
{
    MCAN_ELEM_SIZE_8BYTES = 0U,
    /**< 8 byte data field */
    MCAN_ELEM_SIZE_12BYTES = 1U,
    /**< 12 byte data field */
    MCAN_ELEM_SIZE_16BYTES = 2U,
    /**< 16 byte data field */
    MCAN_ELEM_SIZE_20BYTES = 3U,
    /**< 20 byte data field */
    MCAN_ELEM_SIZE_24BYTES = 4U,
    /**< 24 byte data field */
    MCAN_ELEM_SIZE_32BYTES = 5U,
    /**< 32 byte data field */
    MCAN_ELEM_SIZE_48BYTES = 6U,
    /**< 48 byte data field */
    MCAN_ELEM_SIZE_64BYTES = 7U
                             /**< 64 byte data field */
}MCAN_ElemSize;

/**
 *  \brief    Enum to represent the MCAN time-out counter configuration
 */
typedef enum
{
    MCAN_TIMEOUT_SELECT_CONT = 0U,
    /**< Continuous operation Mode */
    MCAN_TIMEOUT_SELECT_TX_EVENT_FIFO = 1U,
    /**< Timeout controlled by Tx Event FIFO */
    MCAN_TIMEOUT_SELECT_RX_FIFO0 = 2U,
    /**< Timeout controlled by Rx FIFO 0 */
    MCAN_TIMEOUT_SELECT_RX_FIFO1 = 3U
                                   /**< Timeout controlled by Rx FIFO 1 */
}MCAN_TimeOutSelect;

/**
 * \brief  Enum for MCAN interrupts.
 */
typedef enum
{
    MCAN_INTR_SRC_RX_FIFO0_NEW_MSG = MCAN_IR_RF0N_MASK,
    /**< Rx FIFO 0 New Message interrupt */
    MCAN_INTR_SRC_RX_FIFO0_WATERMARK = MCAN_IR_RF0W_MASK,
    /**< Rx FIFO 0 Watermark Reached interrupt */
    MCAN_INTR_SRC_RX_FIFO0_FULL = MCAN_IR_RF0F_MASK,
    /**< Rx FIFO 0 Full interrupt */
    MCAN_INTR_SRC_RX_FIFO0_MSG_LOST = MCAN_IR_RF0L_MASK,
    /**< Rx FIFO 0 Message Lost interrupt */
    MCAN_INTR_SRC_RX_FIFO1_NEW_MSG = MCAN_IR_RF1N_MASK,
    /**< Rx FIFO 1 New Message interrupt */
    MCAN_INTR_SRC_RX_FIFO1_WATERMARK = MCAN_IR_RF1W_MASK,
    /**< Rx FIFO 1 Watermark Reached interrupt */
    MCAN_INTR_SRC_RX_FIFO1_FULL = MCAN_IR_RF1F_MASK,
    /**< Rx FIFO 1 Full interrupt */
    MCAN_INTR_SRC_RX_FIFO1_MSG_LOST = MCAN_IR_RF1L_MASK,
    /**< Rx FIFO 1 Message Lost interrupt */
    MCAN_INTR_SRC_HIGH_PRIO_MSG = MCAN_IR_HPM_MASK,
    /**< High Priority Message interrupt */
    MCAN_INTR_SRC_TRANS_COMPLETE = MCAN_IR_TC_MASK,
    /**< Transmission Completed interrupt */
    MCAN_INTR_SRC_TRANS_CANCEL_FINISH = MCAN_IR_TCF_MASK,
    /**< Transmission Cancellation Finished interrupt */
    MCAN_INTR_SRC_TX_FIFO_EMPTY = MCAN_IR_TFE_MASK,
    /**< Tx FIFO Empty interrupt */
    MCAN_INTR_SRC_TX_EVT_FIFO_NEW_ENTRY = MCAN_IR_TEFN_MASK,
    /**< Tx Event FIFO New Entry interrupt */
    MCAN_INTR_SRC_TX_EVT_FIFO_WATERMARK = MCAN_IR_TEFW_MASK,
    /**< Tx Event FIFO Watermark Reached interrupt */
    MCAN_INTR_SRC_TX_EVT_FIFO_FULL = MCAN_IR_TEFF_MASK,
    /**< Tx Event FIFO Full interrupt */
    MCAN_INTR_SRC_TX_EVT_FIFO_ELEM_LOST = MCAN_IR_TEFL_MASK,
    /**< Tx Event FIFO Element Lost interrupt */
    MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND = MCAN_IR_TSW_MASK,
    /**< Timestamp Wraparound interrupt */
    MCAN_INTR_SRC_MSG_RAM_ACCESS_FAILURE = MCAN_IR_MRAF_MASK,
    /**< Message RAM Access Failure interrupt */
    MCAN_INTR_SRC_TIMEOUT = MCAN_IR_TOO_MASK,
    /**< Timeout Occurred interrupt */
    MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG = MCAN_IR_DRX_MASK,
    /**< Message stored to Dedicated Rx Buffer interrupt */
    MCAN_INTR_SRC_BIT_ERR_CORRECTED = MCAN_IR_BEC_MASK,
    /**< Bit Error Corrected interrupt */
    MCAN_INTR_SRC_BIT_ERR_UNCORRECTED = MCAN_IR_BEU_MASK,
    /**< Bit Error Uncorrected interrupt */
    MCAN_INTR_SRC_ERR_LOG_OVRFLW = MCAN_IR_ELO_MASK,
    /**< Error Logging Overflow interrupt */
    MCAN_INTR_SRC_ERR_PASSIVE = MCAN_IR_EP_MASK,
    /**< Error Passive interrupt */
    MCAN_INTR_SRC_WARNING_STATUS = MCAN_IR_EW_MASK,
    /**< Warning Status interrupt */
    MCAN_INTR_SRC_BUS_OFF_STATUS = MCAN_IR_BO_MASK,
    /**< Bus_Off Status interrupt */
    MCAN_INTR_SRC_WATCHDOG = MCAN_IR_WDI_MASK,
    /**< Watchdog Interrupt interrupt */
    MCAN_INTR_SRC_PROTOCOL_ERR_ARB = MCAN_IR_PEA_MASK,
    /**< Protocol Error in Arbitration Phase interrupt */
    MCAN_INTR_SRC_PROTOCOL_ERR_DATA = MCAN_IR_PED_MASK,
    /**< Protocol Error in Data Phase interrupt */
    MCAN_INTR_SRC_RES_ADDR_ACCESS = MCAN_IR_ARA_MASK
                                    /**< Access to Reserved Address interrupt */
}MCAN_IntrSrc;

/**
 *  \brief    Enum to represent the ECC Error Types
 */
typedef enum
{
    MCAN_ECC_ERR_TYPE_SEC = 0U,
    /**< ECC Single Error Correction */
    MCAN_ECC_ERR_TYPE_DED = 1U
                            /**< ECC Single Error Detection */
}MCAN_ECCErrType;

/**
 *  \brief    Enum to select the MCAN Loopback mode
 */
typedef enum
{
    MCAN_LPBK_MODE_INTERNAL = 0U,
    /**< Internal Loop Back Mode
     *   This mode can be used for hot self-test and this mode will not
     *   affect bus state.
     */
    MCAN_LPBK_MODE_EXTERNAL = 1U
                              /**< External Loop Back Mode
                               *   In this mode, MCAN the M_CAN treats its own
                               **transmitted messages as
                               *   received messages and stores them (if they
                               **pass acceptance filtering)
                               *   into an Rx Buffer or an Rx FIFO.
                               *   This mode will affect bus state
                               */
}MCAN_LpbkMode;

/**
 *  \brief    Enum to represent MCAN's communication state
 */
typedef enum
{
    MCAN_COM_STATE_SYNCHRONIZING = 0U,
    /**< MCAN is synchronizing on CAN communication */
    MCAN_COM_STATE_IDLE = 1U,
    /**< MCAN is neither receiver nor transmitter */
    MCAN_COM_STATE_RECEIVER = 2U,
    /**< MCAN is operating as receiver */
    MCAN_COM_STATE_TRANSMITTER = 3U
                                 /**< MCAN is operating as transmitter */
}MCAN_ComState;

/**
 *  \brief    Enum to represent MCAN's Error Code
 */
typedef enum
{
    MCAN_ERR_CODE_NO_ERROR = 0U,
    /**< No error occurred since LEC has been reset by
     *   successful reception or transmission.
     */
    MCAN_ERR_CODE_STUFF_ERROR = 1U,
    /**< More than 5 equal bits in a sequence have occurred in a part of
     *   a received message where this is not allowed.
     */
    MCAN_ERR_CODE_FORM_ERROR = 2U,
    /**< A fixed format part of a received frame has the wrong format. */
    MCAN_ERR_CODE_ACK_ERROR = 3U,
    /**< The message transmitted by the M_CAN was not acknowledged
     *   by another node.
     */
    MCAN_ERR_CODE_BIT1_ERROR = 4U,
    /**< During the transmission of a message (with the exception of
     *   the arbitration field), the device wanted to send a
     *   recessive level (bit of logical value 鈥�1鈥�),
     *  but the monitored bus value was dominant.
     */
    MCAN_ERR_CODE_BIT0_ERROR = 5U,
    /**< During the transmission of a message (or acknowledge bit,
     *   or active error flag, or overload flag), the device wanted to send
     *   a dominant level (data or identifier bit logical value 鈥�0鈥�),
     *   but the monitored bus value was recessive. During Bus_Off recovery
     *   this status is set each time a sequence of 11 recessive bits has been
     *   monitored. This enables the CPU to monitor the proceeding of
     *   the Bus_Off recovery sequence (indicating the bus is not stuck at
     *   dominant or continuously disturbed).
     */
    MCAN_ERR_CODE_CRC_ERROR = 6U,
    /**< The CRC check sum of a received message was incorrect.
     *   The CRC of an incoming message does not match with the
     *   CRC calculated from the received data.
     */
    MCAN_ERR_CODE_NO_CHANGE = 7U
                              /**< Any read access to the Protocol Status
                               * Register re-initializes
                               *   the LEC to 鈥�7鈥�. When the LEC shows the value
                               ****鈥�7鈥�,
                               *   no CAN bus event was detected since the last
                               ****CPU read access to
                               *   the Protocol Status Register.
                               */
}MCAN_ErrCode;

/**
 *  \brief    Enum to determine the clock source that will be set 
 *            up via a call to the MCAN_selectClockSource() API
 */
typedef enum
{
    //! Peripheral System Clock Source
    MCAN_CLOCK_SOURCE_SYS       = 0x0,


    //! Auxiliary Clock Input Source
    MCAN_CLOCK_SOURCE_AUXIN     = 0x2,  

    //! PLL Raw Clock Source
    MCAN_CLOCK_SOURCE_PLLRAW    = 0x3

} MCAN_ClockSource;

/**
 * \brief  Structure for bit timing calculation.
 *         Bit timing related to data phase will be valid only in case where
 *         MCAN is put in CAN-FD mode and will be '0' otherwise.
 */
typedef struct
{
    uint32_t nomRatePrescalar;
    /**< Nominal Baud Rate Pre-scaler
     *   Range:[0x0-0x1FF]
     */
    uint32_t nomTimeSeg1;
    /**< Nominal Time segment before sample point
     *   Range:[0x0-0xFF]
     */
    uint32_t nomTimeSeg2;
    /**< Nominal Time segment after sample point
     *   Range:[0x0-0x7F]
     */
    uint32_t nomSynchJumpWidth;
    /**< Nominal (Re)Synchronization Jump Width
     *   Range:[0x0-0x7F]
     */
    uint32_t dataRatePrescalar;
    /**< Data Baud Rate Pre-scaler
     *   Range:[0x0-0x1F]
     */
    uint32_t dataTimeSeg1;
    /**< Data Time segment before sample point
     *   Range:[0x0-0x1F]
     */
    uint32_t dataTimeSeg2;
    /**< Data Time segment after sample point
     *   Range:[0x0-0xF]
     */
    uint32_t dataSynchJumpWidth;
    /**< Data (Re)Synchronization Jump Width
     *   Range:[0x0-0xF]
     */
}MCAN_BitTimingParams;

/**
 * \brief  Structure for MCAN Transmitter Delay Compensation parameters.
 */
typedef struct
{
    uint32_t tdcf;
    /**< Transmitter Delay Compensation Filter Window Length
     *   Range:[0x0-0x7F]
     */
    uint32_t tdco;
    /**< Transmitter Delay Compensation Offset
     *   Range:[0x0-0x7F]
     */
}MCAN_TDCConfig;

/**
 * \brief  Structure for MCAN Global Filter Configuration parameters.
 */
typedef struct
{
    uint32_t rrfe;
    /**< Reject Remote Frames Extended
     *   0 = Filter remote frames with 29-bit extended IDs
     *   1 = Reject all remote frames with 29-bit extended IDs
     */
    uint32_t rrfs;
    /**< Reject Remote Frames Standard
     *   0 = Filter remote frames with 11-bit standard IDs
     *   1 = Reject all remote frames with 11-bit standard IDs
     */
    uint32_t anfe;
    /**< Accept Non-matching Frames Extended
     *   0 = Accept in Rx FIFO 0
     *   1 = Accept in Rx FIFO 1
     *   others = Reject
     */
    uint32_t anfs;
    /**< Accept Non-matching Frames Standard
     *   0 = Accept in Rx FIFO 0
     *   1 = Accept in Rx FIFO 1
     *   others = Reject
     */
}MCAN_GlobalFiltConfig;

/**
 * \brief  Structure for MCAN initialization parameters.
 */
typedef struct
{
    uint32_t       fdMode;
    /**< FD Operation Enable
     *   0 = FD operation disabled
     *   1 = FD operation enabled
     */
    uint32_t       brsEnable;
    /**< Bit Rate Switch Enable
     *   This is valid only when opMode = 1.
     *   0 = Bit rate switching for transmissions disabled
     *   1 = Bit rate switching for transmissions enabled
     */
    uint32_t       txpEnable;
    /**< Transmit Pause
     *   0 = Transmit pause disabled
     *   1 = Transmit pause enabled
     */
    uint32_t       efbi;
    /**< FEdge Filtering during Bus Integration
     *   0 = Edge filtering disabled
     *   1 = Two consecutive dominant tq required to detect an edge for
     *       hard synchronization
     */
    uint32_t       pxhddisable;
    /**< Protocol Exception Handling Disable
     *   0 = Protocol exception handling enabled
     *   1 = Protocol exception handling disabled
     */
    uint32_t       darEnable;
    /**< Disable Automatic Retransmission
     *   0 = Automatic retransmission of messages not transmitted successfully
     *       enabled
     *   1 = Automatic retransmission disabled
     */
    uint32_t       wkupReqEnable;
    /**< Wakeup Request Enable
     *   0 = Wakeup request is disabled
     *   1 = Wakeup request is enabled
     */
    uint32_t       autoWkupEnable;
    /**< Auto-Wakeup Enable
     *   0 = Auto-Wakeup is disabled
     *   1 = Auto-Wakeup is enabled
     */
    uint32_t       emulationEnable;
    /**< Emulation/Debug Suspend Enable
     *   0 = Emulation/Debug Suspend is disabled
     *   1 = Emulation/Debug Suspend is enabled
     */
    uint32_t       wdcPreload;
    /**< Start value of the Message RAM Watchdog Counter
     *   Range:[0x0-0xFF]
     */
    MCAN_TDCConfig tdcConfig;
    /**< Transmitter Delay Compensation parameters.
     *   Refer struct #MCAN_TDCConfig.
     */
    uint32_t       tdcEnable;
    /**< Transmitter Delay Compensation Enable
     *   0 = Transmitter Delay Compensation is disabled
     *   1 = Transmitter Delay Compensation is enabled
     */
}MCAN_InitParams;

/**
 * \brief  Structure for MCAN configuration parameters.
 */
typedef struct
{
    uint32_t              monEnable;
    /**< Bus Monitoring Mode
     *   0 = Bus Monitoring Mode is disabled
     *   1 = Bus Monitoring Mode is enabled
     */
    uint32_t              asmEnable;
    /**< Restricted Operation Mode
     *   0 = Normal CAN operation
     *   1 = Restricted Operation Mode active
     *   This mode should not be combined with test modes.
     */
    uint32_t              tsPrescalar;
    /**< Timestamp Counter Prescaler.
     *   Range:[0x0-0xF]
     */
    uint32_t              tsSelect;
    /**< Timestamp source selection.
     *   00= Timestamp counter value always 0x0000
     *   01= Timestamp counter value incremented according to tsPrescalar
     *   10= External timestamp counter value used
     *   11= Same as 鈥�00鈥�
     */
    uint32_t              timeoutSelect;
    /**< Time-out counter source select.
     *   Refer enum #MCAN_TimeOutSelect.
     */
    uint32_t              timeoutPreload;
    /**< Start value of the Timeout Counter (down-counter).
     *   The Timeout Counter is decremented in multiples of CAN bit times [1-16]
     *   depending on the configuration of the tsPrescalar.
     *   Range:[0x0-0xFFFF]
     */
    uint32_t              timeoutCntEnable;
    /**< Time-out Counter Enable
     *   0 = Time-out Counter is disabled
     *   1 = Time-out Counter is enabled
     */
    MCAN_GlobalFiltConfig filterConfig;
    /**< Global Filter Configuration parameters.
     *    Refer struct #MCAN_GlobalFiltConfig.
     */
}MCAN_ConfigParams;

/**
 * \brief  Structure for MCAN error logging counters status.
 */
typedef struct
{
    uint32_t transErrLogCnt;
    /**< Transmit Error Counter */
    uint32_t recErrCnt;
    /**< Receive Error Counter */
    uint32_t rpStatus;
    /**< Receive Error Passive
     *   0 = The Receive Error Counter is below the error passive level(128)
     *   1 = The Receive Error Counter has reached the error passive level(128)
     */
    uint32_t canErrLogCnt;
    /**< CAN Error Logging */
}MCAN_ErrCntStatus;

/**
 * \brief  Structure for MCAN protocol status.
 */
typedef struct
{
    uint32_t lastErrCode;
    /**< Last Error Code
     *   Refer enum #MCAN_ErrCode
     */
    uint32_t act;
    /**< Activity - Monitors the module鈥檚 CAN communication state.
     *   refer enum #MCAN_ComState
     */
    uint32_t errPassive;
    /**< Error Passive
     *   0 = The M_CAN is in the Error_Active state
     *   1 = The M_CAN is in the Error_Passive state
     */
    uint32_t warningStatus;
    /**< Warning Status
     *   0 = Both error counters are below the Error_Warning limit of 96
     *   1 = At least one of error counter has reached the Error_Warning
     *       limit of 96
     */
    uint32_t busOffStatus;
    /**< Bus_Off Status
     *   0 = The M_CAN is not Bus_Off
     *   1 = The M_CAN is in Bus_Off state
     */
    uint32_t dlec;
    /**< Data Phase Last Error Code
     *   Refer enum #MCAN_ErrCode
     */
    uint32_t resi;
    /**< ESI flag of last received CAN FD Message
     *   0 = Last received CAN FD message did not have its ESI flag set
     *   1 = Last received CAN FD message had its ESI flag set
     */
    uint32_t rbrs;
    /**< BRS flag of last received CAN FD Message
     *   0 = Last received CAN FD message did not have its BRS flag set
     *   1 = TLast received CAN FD message had its BRS flag set
     */
    uint32_t rfdf;
    /**< Received a CAN FD Message
     *   0 = Since this bit was reset by the CPU, no CAN FD message has been
     *       received
     *   1 = Message in CAN FD format with FDF flag set has been received
     */
    uint32_t pxe;
    /**< Protocol Exception Event
     *   0 = No protocol exception event occurred since last read access
     *   1 = Protocol exception event occurred
     */
    uint32_t tdcv;
    /**< Transmitter Delay Compensation Value */
}MCAN_ProtocolStatus;

/**
 * \brief  Structure for MCAN Message RAM Configuration Parameters.
 *         Message RAM can contain following sections:
 *         Standard ID filters, Extended ID filters, TX FIFO(or TX Q),
 *         TX Buffers, TX EventFIFO, RX FIFO0, RX FIFO1, RX Buffer.
 *         Note: If particular section in the RAM is not used then it's size
 *         should be initialized to '0'
 *         (Number of buffers in case of Tx/Rx buffer).
 */
typedef struct
{
    uint32_t flssa;
    /**< Standard ID Filter List Start Address */
    uint32_t lss;
    /**< List Size: Standard ID
     *   0 = No standard Message ID filter
     *   1-127 = Number of standard Message ID filter elements
     *   others = Values greater than 128 are interpreted as 128
     */
    uint32_t flesa;
    /**< Extended ID Filter List Start Address */
    uint32_t lse;
    /**< List Size: Extended ID
     *   0 = No standard Message ID filter
     *   1-64 = Number of standard Message ID filter elements
     *   others = Values greater than 64 are interpreted as 64
     */
    uint32_t txStartAddr;
    /**< Tx Buffers Start Address */
    uint32_t txBufNum;
    /**< Number of Dedicated Transmit Buffers
     *   0 = No Dedicated Tx Buffers
     *   1-32 = Number of Dedicated Tx Buffers
     *   others = Values greater than 32 are interpreted as 32
     */
    uint32_t txFIFOSize;
    /**< Transmit FIFO/Queue Size
     *   0 = No Tx FIFO/Queue
     *   1-32 = Number of Tx Buffers used for Tx FIFO/Queue
     *   others = Values greater than 32 are interpreted as 32
     */
    uint32_t txBufMode;
    /**< Tx FIFO/Queue Mode
     *   0 = Tx FIFO operation
     *   1 = Tx Queue operation
     */
    uint32_t txBufElemSize;
    /**< Tx Buffer Element Size */
    uint32_t txEventFIFOStartAddr;
    /**< Tx Event FIFO Start Address */
    uint32_t txEventFIFOSize;
    /**< Event FIFO Size
     *   0 = Tx Event FIFO disabled
     *   1-32 = Number of Tx Event FIFO elements
     *   others = Values greater than 32 are interpreted as 32
     */
    uint32_t txEventFIFOWaterMark;
    /**< Tx Event FIFO Watermark
     *   0 = Watermark interrupt disabled
     *   1-32 = Level for Tx Event FIFO watermark interrupt
     *   others = Watermark interrupt disabled
     */
    uint32_t rxFIFO0startAddr;
    /**< Rx FIFO0 Start Address */
    uint32_t rxFIFO0size;
    /**< Rx FIFO0 Size
     *   0 = No Rx FIFO
     *   1-64 = Number of Rx FIFO elements
     *   others = Values greater than 64 are interpreted as 64
     */
    uint32_t rxFIFO0waterMark;
    /**< Rx FIFO0 Watermark
     *   0 = Watermark interrupt disabled
     *   1-63 = Level for Rx FIFO 0 watermark interrupt
     *   others = Watermark interrupt disabled
     */
    uint32_t rxFIFO0OpMode;
    /**< Rx FIFO0 Operation Mode
     *   0 = FIFO blocking mode
     *   1 = FIFO overwrite mode
     */
    uint32_t rxFIFO1startAddr;
    /**< Rx FIFO1 Start Address */
    uint32_t rxFIFO1size;
    /**< Rx FIFO1 Size
     *   0 = No Rx FIFO
     *   1-64 = Number of Rx FIFO elements
     *   others = Values greater than 64 are interpreted as 64
     */
    uint32_t rxFIFO1waterMark;
    /**< Rx FIFO1 Watermark
     *   0 = Watermark interrupt disabled
     *   1-63 = Level for Rx FIFO 1 watermark interrupt
     *   others = Watermark interrupt disabled
     */
    uint32_t rxFIFO1OpMode;
    /**< Rx FIFO1 Operation Mode
     *   0 = FIFO blocking mode
     *   1 = FIFO overwrite mode
     */
    uint32_t rxBufStartAddr;
    /**< Rx Buffer Start Address */
    uint32_t rxBufElemSize;
    /**< Rx Buffer Element Size */
    uint32_t rxFIFO0ElemSize;
    /**< Rx FIFO0 Element Size */
    uint32_t rxFIFO1ElemSize;
    /**< Rx FIFO1 Element Size */
}MCAN_MsgRAMConfigParams;

/**
 * \brief  Structure for MCAN High Priority Message.
 */
typedef struct
{
    uint32_t bufIdx;
    /**< Buffer Index
     *   Only valid when MSI[1] = 鈥�1鈥�.
     */
    uint32_t msi;
    /**< Message Storage Indicator
     *   MSI[1:0]
     *       00  = No FIFO selected
     *       01  = FIFO message lost
     *       10  = Message stored in FIFO 0
     *       11  = Message stored in FIFO 1
     */
    uint32_t filterIdx;
    /**< Filter Index */
    uint32_t filterList;
    /**< Indicates the filter list of the matching filter element
     *   0 = Standard Filter List
     *   1 = Extended Filter List
     */
}MCAN_HighPriorityMsgInfo;

/**
 * \brief  Structure for MCAN new data flag for Rx buffer.
 */
typedef struct
{
    uint32_t statusLow;
    /**< New data flag for Rx buffer no. 0 to 31 */
    uint32_t statusHigh;
    /**< New data flag for Rx buffer no. 32 to 63 */
}MCAN_RxNewDataStatus;

/**
 * \brief  Structure for MCAN Rx FIFO Status.
 */
typedef struct
{
    uint32_t num;
    /**< Rx FIFO number
     *   Refer enum #MCAN_RxFIFONum
     */
    uint32_t fillLvl;
    /**< Rx FIFO Fill Level */
    uint32_t getIdx;
    /**< Rx FIFO Get Index */
    uint32_t putIdx;
    /**< Rx FIFO Put Index */
    uint32_t fifoFull;
    /**< Rx FIFO Full
     *   0 = Rx FIFO not full
     *   1 = Rx FIFO full
     */
    uint32_t msgLost;
    /**< Rx FIFO Message Lost */
}MCAN_RxFIFOStatus;

/**
 * \brief  Structure for MCAN Tx FIFO Status.
 */
typedef struct
{
    uint32_t freeLvl;
    /**< Tx FIFO Free Level */
    uint32_t getIdx;
    /**< Tx FIFO Get Index
     *   Read as zero when Tx Queue operation is configured.
     */
    uint32_t putIdx;
    /**< Tx FIFO/Queue Put Index */
    uint32_t fifoFull;
    /**< Tx FIFO/Queue Full
     *   0 = Tx FIFO/Queue not full
     *   1 = Tx FIFO/Queue full
     */
}MCAN_TxFIFOStatus;

/**
 * \brief  Structure for MCAN Tx Event FIFO Status.
 */
typedef struct
{
    uint32_t fillLvl;
    /**< Event FIFO Fill Level */
    uint32_t getIdx;
    /**< Event FIFO Gut Index */
    uint32_t putIdx;
    /**< Event FIFO Put Index */
    uint32_t fifoFull;
    /**< Event FIFO Full
     *   0 = Tx Event FIFO not full
     *   1 = Tx Event FIFO full
     */
    uint32_t eleLost;
    /**< Tx Event FIFO Element Lost
     *   0 = No Tx Event FIFO element lost
     *   1 = Tx Event FIFO element lost, also set after write attempt to
     *       Tx Event FIFO of size zero.
     */
}MCAN_TxEventFIFOStatus;

/**
 * \brief  Structure for ECC Error forcing.
 */
typedef struct
{
    uint32_t errType;
    /**< Error type to be forced
     *   Refer enum  #MCAN_ECCErrType.
     */
    uint32_t rowNum;
    /**< Row address where error needs to be applied. */
    uint32_t bit1;
    /**< Column/Data bit that needs to be flipped when
     *   force_sec or force_ded is set
     */
    uint32_t bit2;
    /**< Data bit that needs to be flipped when force_ded is set */
    uint32_t errOnce;
    /**< Force Error once
     *   1: The error will inject an error to the specified row only once
     */
    uint32_t errForce;
    /**< Force error on the next RAM read */
}MCAN_ECCErrForceParams;

/**
 * \brief  Structure for ECC Error Status.
 */
typedef struct
{
    uint32_t secErr;
    /**< Single Bit Error Status
     *   0 = No Single Bit Error pending
     *   1 = Single Bit Error pending
     */
    uint32_t dedErr;
    /**< Double Bit Error Status
     *   0 = No Double Bit Error pending
     *   1 = Double Bit Error pending
     */
    uint32_t row;
    /**< Indicates the row/address where the single or double bit
     *   error occurred.
     */
    uint32_t bit1;
    /**< Indicates the bit position in the ram data that is in error
     */
}MCAN_ECCErrStatus;

/**
 * \brief  Structure for accessing Revision ID and Core Release Info.
 *         of MCAN module.
 */
typedef struct
{
    uint32_t scheme;
    /**< Scheme */
    uint32_t bu;
    /**< Business Unit: 10 = Processors */
    uint32_t modId;
    /**< Module ID */
    uint32_t rtlRev;
    /**< RTL revision */
    uint32_t major;
    /**< Major revision */
    uint32_t custom;
    /**< Custom revision */
    uint32_t minor;
    /**< Minor revision */
    uint32_t day;
    /**< Time Stamp Day. Two digits, BCD-coded. */
    uint32_t mon;
    /**< Time Stamp Month. Two digits, BCD-coded. */
    uint32_t year;
    /**< Time Stamp Year. Single digit, BCD-coded. */
    uint32_t subStep;
    /**< Sub-step of Core Release Single digit, BCD-coded. */
    uint32_t step;
    /**< Step of Core Release.Two digits, BCD-coded Single digit, BCD-coded. */
    uint32_t rel;
    /**< Core Release. Single digit, BCD-coded. */
}MCAN_RevisionId;

/**
 * \brief  Structure for accessing Revision ID of ECC AGGR.
 */
typedef struct
{
    uint32_t scheme;
    /**< Scheme */
    uint32_t bu;
    /**< Business Unit: 10 = Processors */
    uint32_t modId;
    /**< Module ID */
    uint32_t rtlRev;
    /**< RTL revision */
    uint32_t major;
    /**< Major revision */
    uint32_t custom;
    /**< Custom revision */
    uint32_t minor;
    /**< Minor revision */
}MCAN_ECCAggrRevisionId;

/**
 * \brief  Structure for MCAN ECC configuration parameters.
 */
typedef struct
{
    uint32_t enable;
    /**< Enable/disable ECC
     *   0 = Disable ECC
     *   1 = Enable ECC
     */
    uint32_t enableChk;
    /**< Enable/disable ECC Check
     *   0 = Disable ECC Check
     *   1 = Enable ECC Check
     */
    uint32_t enableRdModWr;
    /**< Enable/disable Read Modify Write operation
     *   0 = Disable Read Modify Write operation
     *   1 = Enable Read Modify Write operation
     */
}MCAN_ECCConfigParams;

/**
 * \brief  Structure for accessing Revision ID of ECC wrapper.
 */
typedef struct
{
    uint32_t scheme;
    /**< Scheme */
    uint32_t bu;
    /**< Business Unit: 10 = Processors */
    uint32_t modId;
    /**< Module ID */
    uint32_t rtlRev;
    /**< RTL revision */
    uint32_t major;
    /**< Major revision */
    uint32_t custom;
    /**< Custom revision */
    uint32_t minor;
    /**< Minor revision */
}MCAN_ECCWrapRevisionId;

/**
 * \brief  Structure for MCAN Tx Buffer element.
 */
typedef struct
{
    uint32_t id;
    /**< Identifier */
    uint32_t rtr;
    /**< Remote Transmission Request
     *   0 = Transmit data frame
     *   1 = Transmit remote frame
     */
    uint32_t xtd;
    /**< Extended Identifier
     *   0 = 11-bit standard identifier
     *   1 = 29-bit extended identifier
     */
    uint32_t esi;
    /**< Error State Indicator
     *   0 = ESI bit in CAN FD format depends only on error passive flag
     *   1 = ESI bit in CAN FD format transmitted recessive
     */
    uint32_t dlc;
    /**< Data Length Code
     *   0-8  = CAN + CAN FD: transmit frame has 0-8 data bytes
     *   9-15 = CAN: transmit frame has 8 data bytes
     *   9-15 = CAN FD: transmit frame has 12/16/20/24/32/48/64 data bytes
     */
    uint32_t brs;
    /**< Bit Rat Switching
     *   0 = CAN FD frames transmitted without bit rate switching
     *   1 = CAN FD frames transmitted with bit rate switching
     */
    uint32_t fdf;
    /**< FD Format
     *   0 = Frame transmitted in Classic CAN format
     *   1 = Frame transmitted in CAN FD format
     */
    uint32_t efc;
    /**< Event FIFO Control
     *   0 = Don鈥檛 store Tx events
     *   1 = Store Tx events
     */
    uint32_t mm;
    /**< Message Marker */
    uint16_t  data[MCAN_MAX_PAYLOAD_BYTES];
    /**< Data bytes.
     *   Only first dlc number of bytes are valid.
     */
}MCAN_TxBufElement;

/**
 * \brief  Structure for MCAN Rx Buffer element.
 */
typedef struct
{
    uint32_t id;
    /**< Identifier */
    uint32_t rtr;
    /**< Remote Transmission Request
     *   0 = Received frame is a data frame
     *   1 = Received frame is a remote frame
     */
    uint32_t xtd;
    /**< Extended Identifier
     *   0 = 11-bit standard identifier
     *   1 = 29-bit extended identifier
     */
    uint32_t esi;
    /**< Error State Indicator
     *   0 = Transmitting node is error active
     *   1 = Transmitting node is error passive
     */
    uint32_t rxts;
    /**< Rx Timestamp */
    uint32_t dlc;
    /**< Data Length Code
     *   0-8  = CAN + CAN FD: received frame has 0-8 data bytes
     *   9-15 = CAN: received frame has 8 data bytes
     *   9-15 = CAN FD: received frame has 12/16/20/24/32/48/64 data bytes
     */
    uint32_t brs;
    /**< Bit Rat Switching
     *   0 = Frame received without bit rate switching
     *   1 = Frame received with bit rate switching
     */
    uint32_t fdf;
    /**< FD Format
     *   0 = Standard frame format
     *   1 = CAN FD frame format (new DLC-coding and CRC)
     */
    uint32_t fidx;
    /**< Filter Index */
    uint32_t anmf;
    /**< Accepted Non-matching Frame
     *   0 = Received frame matching filter index FIDX
     *   1 = Received frame did not match any Rx filter element
     */
    uint16_t  data[MCAN_MAX_PAYLOAD_BYTES];
    /**< Data bytes.
     *   Only first dlc number of bytes are valid.
     */
}MCAN_RxBufElement;

/**
 * \brief  Structure for MCAN Tx Event FIFO element.
 */
typedef struct
{
    uint32_t id;
    /**< Identifier */
    uint32_t rtr;
    /**< Remote Transmission Request
     *   0 = Data frame transmitted
     *   1 = Remote frame transmitted
     */
    uint32_t xtd;
    /**< Extended Identifier
     *   0 = 11-bit standard identifier
     *   1 = 29-bit extended identifier
     */
    uint32_t esi;
    /**< Error State Indicator
     *   0 = Transmitting node is error active
     *   1 = Transmitting node is error passive
     */
    uint32_t txts;
    /**< Tx Timestamp */
    uint32_t dlc;
    /**< Data Length Code
     *   0-8  = CAN + CAN FD: frame with 0-8 data bytes transmitted
     *   9-15 = CAN: frame with 8 data bytes transmitted
     *   9-15 = CAN FD: frame with 12/16/20/24/32/48/64 data bytes transmitted
     */
    uint32_t brs;
    /**< Bit Rat Switching
     *   0 = Frame transmitted without bit rate switching
     *   1 = Frame transmitted with bit rate switching
     */
    uint32_t fdf;
    /**< FD Format
     *   0 = Standard frame format
     *   1 = CAN FD frame format (new DLC-coding and CRC)
     */
    uint32_t et;
    /**< Event Type
     *   00 = Reserved
     *   01 = Tx event
     *   10 = Transmission in spite of cancellation
     *        (always set for transmissions in DAR mode)
     *   11 = Reserved
     */
    uint32_t mm;
    /**< Message Marker */
}MCAN_TxEventFIFOElement;

/**
 * \brief  Structure for MCAN Standard Message ID Filter Element.
 */
typedef struct
{
    uint32_t sfid2;
    /**< Standard Filter ID 2 */
    uint32_t sfid1;
    /**< Standard Filter ID 1 */
    uint32_t sfec;
    /**< Standard Filter Element Configuration (macros defined for each value)
     *   000 = Disable filter element                               (MCAN_STDFILTEC_DISABLE)
     *   001 = Store in Rx FIFO 0 if filter matches                 (MCAN_STDFILTEC_FIFO0)
     *   010 = Store in Rx FIFO 1 if filter matches                 (MCAN_STDFILTEC_FIFO1)
     *   011 = Reject ID if filter matches                          (MCAN_STDFILTEC_REJECT)
     *   100 = Set priority if filter matches                       (MCAN_STDFILTEC_PRI)
     *   101 = Set priority and store in FIFO 0 if filter matches   (MCAN_STDFILTEC_PRI_FIFO0)
     *   110 = Set priority and store in FIFO 1 if filter matches   (MCAN_STDFILTEC_PRI_FIFO1)
     *   111 = Store into Rx Buffer or as debug message,            (MCAN_STDFILTEC_RXBUFF)
     *         configuration of SFT[1:0] ignored.
     *   If SFEC = 鈥�100鈥�, 鈥�101鈥�, or 鈥�110鈥� a match sets high priority
     *   message event is generated.
     */
    uint32_t sft;
    /**< Standard Filter Type (macros defined for each value)
     *   00 = Range filter from SFID1 to SFID2 (SFID2 鈮� SFID1)  (MCAN_STDFILT_RANGE)
     *   01 = Dual ID filter for SFID1 or SFID2                 (MCAN_STDFILT_DUAL)
     *   10 = Classic filter: SFID1 = filter, SFID2 = mask      (MCAN_STDFILT_CLASSIC)
     *   11 = Filter element disabled                           (MCAN_STDFILT_DISABLED)
     */
}MCAN_StdMsgIDFilterElement;

/**
 * \brief  Structure for MCAN Extended Message ID Filter Element.
 */
typedef struct
{
    uint32_t efid1;
    /**< Extended Filter ID 1 */
    uint32_t efec;
    /**< Extended Filter Element Configuration
     *   000 = Disable filter element
     *   001 = Store in Rx FIFO 0 if filter matches
     *   010 = Store in Rx FIFO 1 if filter matches
     *   011 = Reject ID if filter matches
     *   100 = Set priority if filter matches
     *   101 = Set priority and store in FIFO 0 if filter matches
     *   110 = Set priority and store in FIFO 1 if filter matches
     *   111 = Store into Rx Buffer or as debug message,
     *         configuration of SFT[1:0] ignored.
     *   If EFEC = 鈥�100鈥�, 鈥�101鈥�, or 鈥�110鈥� a match sets high priority
     *   message event is generated.
     */
    uint32_t efid2;
    /**< Extended Filter ID 2 */
    uint32_t eft;
    /**< Extended Filter Type
     *   00 = Range filter from EFID1 to EFID2 (EFID2 鈮� EFID1)
     *   01 = Dual ID filter for EFID1 or EFID2
     *   10 = Classic filter: EFID1 = filter, EFID2 = mask
     *   11 = Range filter from EFID1 to EFID2 (EFID2 鈮� EFID1),
     *        XIDAM mask not applied
     */
}MCAN_ExtMsgIDFilterElement;

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                          Function Declarations                             */
/* ========================================================================== */


/**
 * \brief   This function selects the specified clock source for the MCAN controller.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   source          Clock source to use for the MCAN controller.
 *
 * The \e source parameter can be any one of the following:
 * - \b MCAN_CLOCK_SOURCE_SYS       - Peripheral System Clock
 * - \b MCAN_CLOCK_SOURCE_AUXIN     - Auxiliary Clock Input
 * - \b MCAN_CLOCK_SOURCE_PLLRAW    - PLL Raw Clock
 *
 * \retval  None
 */
void MCAN_selectClockSource(uint32_t baseAddr, MCAN_ClockSource source);

/**
 * \brief   This function checks if the MCAN module is in Reset.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \retval  state           Returns TRUE if reset is in progress.
 *                          Else returns FALSE.
 */
uint32_t MCAN_isInReset(uint32_t baseAddr);

/**
 * \brief   This API will return flexible data rate operation status
 *          MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  state           Returns TRUE if flexible data rate operation
 *                          is enabled. Else returns FALSE.
 */
uint32_t MCAN_isFDOpEnable(uint32_t baseAddr);

/**
 * \brief   This function checks if the memory initialization is done for
 *          MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \retval  state           Returns TRUE if memory initialization is done.
 *                          Else returns FALSE.
 */
uint32_t MCAN_isMemInitDone(uint32_t baseAddr);

/**
 * \brief   This API will set MCAN module mode of operation.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   mode            Mode of operation.
 *                          Refer enum #MCAN_OperationMode.
 *
 * \return  None.
 */
void MCAN_setOpMode(uint32_t baseAddr, uint32_t mode);

/**
 * \brief   This API will return MCAN module mode of operation.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  mode            Mode of operation.
 *                          Refer enum #MCAN_OperationMode.
 */
uint32_t MCAN_getOpMode(uint32_t baseAddr);

/**
 * \brief   This API will initialize MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   initParams      Initialization parameters.
 *                          Refer struct #MCAN_InitParams.
 *
 * \return  status          Initialization status.
 */
int32_t MCAN_init(uint32_t baseAddr, const MCAN_InitParams *initParams);

/**
 * \brief   This API will configure MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   configParams    configuration parameters.
 *                          Refer struct #MCAN_ConfigParams.
 *
 * \return  status          Configuration status.
 */
int32_t MCAN_config(uint32_t baseAddr, const MCAN_ConfigParams *configParams);

/**
 * \brief   This API will enable/disable ECC on the Message RAM.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   configParams    MCAN ECC Configuration Parameters.
 *                          Refer #struct MCAN_ECCConfigParams.
 *
 * \return  None.
 */
void MCAN_eccConfig(uint32_t                    baseAddr,
                    const MCAN_ECCConfigParams *configParams);

/**
 * \brief   This API will configure a bit timings for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   configParams    Configuration parameters for MCAN bit timing.
 *                          Refer struct #MCAN_BitTimingParams.
 *
 * \return  status          Bit Timings configuration status.
 */
int32_t MCAN_setBitTime(uint32_t                    baseAddr,
                        const MCAN_BitTimingParams *configParams);

/**
 * \brief   This API will configure Different sections of Message RAM.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   msgRAMConfigParams
 *                          Message RAM Configuration parameters.
 *                          Refer struct #MCAN_MsgRAMConfigParams.
 *
 * \return  status          Configuration Status.
 */
int32_t MCAN_msgRAMConfig(uint32_t                       baseAddr,
                          const MCAN_MsgRAMConfigParams *msgRAMConfigParams);

/**
 * \brief   This API will configure Extended ID AND Mask.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   idMask          Configuration parameters for MCAN Extended Id mask.
 *                          This value is 29 bit wide.
 *
 * \return  status          Extended ID AND Mask configuration status.
 */
int32_t MCAN_setExtIDAndMask(uint32_t baseAddr, uint32_t idMask);

/**
 * \brief   This API is used to write Tx message to message RAM.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   memType         Part of message ram to which given message to write.
 *                          Refer enum #MCAN_MemType.
 * \param   bufNum          Buffer  number where message to write.
 *                          This parameter will ignored if memType is FIFO/Q.
 * \param   elem            Message Object.
 *                          Refer struct #MCAN_TxBufElement.
 *
 * \return  None.
 */
void MCAN_writeMsgRam(uint32_t                 baseAddr,
                      uint32_t                 memType,
                      uint32_t                 bufNum,
                      const MCAN_TxBufElement *elem);

/**
 * \brief   This API will set Tx Buffer Add Request.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   bufNum          Tx Buffer number for which request is to be added.
 *
 * \return  status          Configuration Status.
 */
int32_t MCAN_txBufAddReq(uint32_t baseAddr, uint32_t bufNum);

/**
 * \brief   This API will return New Data Message Status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   newDataStatus   Rx Buffer new data status.
 *                          Refer struct #MCAN_RxNewDataStatus.
 *
 * \return  None.
 */
void  MCAN_getNewDataStatus(uint32_t              baseAddr,
                            MCAN_RxNewDataStatus *newDataStatus);

/**
 * \brief   This API clear New Data Message Status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   newDataStatus
 *                          Rx Buffer new data status.
 *                          Refer struct #MCAN_RxNewDataStatus.
 *
 * \return  None.
 */
void  MCAN_clearNewDataStatus(uint32_t                    baseAddr,
                              const MCAN_RxNewDataStatus *newDataStatus);

/**
 * \brief   This API is used to read received message form message RAM.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   memType         Part of message ram to which given message to write.
 *                          Refer enum #MCAN_MemType.
 * \param   bufNum          Buffer  number from where message is to read.
 *                          This parameter will ignored if memType is FIFO/Q.
 *  \param  fifoNum         FIFOs number from where message is to read.
 *                          Refer enum #MCAN_RxFIFONum.
 *                          This parameter will ignored if memType is buffer.
 * \param   elem            Message Object.
 *                          Refer struct #MCAN_RxBufElement.
 *
 * \return  None.
 */
void MCAN_readMsgRam(uint32_t           baseAddr,
                     uint32_t           memType,
                     uint32_t           bufNum,
                     uint32_t           fifoNum,
                     MCAN_RxBufElement *elem);

/**
 * \brief   This API is used to read message form Tx Event FIFO.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   txEventElem     Tx Event FIFO Message Object.
 *                          Refer struct #MCAN_TxEventFIFOElement.
 *
 * \return  None.
 */
void MCAN_readTxEventFIFO(uint32_t           baseAddr,
                          MCAN_TxEventFIFOElement *txEventElem);

/**
 * \brief   This API is used to add Standard Message ID Filter Element.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   filtNum         Filter number.
 * \param   elem            Filter Object.
 *                          Refer struct #MCAN_StdMsgIDFilterElement.
 *
 * \return  None.
 */
void MCAN_addStdMsgIDFilter(uint32_t                          baseAddr,
                            uint32_t                          filtNum,
                            const MCAN_StdMsgIDFilterElement *elem);

/**
 * \brief   This API is used to add Extended Message ID Filter Element.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   filtNum         Filter  number.
 * \param   elem            Filter Object.
 *                          Refer struct #MCAN_ExtMsgIDFilterElement.
 *
 * \return  None.
 */
void MCAN_addExtMsgIDFilter(uint32_t                          baseAddr,
                            uint32_t                          filtNum,
                            const MCAN_ExtMsgIDFilterElement *elem);

/**
 * \brief   This API will enable/disable Loop Back Test Mode for
 *          MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   lpbkMode        Loopback mode for MCAN.
 *                          Refer #enum MCAN_LpbkMode.
 * \param   enable          Loop Back Mode is enabled if it is TRUE.
 *                          Loop Back Mode is disabled  if it is FALSE.
 *
 * \return  None.
 * \note    This API can be called only when MCAN is in Software
 *          Initialization mode of operation.
 */
void MCAN_lpbkModeEnable(uint32_t baseAddr,
                         uint32_t lpbkMode,
                         uint32_t enable);

/**
 * \brief   This API will return error counter status for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   errCounter      Error Counter Status.
 *                          Refer struct #MCAN_ErrCntStatus.
 *
 * \return  None.
 */
void  MCAN_getErrCounters(uint32_t           baseAddr,
                          MCAN_ErrCntStatus *errCounter);

/**
 * \brief   This API will return protocol status for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   protStatus      Protocol Status.
 *                          Refer struct #MCAN_ProtocolStatus.
 *
 * \return  None.
 */
void  MCAN_getProtocolStatus(uint32_t             baseAddr,
                             MCAN_ProtocolStatus *protStatus);

/**
 * \brief   This API is used to enable/disable interrupts.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   intrMask        Interrupts to enable.
 *                          Refer enum #MCAN_IntrSrc.
 * \param   enable          Interrupt is enabled if it is TRUE.
 *                          Interrupt is disabled  if it is FALSE.
 *
 * \return  None.
 */
void MCAN_enableIntr(uint32_t baseAddr, uint32_t intrMask, uint32_t enable);

/**
 * \brief   This API is used to select interrupt line.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   intrMask        Interrupt Number for which interrupt
 *                          line is to be selected. Refer enum #MCAN_IntrSrc.
 * \param   lineNum         Interrupt Line to select.
 *                          Refer enum #MCAN_IntrLineNum,
 *
 * \return  None.
 */
void MCAN_selectIntrLine(uint32_t baseAddr,
                         uint32_t intrMask,
                         uint32_t lineNum);

/**
 * \brief   This API is used to get interrupt line selected for each interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Interrupt Line Select Status.
 */
uint32_t MCAN_getIntrLineSelectStatus(uint32_t baseAddr);

/**
 * \brief   This API is used to enable/disable selected interrupt line.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   lineNum         Interrupt Line to select.
 *                          Refer enum #MCAN_IntrLineNum,
 * \param   enable          Interrupt Line is enabled if it is 1.
 *                          Interrupt Line is disabled  if it is 0.
 *
 * \return  None.
 */
void MCAN_enableIntrLine(uint32_t baseAddr,
                         uint32_t lineNum,
                         uint32_t enable);

/**
 * \brief   This API will return interrupt status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Interrupt Status.
 */
uint32_t MCAN_getIntrStatus(uint32_t baseAddr);

/**
 * \brief   This API is used to clear the interrupt status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   intrMask        Interrupts to clear status.
 *
 * \return  None.
 */
void MCAN_clearIntrStatus(uint32_t baseAddr, uint32_t intrMask);

/**
 * \brief   This API is used to clear the interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   intrMask        Interrupts to clear.
 *                          0x00    External TS Interrupt is cleared
 *                          0x01    Interrupt Line 0 is cleared
 *                          0x02    Interrupt Line 1 is cleared
 *                          Other writes are ignored
 *
 * \return  None.
 */
void MCAN_clearInterrupt(uint32_t baseAddr, uint16_t intrNum);
/**
 * \brief   This API will return High Priority Message Status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   hpm             High Priority Message Status.
 *                          Refer struct #MCAN_HighPriorityMsgInfo.
 *
 * \return  None.
 */
void  MCAN_getHighPriorityMsgStatus(uint32_t                  baseAddr,
                                    MCAN_HighPriorityMsgInfo *hpm);

/**
 * \brief   This API will Rx FIFO status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   fifoStatus      Rx FIFO Status.
 *                          Refer struct #MCAN_RxFIFOStatus.
 *
 * \return  None.
 */
void MCAN_getRxFIFOStatus(uint32_t           baseAddr,
                          MCAN_RxFIFOStatus *fifoStatus);

/**
 * \brief   This API will write Rx FIFO Acknowledgement.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *                          Refer enum #MCAN_RxFIFONum.
 * \param   fifoNum         FIFO Number.
 * \param   idx             Rx FIFO Acknowledge Index
 *
 * \return  status          Acknowledgement Status.
 */
int32_t MCAN_writeRxFIFOAck(uint32_t baseAddr,
                            uint32_t fifoNum,
                            uint32_t idx);

/**
 * \brief   This API will Tx FIFO status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   fifoStatus      Tx FIFO Status.
 *                          Refer struct #MCAN_TxFIFOStatus.
 *
 * \return  None.
 */
void MCAN_getTxFIFOQueStatus(uint32_t           baseAddr,
                             MCAN_TxFIFOStatus *fifoStatus);

/**
 * \brief   This API will return Tx Buffer Request Pending status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Tx Buffer Request Pending status.
 */
uint32_t MCAN_getTxBufReqPend(uint32_t baseAddr);

/**
 * \brief   This API will set Tx Buffer Cancellation Request.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   buffNum         Tx Buffer number for which request is to be added.
 *
 * \return  status          Configuration Status.
 */
int32_t MCAN_txBufCancellationReq(uint32_t baseAddr, uint32_t buffNum);

/**
 * \brief   This API will return Tx Buffer Transmission Occurred status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Tx Buffer Transmission Occurred status.
 */
uint32_t MCAN_getTxBufTransmissionStatus(uint32_t baseAddr);

/**
 * \brief   This API will return Transmit Buffer Cancellation Finished status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Transmit Buffer Cancellation Finished status.
 */
uint32_t MCAN_txBufCancellationStatus(uint32_t baseAddr);

/**
 * \brief   This API is used to enable/disable Tx Buffer Transmission Interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   bufNum          Buffer number for which interrupt is to enable.
 * \param   enable          Interrupt is enabled if it is TRUE.
 *                          Interrupt is disabled  if it is FALSE.
 *
 * \return  status          Configuration status.
 */
int32_t MCAN_txBufTransIntrEnable(uint32_t baseAddr,
                                  uint32_t bufNum,
                                  uint32_t enable);

/**
 * \brief   This API is used to enable/disable Tx Buffer Cancellation Finished
 *          Interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   bufNum         Buffer number for which interrupt is to enable.
 * \param   enable          Interrupt is enabled if it is TRUE.
 *                          Interrupt is disabled  if it is FALSE.
 *
 * \return  status          Configuration status.
 */
int32_t MCAN_getTxBufCancellationIntrEnable(uint32_t baseAddr,
                                            uint32_t bufNum,
                                            uint32_t enable);

/**
 * \brief   This API add clock stop request for MCAN module to put it in
 *          power down mode.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   enable          Add CLock Stop Request.
 *                          Adds Clock Clock stop Request is TRUE otherwise
 *                          removes it.
 *
 * \return  None.
 */
void MCAN_addClockStopRequest(uint32_t baseAddr, uint32_t enable);

/**
 * \brief   This API will Tx Event FIFO status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   fifoStatus      Tx Event FIFO Status.
 *                          Refer struct #MCAN_TxEventFIFOStatus.
 *
 * \return  None.
 */
void MCAN_getTxEventFIFOStatus(uint32_t                baseAddr,
                               MCAN_TxEventFIFOStatus *fifoStatus);

/**
 * \brief   This API will write Event FIFO Acknowledge Index.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   idx             Event FIFO Acknowledge Index
 *
 * \return  status          Acknowledgement Status.
 */
int32_t MCAN_writeTxEventFIFOAck(uint32_t baseAddr, uint32_t idx);

/**
 * \brief   This API will Force Error on ECC.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   eccErr          Force Error on ECC configuration.
 *                          Refer struct #MCAN_ECCErrForceParams.
 *
 * \return  status          configuration status.
 */
void MCAN_eccForceError(uint32_t                      baseAddr,
                        const MCAN_ECCErrForceParams *eccErr);

/**
 * \brief   This API will return ECC Error status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   eccErr          ECC error status.
 *                          Refer struct #MCAN_ECCErrStatus.
 *
 * \return  None.
 */
void MCAN_eccGetErrorStatus(uint32_t           baseAddr,
                            MCAN_ECCErrStatus *eccErr);

/**
 * \brief   This API is used to clear the ECC Error status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   errType         Error type to clear status.
 *                          Refer enum #MCAN_ECCErrType.
 *
 * \return  None.
 */
void MCAN_eccClearErrorStatus(uint32_t baseAddr, uint32_t errType);

/**
 * \brief   This API is used to write End of Interrupt for ECC interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   errType         Interrupt to enable.
 *                          Refer enum #MCAN_ECCErrType.
 *
 * \return  None.
 */
void MCAN_eccWriteEOI(uint32_t baseAddr, uint32_t errType);

/**
 * \brief   This API is used to enable ECC interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   errType         Interrupt to enable.
 *                          Refer enum #MCAN_ECCErrType.
 * \param   enable          ECC Interrupt is enabled if it is TRUE.
 *                          ECC Interrupt is disabled  if it is FALSE.
 *
 * \return  None.
 */
void MCAN_eccEnableIntr(uint32_t baseAddr, uint32_t errType, uint32_t enable);

/**
 * \brief   This API is used to get ECC interrupt status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   errType         Interrupt status to read.
 *                          Refer enum #MCAN_ECCErrType.
 *
 * \return  None.
 */
uint32_t MCAN_eccGetIntrStatus(uint32_t baseAddr, uint32_t errType);

/**
 * \brief   This API is used to clear ECC interrupt status.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   errType         Interrupt status to clear.
 *                          Refer enum #MCAN_ECCErrType.
 *
 * \return  None.
 */
void MCAN_eccClearIntrStatus(uint32_t baseAddr, uint32_t errType);

/**
 * \brief   This API will configure external timestamp counter for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   prescalar       Timestamp Counter Prescaler. Range:[0x0-0xFFFFFF]
 *
 * \return  None.
 *
 * \note    Actual value programmed prescalar values is (prescalar - 1).
 */
void MCAN_extTSCounterConfig(uint32_t baseAddr,
                             uint32_t prescalar);

/**
 * \brief   This API will enable/disable fast external time stamp counter for
 *          MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   enable          External TS is enabled if it is 1.
 *                          External TS is disabled  if it is 0.
 *
 * \return  None.
 */
void MCAN_extTSCounterEnable(uint32_t baseAddr, uint32_t enable);

/**
 * \brief   This API will enable/disable External TimeStamp Counter
 *          Overflow Interrupt for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   enable          External TimeStamp Counter Overflow Interrupt is
 *                          enabled if it is TRUE.
 *                          External TimeStamp Counter Overflow Interrupt is
 *                          disabled  if it is FALSE.
 *
 * \return  None.
 */
void MCAN_extTSEnableIntr(uint32_t baseAddr, uint32_t enable);

/**
 * \brief   This API is used to write End of Interrupt for External TimeStamp
 *          Counter Overflow Interrupt.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  None.
 */
void MCAN_extTSWriteEOI(uint32_t baseAddr);

/**
 * \brief   This API returns Number of unserviced rollover/overflow
 *          interrupts for external TimeStamp counter.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Returns Number of unserviced rollover/overflow
 *                          interrupts for external TimeStamp counter.
 *                          Maximum number of unserviced interrupts is 0xF.
 */
uint32_t MCAN_extTSGetUnservicedIntrCount(uint32_t baseAddr);

/* ========================================================================== */
/*                          Advance Functions                                 */
/* ========================================================================== */

/**
 * \brief   This API is used get the MCAN revision ID.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   revId           Contains Revision ID of MCAN module.
 *                          Refer struct #MCAN_RevisionId.
 *
 * \return  None.
 */
void MCAN_getRevisionId(uint32_t baseAddr, MCAN_RevisionId *revId);

/**
 * \brief   This API get clock stop acknowledgement for MCAN module.
 *          It return whether MCAN is power down mode or not.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Return Clock Stop Acknowledgement status.
 *                          Return '1' if M_CAN is set in power down mode else
 *                          returns '0'.
 */
uint32_t MCAN_getClockStopAck(uint32_t baseAddr);

/**
 * \brief   This API will set External TimeStamp Counter Overflow Interrupt
 *          Raw status for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  None.
 */
void MCAN_extTSSetRawStatus(uint32_t baseAddr);

/**
 * \brief   This API will clear External TimeStamp Counter Overflow Interrupt
 *          raw status for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  None.
 */
void MCAN_extTSClearRawStatus(uint32_t baseAddr);

/**
 * \brief   This API will return Rx pin state of MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  state           MCAN Rx Pin State.
 *                          0= The CAN bus is dominant
 *                          1= The CAN bus is recessive
 */
uint32_t MCAN_getRxPinState(uint32_t baseAddr);

/**
 * \brief   This API will set Tx pin state of MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   state           MCAN Tx Pin State.
 *                          00= Reset value
 *                          01= Sample Point can be monitored at tx pin
 *                          10= The CAN bus is dominant
 *                          11= The CAN bus is recessive
 *                          other= It will treated as 11.
 *
 * \return  None.
 */
void MCAN_setTxPinState(uint32_t baseAddr, uint32_t state);

/**
 * \brief   This API will return Tx pin state of MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  state           MCAN Tx Pin State.
 *                          00= Reset value
 *                          01= Sample Point can be monitored at tx pin
 *                          10= The CAN bus is dominant
 *                          11= The CAN bus is recessive
 */
uint32_t MCAN_getTxPinState(uint32_t baseAddr);

/**
 * \brief   This API will return current timestamp counter value.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  val             Current Timestamp counter value.
 */
uint32_t MCAN_getTSCounterVal(uint32_t baseAddr);

/**
 * \brief   This API will return clock stop acknowledgement
 *          for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  ack             Clock Stop Acknowledge
 *                          0= No clock stop acknowledged
 *                          1= M_CAN may be set in power down
 */
uint32_t MCAN_getClkStopAck(uint32_t baseAddr);

/**
 * \brief   This API will get the configured bit timings for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   configParams    Configuration parameters for MCAN bit timing.
 *                          Refer struct #MCAN_BitTimingParams.
 *
 * \return  None.
 */
void MCAN_getBitTime(uint32_t              baseAddr,
                     MCAN_BitTimingParams *configParams);

/**
 * \brief   This API will reset timestamp counter value.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  None.
 */
void MCAN_resetTSCounter(uint32_t baseAddr);

/**
 * \brief   This API will return current time-out counter value.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  val             Current Time-out counter value.
 */
uint32_t MCAN_getTOCounterVal(uint32_t baseAddr);

/**
 * \brief   This API is used get the ECC AGGR revision ID.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   revId           Contains Revision ID of ECC AGGR.
 *                          Refer struct #MCAN_ECCAggrRevisionId.
 *
 * \return  None.
 */
void MCAN_eccAggrGetRevisionId(uint32_t                baseAddr,
                               MCAN_ECCAggrRevisionId *revId);

/**
 * \brief   This API is used get the ECC Wrapper revision ID.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 * \param   revId           Contains Revision ID of ECC Wrapper
 *                          Refer struct #MCAN_ECCWrapRevisionId.
 *
 * \return  None.
 */
void MCAN_eccWrapGetRevisionId(uint32_t                baseAddr,
                               MCAN_ECCWrapRevisionId *revId);

/**
 * \brief   This API returns External TimeStamp Counter Overflow Interrupt
 *          enable status for MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  status          Returns TRUE if External TimeStamp Counter Overflow
 *                          Interrupt is enabled.
 *                          Else returns FALSE.
 */
uint32_t MCAN_extTSIsIntrEnable(uint32_t baseAddr);

/**
 * \brief   This function return endianness value of MCAN module.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \retval  val             Endianness value. (0x87654321)
 */
uint32_t MCAN_getEndianVal(uint32_t baseAddr);

/**
 * \brief   This API will get the configured Extended ID AND Mask.
 *
 * \param   baseAddr        Base Address of the MCAN Registers.
 *
 * \return  idMask          Extended ID AND Mask.
 */
uint32_t MCAN_getExtIDANDMask(uint32_t baseAddr);

/**
 * \brief   This API will return message object size.
 *
 * \param   elemSize        Element Size.
 *
 * \return  message object size
 *                          Size of the message object stored in Message RAM.
 */
uint32_t MCAN_getMsgObjSize(uint32_t elemSize);

// Close the Doxygen group.
//! @}

#ifdef __cplusplus
}

#endif /*extern "C" */

#endif
不知道为什么代码进入中断了,设置断点后发现intrStatus的值为0x800 0000,但是一直都进不去中断里的这段代码

if((MCAN_IR_DRX_MASK & intrStatus) == MCAN_IR_DRX_MASK)
    {
        //
        // Read the NewData registers
        //
        MCAN_getNewDataStatus(MCANA_DRIVER_BASE, &newData);

        //  If message is received in buffer element 0
        if((newData.statusLow & (1UL << 0U)) != 0)
        {
            MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U,
                          0, &rxMsg1);

            rxMsg[loopCnt] = rxMsg1;
        }
        if((newData.statusLow & (1UL << 1U)) != 0)
        {
            MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 1U,
                          0, &rxMsg1);

            rxMsg[loopCnt] = rxMsg1;
        }main.c 


        //
        //  Clearing the NewData registers
        //
        MCAN_clearNewDataStatus(MCANA_DRIVER_BASE, &newData);
    }这段代码