Part Number: TMS320F28P659DH-Q1
Other Parts Discussed in Thread: C2000WARE
Hi ALL,
reference ticket ---
MCAN Interrupt is occur only once
https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1622361/tms320f28p659dh-q1-mcan-interrupt-is-occur-only-once/6258007
In my code, I changed the configuration to 250 kbps using the following settings:
bitTiming.nomRatePrescalar = 3U;
bitTiming.nomTimeSeg1 = 11U;
bitTiming.nomTimeSeg2 = 8U;
bitTiming.nomSynchJumpWidth = 4U;
However, it did not work.
My target is 1 Mbps bitrate. I used the following configuration:
SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_10, 1U);
bitTiming.nomRatePrescalar = 0;
bitTiming.nomTimeSeg1 = 14;
bitTiming.nomTimeSeg2 = 5;
bitTiming.nomSynchJumpWidth = 2;
But this configuration also did not work.
Please refer to the code attached above for your reference.
Below is my processor card side configuration:
tcu1_processor_card_1:/home/petalinux# ip link set can1 down ip link set can1 type can bitrate 1000000 ip link set can1 up tcu1_processor_card_1:/home/petalinux# ip -details link show can1
4: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
bitrate 999999 sample-point 0.750
tq 50 prop-seg 7 phase-seg1 7 phase-seg2 5 sjw 2 brp 5
xilinx_can: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..256 brp_inc 1
clock 99999999 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size
Statistics output:
tcu1_processor_card_1:/home/petalinux# ip -details -statistics link show can14: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
bitrate 999999 sample-point 0.750
tq 50 prop-seg 7 phase-seg1 7 phase-seg2 5 sjw 2 brp 5
xilinx_can: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..256 brp_inc 1
clock 99999999
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 129 0 4 4 4 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped missed mcast
0 0 34 0 0 0
TX: bytes packets errors dropped carrier collsns
0 0 96 4 0 0
/* ================================================================
* mcan_debug.c – Working version for Linux SocketCAN
* 1 Mbps @ 75% Sample Point
* ================================================================ */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "driverlib.h"
#include "device.h"
#include "FreeRTOS.h"
#include "BSP/uart/uart.h"
#include "libs/mcan/mcan.h"
volatile uint8_t mcan_flag = 0;
volatile uint32_t mcan_isr_count = 0;
/* ---------------- Configuration ---------------- */
#define MCAN_FIFO_1_NUM 8U
#define MCAN_FIFO_1_ELEM_SIZE MCAN_ELEM_SIZE_8BYTES
#define MCAN_TX_BUFF_ELEM_SIZE MCAN_ELEM_SIZE_8BYTES
#define MCAN_STD_ID_FILT_START_ADDR 0x0000U
#define MCAN_FIFO_1_START_ADDR 0x0100U
#define MCAN_TX_BUFF_START_ADDR 0x0200U
MCAN_TxBufElement txMsg;
MCAN_RxBufElement rxMsg;
static void MCANConfig(void);
static void MCANIntrConfig(void);
__interrupt static void MCAN_isr(void);
MCAN_RxBufElement* MCAN_getLastRxMsg(void)
{
return &rxMsg;
}
void MCAN_initDriver(void)
{
int i;
/* Enable Transceiver */
GPIO_setDirectionMode(32, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(32, GPIO_PIN_TYPE_PULLUP);
GPIO_writePin(32, 0);
GPIO_setPinConfig(GPIO_32_GPIO32);
/* MCAN Clock = 20 MHz */
SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_10, 1U);
/* Configure CAN pins */
GPIO_setPinConfig(GPIO_45_MCANB_TX);
GPIO_setPinConfig(GPIO_44_MCANB_RX);
GPIO_setQualificationMode(44, GPIO_QUAL_ASYNC);
MCANIntrConfig();
for(i = 0; i < 64; i++)
rxMsg.data[i] = 0;
MCANConfig();
/* Enable RX FIFO interrupt */
MCAN_enableIntr(MCANB_DRIVER_BASE,
MCAN_INTR_SRC_RX_FIFO1_NEW_MSG,
1U);
MCAN_selectIntrLine(MCANB_DRIVER_BASE,
MCAN_INTR_SRC_RX_FIFO1_NEW_MSG,
MCAN_INTR_LINE_NUM_1);
MCAN_enableIntrLine(MCANB_DRIVER_BASE,
MCAN_INTR_LINE_NUM_1,
1U);
}
/* ------------------------------------------------ */
int MCAN_sendStdCAN(void)
{
uint16_t txData[4] = {0x11,0x22,0x33,0x44};
int i;
txMsg.id = ((uint32_t)0x123 << 18);
txMsg.rtr = 0;
txMsg.xtd = 0;
txMsg.esi = 0;
txMsg.dlc = 8;
txMsg.brs = 0;
txMsg.fdf = 0;
txMsg.efc = 0;
txMsg.mm = 0;
for(i=0;i<4;i++)
{
txMsg.data[i*2] = (uint8_t)(txData[i] & 0xFF);
txMsg.data[i*2+1] = (uint8_t)(txData[i] >> 8);
}
MCAN_writeMsgRam(MCANB_DRIVER_BASE,
MCAN_MEM_TYPE_BUF,
0,
&txMsg);
MCAN_txBufAddReq(MCANB_DRIVER_BASE,0);
return 0;
}
/* ------------------------------------------------ */
static void MCANConfig(void)
{
MCAN_InitParams initParams = {0};
MCAN_BitTimingParams bitTiming = {0};
MCAN_MsgRAMConfigParams ramCfg = {0};
MCAN_StdMsgIDFilterElement stdFilter = {0};
/* 1 Mbps configuration */
bitTiming.nomRatePrescalar = 0;
bitTiming.nomTimeSeg1 = 14;
bitTiming.nomTimeSeg2 = 5;
bitTiming.nomSynchJumpWidth = 2;
initParams.fdMode = 0;
initParams.brsEnable = 0;
/* Message RAM */
ramCfg.flssa = MCAN_STD_ID_FILT_START_ADDR;
ramCfg.lss = 1;
ramCfg.rxFIFO1startAddr = MCAN_FIFO_1_START_ADDR;
ramCfg.rxFIFO1size = MCAN_FIFO_1_NUM;
ramCfg.rxFIFO1waterMark = 1;
ramCfg.rxFIFO1ElemSize = MCAN_FIFO_1_ELEM_SIZE;
ramCfg.txStartAddr = MCAN_TX_BUFF_START_ADDR;
ramCfg.txBufNum = 1;
ramCfg.txBufElemSize = MCAN_TX_BUFF_ELEM_SIZE;
/* Accept Linux ID 0x7F4 */
stdFilter.sfid1 = 0x000;
stdFilter.sfid2 = 0x7FF;
stdFilter.sfec = 2; // store in FIFO1
stdFilter.sft = 2; // range filter
while(!MCAN_isMemInitDone(MCANB_DRIVER_BASE));
MCAN_setOpMode(MCANB_DRIVER_BASE,MCAN_OPERATION_MODE_SW_INIT);
while(MCAN_getOpMode(MCANB_DRIVER_BASE)!=MCAN_OPERATION_MODE_SW_INIT);
MCAN_init(MCANB_DRIVER_BASE,&initParams);
MCAN_setBitTime(MCANB_DRIVER_BASE,&bitTiming);
MCAN_msgRAMConfig(MCANB_DRIVER_BASE,&ramCfg);
MCAN_addStdMsgIDFilter(MCANB_DRIVER_BASE,0,&stdFilter);
MCAN_setOpMode(MCANB_DRIVER_BASE,MCAN_OPERATION_MODE_NORMAL);
while(MCAN_getOpMode(MCANB_DRIVER_BASE)!=MCAN_OPERATION_MODE_NORMAL);
}
/* ------------------------------------------------ */
static void MCANIntrConfig(void)
{
Interrupt_register(INT_MCANB_1,&MCAN_isr);
Interrupt_enable(INT_MCANB_1);
}
/* ------------------------------------------------ */
__interrupt void MCAN_isr(void)
{
uint32_t ir;
MCAN_RxFIFOStatus fs;
ir = MCAN_getIntrStatus(MCANB_DRIVER_BASE);
if(ir & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG)
{
MCAN_getRxFIFOStatus(MCANB_DRIVER_BASE,&fs);
MCAN_readMsgRam(MCANB_DRIVER_BASE,
MCAN_MEM_TYPE_FIFO,
fs.getIdx,
MCAN_RX_FIFO_NUM_1,
&rxMsg);
MCAN_writeRxFIFOAck(MCANB_DRIVER_BASE,
MCAN_RX_FIFO_NUM_1,
fs.getIdx);
mcan_flag = 1;
}
MCAN_clearIntrStatus(MCANB_DRIVER_BASE,ir);
MCAN_clearInterrupt(MCANB_DRIVER_BASE,MCAN_INTR_LINE_NUM_1);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);
mcan_isr_count++;
}
Below is my mcan.h
#include <stdint.h>
#include <stdbool.h>
#include "driverlib.h"
#include "device.h"
// Standard 11-bit CAN ID (matches receiver RX_MSG_OBJ_ID = 1)
#define STD_CAN_ID 0x01
#define MSG_DATA_LENGTH 8 // 4 x 2-byte (uint16_t)
extern volatile uint8_t mcan_flag;
static void MCANConfig(void);
static void MCANIntrConfig(void);
__interrupt static void MCAN_isr(void);
void MCAN_initDriver(void);
int MCAN_sendStdCAN(void);
extern volatile uint8_t mcan_flag;
extern volatile uint32_t mcan_isr_count;
MCAN_RxBufElement* MCAN_getLastRxMsg(void);
//extern volatile uint32_t mcan_isr_count = 0; // Add this counter
below is my main.c
void main()
MCAN_initDriver();
MCAN_sendStdCAN();
DEVICE_DELAY_US(500000); // 500ms
MCAN_sendStdCAN();
/* In vTransDataTask — print ISR count every loop to confirm */
SYSTEM_LOG_UART(LOG, __func__,
"mcan_isr_count=%lu mcan_flag=%u\r\n",
mcan_isr_count, mcan_flag);
while (1)
if (mcan_flag)
{
mcan_flag = 0;
MCAN_RxBufElement *msg = MCAN_getLastRxMsg();
/* Cap DLC — valid CAN = 0 to 8 bytes */
uint16_t dlc = (msg->dlc <= 8U) ? msg->dlc : 8U;
char buf[32] = {0};
uint16_t i, pos = 0;
for (i = 0; i < dlc; i++)
pos += snprintf(buf + pos, sizeof(buf) - pos, "%02X ", msg->data[i]);
SYSTEM_LOG_UART(LOG, __func__,
"MCAN RX: ID=0x%03X DLC=%u Data= %s\r\n",
(unsigned int)(msg->id >> 18U),
(unsigned int)dlc,
buf);
}
Could you please help me identify what might be wrong with my configuration?