This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28P659DH-Q1: MCAN Interrupt is occur only once

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:

  1. 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.

  2. 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);
       }
}
  • Hi Saravanan,

    I am looking into this issue for you and will provide a response before end of day tomorrow. Thank you for your patience.

    Best Regards,

    Zackary Fleenor

  • Hi Saravanan,

    This test involves communication between the Processor Card and the Controller Card.

    I identified a potential discrepancy in the CAN transceiver configuration. The code comments indicate a target baud rate of 250 kbps using a 20 MHz clock:

    bitTiming.nomRatePrescalar = 3U;
    bitTiming.nomTimeSeg1 = 9U;
    bitTiming.nomTimeSeg2 = 8U;
    bitTiming.nomSynchJumpWidth = 8U;

    However, based on the current configuration, the calculated baud rate is approximately 277.7 kbps:

    Calculation:

    * Time Quantum (TQ) = (Prescaler + 1) / CAN_Clock = (3 + 1) / 20 MHz = 200 ns
    * Bit Time = (1 + TimeSeg1 + TimeSeg2) * TQ = (1 + 9 + 8) * 200 ns = 3.6 μs
    * Baud Rate = 1 / Bit Time = 1 / 3.6 μs ≈ 277.7 kbps

    This difference could lead to communication errors or frame synchronization issues. I recommend adjusting the bit timing parameters to achieve the intended 250 kbps.

    Recommended Bit Timing for 250 kbps @ 20 MHz:

    bitTiming.nomRatePrescalar = 3U;
    bitTiming.nomTimeSeg1 = 11U;
    bitTiming.nomTimeSeg2 = 8U;
    bitTiming.nomSynchJumpWidth = 4U;

    This configuration yields a Bit Time of (1 + 11 + 8) * 200 ns = 4 μs, resulting in a baud rate of 250 kbps.

    For consideration: While 250kbps is achievable at 20MHz, running the MCAN peripheral at 80 MHz typically provides better timing resolution and overall robustness, particularly for higher throughput applications. Given your current data rate, the impact may be minimal, but I wanted to share this as a general best practice.

    Best Regards,

    Zackary Fleenor