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);
}这段代码