Part Number: TMS320F28P659DH-Q1
Hi All,
Currently, I am working on the TMS320F28P65DK9. I am implementing the MCAN interface to enable communication between the processor card and the controller card.
I am able to receive data multiple times on the processor card when I run candump can1. On the processor card side, I have set the bitrate to 500 kbps, and on the controller card side, I have set it to 370 kbps.
If I change the controller card bitrate to 500 kbps, I am not able to receive any data on either the processor card side or the controller card side.
I am facing two issues:
-
When I flash the code through CCS for the second time, I am able to receive data from the controller card. However, after flashing it for the first time, I am not able to receive any data on the controller side.
-
The ISR is triggered only once able to receive the data. The second time, the ISR is not triggered Not able to receive any data, and I am not sure what the issue is.
Please help me resolve these issues.
/* ================================================================
* mcan_debug.c – Drop-in replacement for mcan.c
* Added: targeted debug prints to find proc→controller Rx failure
* ================================================================ */
#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; // Definition
volatile uint32_t mcan_isr_count = 0; // Add this counter
/* -------------------- Configuration -------------------- */
#define NUM_OF_MSG (1U) /* Used for both Tx and FIFO‑1 Rx */
/* Filters */
#define MCAN_STD_ID_FILTER_NUM (1U) /* 1 standard ID filter for Rx */
#define MCAN_EXT_ID_FILTER_NUM (0U)
/* FIFO‑0: Not used */
#define MCAN_FIFO_0_NUM (0U)
#define MCAN_FIFO_0_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
/* FIFO‑1: Used for Rx */
#define MCAN_FIFO_1_NUM (NUM_OF_MSG)
#define MCAN_FIFO_1_WATERMARK (NUM_OF_MSG)
#define MCAN_FIFO_1_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
/* Rx Buffer: Not used */
#define MCAN_RX_BUFF_NUM (0U)
#define MCAN_RX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
/* Tx Buffers */
#define MCAN_TX_BUFF_SIZE (NUM_OF_MSG)
#define MCAN_TX_FQ_SIZE (0U) /* Tx FIFO/Queue not used */
#define MCAN_TX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_8BYTES)
#define MCAN_TX_EVENT_SIZE (0U)
/* -------------------- Message RAM Address Map -------------------- */
#define MCAN_STD_ID_FILT_START_ADDR (0x0000U)
#define MCAN_EXT_ID_FILT_START_ADDR (MCAN_STD_ID_FILT_START_ADDR + (MCAN_STD_ID_FILTER_NUM * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U))
#define MCAN_FIFO_0_START_ADDR (MCAN_EXT_ID_FILT_START_ADDR + (MCAN_EXT_ID_FILTER_NUM * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U))
#define MCAN_FIFO_1_START_ADDR (MCAN_FIFO_0_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_0_ELEM_SIZE) * 4U * MCAN_FIFO_0_NUM))
#define MCAN_RX_BUFF_START_ADDR (MCAN_FIFO_1_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_1_ELEM_SIZE) * 4U * MCAN_FIFO_1_NUM))
#define MCAN_TX_BUFF_START_ADDR (MCAN_RX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_RX_BUFF_ELEM_SIZE) * 4U * MCAN_RX_BUFF_NUM))
#define MCAN_TX_EVENT_START_ADDR (MCAN_TX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_TX_BUFF_ELEM_SIZE) * 4U * (MCAN_TX_BUFF_SIZE + MCAN_TX_FQ_SIZE)))
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;
// SYSTEM_LOG_UART(LOG,__func__,"\r\n=== MCAN‑B Initialization ===\r\n");
// 1. Enable external transceiver (STB‑L on GPIO32)
GPIO_setPadConfig(32, GPIO_PIN_TYPE_PULLUP);
GPIO_writePin(32, 0);
GPIO_setPinConfig(GPIO_32_GPIO32);
GPIO_setDirectionMode(32, GPIO_DIR_MODE_OUT);
// 2. Set MCAN clock (20 MHz = SYSCLK / 5)
SysCtl_setMCANClk(SYSCTL_MCANB, SYSCTL_MCANCLK_DIV_5);
// 3. Configure MCANB TX/RX pins (TX=GPIO45, RX=GPIO44)
GPIO_setPinConfig(GPIO_45_MCANB_TX);
GPIO_setPinConfig(GPIO_44_MCANB_RX);
// 4. Configure interrupt line (PIE vector, etc.)
MCANIntrConfig();
// 5. Clear local RX buffer
for (i = 0; i < 64; i++)
rxMsg.data[i] = 0;
// 6. Configure MCAN module (core, filters, timing, RAM, etc.)
MCANConfig();
// 7. Enable all interrupt sources on line 1
MCAN_enableIntr (MCANB_DRIVER_BASE, MCAN_INTR_MASK_ALL, 1U);
MCAN_selectIntrLine (MCANB_DRIVER_BASE, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_1);
MCAN_enableIntrLine (MCANB_DRIVER_BASE, MCAN_INTR_LINE_NUM_1, 1U);
//SYSTEM_LOG_UART(LOG,__func__,"MCAN initialization done – Receiver ready for 0x7F4 standard ID\r\n");
}
int MCAN_sendStdCAN(void)
{
uint16_t txData[4] = {0x11, 0x22, 0x33, 0x44};
int i;
/* TX = 0x123 (different from 0x7F4 so no collision with Linux) */
txMsg.id = ((uint32_t)0x123U << 18U);
txMsg.rtr = 0U;
txMsg.xtd = 0U;
txMsg.esi = 0U;
txMsg.dlc = 8U;
txMsg.brs = 0U;
txMsg.fdf = 0U;
txMsg.efc = 0U;
txMsg.mm = 0U;
for (i = 0; i < 4; i++)
{
txMsg.data[i * 2] = (uint8_t)(txData[i] & 0xFFU);
txMsg.data[i * 2 + 1] = (uint8_t)((txData[i] >> 8U) & 0xFFU);
}
MCAN_writeMsgRam(MCANB_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U, &txMsg);
MCAN_txBufAddReq(MCANB_DRIVER_BASE, 0U);
return 0;
}
//int MCAN_sendStdCAN(void)
//{
// /* Use different TX ID so it doesn't collide with Linux cansend 7F4 */
// txMsg.id = ((uint32_t)0x123U << 18U); /* TX = 0x123, RX filter = 0x7F4 */
// txMsg.xtd = 0U;
// txMsg.rtr = 0U;
// txMsg.esi = 0U;
// txMsg.dlc = 8U;
// txMsg.brs = 0U;
// txMsg.fdf = 0U;
// txMsg.efc = 0U;
// txMsg.mm = 0U;
//
// txMsg.data[0] = 0xAA;
// txMsg.data[1] = 0xBB;
// txMsg.data[2] = 0xCC;
// txMsg.data[3] = 0xDD;
// txMsg.data[4] = 0x00;
// txMsg.data[5] = 0x00;
// txMsg.data[6] = 0x00;
// txMsg.data[7] = 0x00;
//
// MCAN_writeMsgRam(MCANB_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U, &txMsg);
// MCAN_txBufAddReq(MCANB_DRIVER_BASE, 0U);
// return 0;
//}
/* ======================================================================== */
static void MCANIntrConfig(void)
{
/* assume Interrupt_initModule/VectorTable already done in main() */
Interrupt_register(INT_MCANB_1, &MCAN_isr);
Interrupt_enable (INT_MCANB_1);
Interrupt_enableGlobal();
}
static void MCANConfig(void)
{
// SYSTEM_LOG_UART(LOG,__func__,
// "[MCAN] Initializing unified TX/RX configuration...\r\n");
//
MCAN_InitParams initParams = {0};
MCAN_BitTimingParams bitTiming = {0};
MCAN_MsgRAMConfigParams ramCfg = {0};
MCAN_StdMsgIDFilterElement stdFilter = {0};
/* ================= Bit Timing: 250 kbps @ 20 MHz ================= */
bitTiming.nomRatePrescalar = 3U;
bitTiming.nomTimeSeg1 = 9U;
bitTiming.nomTimeSeg2 = 8U;
bitTiming.nomSynchJumpWidth = 8U;
initParams.fdMode = 0;
initParams.brsEnable = 0;
/* ================= Message RAM Configuration ================= */
/* --- Standard Filter Section --- */
ramCfg.flssa = MCAN_STD_ID_FILT_START_ADDR; // Std filter start addr
ramCfg.lss = 1U; // Number of std filters
/* --- Extended Filter Section (Not Used) --- */
ramCfg.flesa = MCAN_EXT_ID_FILT_START_ADDR;
ramCfg.lse = 0U;
/* --- RX FIFO-1 --- */
ramCfg.rxFIFO1startAddr = MCAN_FIFO_1_START_ADDR;
ramCfg.rxFIFO1size = 1U;
ramCfg.rxFIFO1waterMark = 1U;
ramCfg.rxFIFO1OpMode = 0U;
ramCfg.rxFIFO1ElemSize = MCAN_FIFO_1_ELEM_SIZE;
/* --- TX Buffer --- */
ramCfg.txStartAddr = MCAN_TX_BUFF_START_ADDR;
ramCfg.txBufNum = 1U;
ramCfg.txBufMode = 0U;
ramCfg.txBufElemSize = MCAN_TX_BUFF_ELEM_SIZE;
/* ================= Filter: Accept ID 0x7F4 → FIFO-1 ================= */
stdFilter.sfid1 = 0x7F4;
stdFilter.sfid2 = 0x7FF; // Not critical for classic match
stdFilter.sfec = 0x2; // Store in FIFO-1
stdFilter.sft = 0x2; // Classic filter (exact match)
/* ================= Apply Configuration ================= */
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);
// SYSTEM_LOG_UART(LOG,__func__,
// "[MCAN] Config complete. NORMAL mode active.\r\n");
}
__interrupt void MCAN_isr(void)
{
uint32_t ir = MCAN_getIntrStatus(MCANB_DRIVER_BASE);
/* FIX 1: Clear PIE ACK immediately — correct group 10 */
MCAN_clearIntrStatus(MCANB_DRIVER_BASE, ir);
MCAN_clearInterrupt(MCANB_DRIVER_BASE, MCAN_INTR_LINE_NUM_1);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP10); /* WAS GROUP9 — BUG */
mcan_isr_count++; /* Always increment — tells you ISR fired */
GPIO_togglePin(99); /* Toggle LED — visual confirmation */
if (ir & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG)
{
MCAN_RxFIFOStatus fs;
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; /* FIX 2: No UART here — flag only */
}
}
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 file is main .c
MCAN_initDriver();
MCAN_sendStdCAN();
while (1)
{
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);
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);
}
}