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.

TMS320F280039C: MCAN interrupt will only trigger one time.

Part Number: TMS320F280039C

I have a system where MCAN interrupts are triggered by received and transmitted messages.

First interrupt works as expected, the MCAN_IR: RF0N is set and the program enters the interrupts, responds and resets.. The problem is when the next message arrives it won't trigger the interrupt even though MCAN_IR: RF0N is set. I have used the scope and can see that the messages that are arriving are getting ACK'ed.

Mcan config:

void Init_Mcan(){

    // Configure the divisor for the MCAN bit-clock
    SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_2);

     MCAN_InitParams            initParams;
     MCAN_ConfigParams          configParams;
     MCAN_MsgRAMConfigParams    msgRAMConfigParams;
     MCAN_BitTimingParams       bitTimes;

      // Initialize MCAN Init parameters.
     initParams.fdMode            = 0x0U; // FD operation disabled.
     initParams.brsEnable         = 0x0U; // Bit rate switching for transmissions disabled.
      initParams.tdcConfig.tdcf    = 0xAU;
      initParams.tdcConfig.tdco    = 0x6U;
      initParams.txpEnable         = 0x0U; // Transmit pause disabled.
      initParams.efbi              = 0x0U; // Edge filtering disabled.
      initParams.pxhddisable       = 0x0U; // Protocol exception handling enabled
      initParams.darEnable         = 0x0U; // Enable Automatic retransmission of
                                         // messages not transmitted successfully
      initParams.wkupReqEnable     = 0x1U; // Wakeup request is enabled.
      initParams.autoWkupEnable    = 0x1U; // Auto-Wakeup is enabled.
      initParams.emulationEnable   = 0x1U; // Emulation/Debug Suspend is enabled.
      initParams.tdcEnable         = 0x1U; // Transmitter Delay Compensation is
                                           // enabled.


      // Initialize MCAN Config parameters.
      configParams.monEnable         = 0x0U;    // Bus Monitoring Mode is disabled
      configParams.asmEnable         = 0x0U;    // Normal CAN operation.
      configParams.tsPrescalar       = 0xFU;    //0xFU;  // Prescaler Value.
      configParams.tsSelect          = 0x0U;    // Timestamp counter value.
      configParams.timeoutSelect     = MCAN_TIMEOUT_SELECT_CONT; // Time-out counter source select
      configParams.timeoutPreload    = 0xFFFFU; // Start value of the Timeout Counter.
      configParams.timeoutCntEnable  = 0x0U; // Time-out Counter is disabled.


      // Initialize Message RAM Sections Configuration Parameters
      msgRAMConfigParams.flssa                = MCAN_STD_ID_FILT_START_ADDR;    // Standard ID Filter List Start Address.
      msgRAMConfigParams.lss                  = MCAN_STD_ID_FILTER_NUM;

      msgRAMConfigParams.txStartAddr          = MCAN_TX_BUFF_START_ADDR;        // Tx Buffers Start Address.
      msgRAMConfigParams.txBufNum             = 0; //MCAN_TX_BUFF_SIZE;         // Number of Dedicated Transmit Buffers.
      msgRAMConfigParams.txFIFOSize           = 4U;
      msgRAMConfigParams.txBufMode            = 0U;
      msgRAMConfigParams.txBufElemSize        = MCAN_ELEM_SIZE_8BYTES;          // Tx Buffer Element Size.

      msgRAMConfigParams.rxFIFO0startAddr     = MCAN0_MCAN_FIFO_0_START_ADDR;
      msgRAMConfigParams.rxFIFO0size          = 100;
      msgRAMConfigParams.rxFIFO0OpMode        = 1;                              // 1 = Overwrite mode, 0 = Blocking mode
      msgRAMConfigParams.rxBufStartAddr       = MCAN_RX_BUFF_START_ADDR;        // Rx Buffer Start Address.
      msgRAMConfigParams.rxBufElemSize        = MCAN_ELEM_SIZE_8BYTES;          // Rx Buffer Element Size.

      // Initialize bit timings. Based on CAN.c setBitRate function
      bitTimes.nomRatePrescalar   = 0x5U; // Nominal Baud Rate Pre-scaler.
      bitTimes.nomTimeSeg1        = 0x6U; // Nominal Time segment before SP.
      bitTimes.nomTimeSeg2        = 0x1U; // Nominal Time segment after SP.
      bitTimes.nomSynchJumpWidth  = 0x1U; // Nominal SJW Range.


      // Wait for memory initialization to happen.
      while(FALSE == MCAN_isMemInitDone(MCAN0_BASE));

      // Put MCAN in SW initialization mode.
      MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_SW_INIT);

      // Wait till MCAN is not initialized.
      while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(MCAN0_BASE));

      // Initialize MCAN module.
      MCAN_init(MCAN0_BASE, &initParams);

      // Configure MCAN module.
      MCAN_config(MCAN0_BASE, &configParams);

      // Configure Bit timings.
      MCAN_setBitTime(MCAN0_BASE, &bitTimes);



      // Configure Message RAM Sections
      MCAN_msgRAMConfig(MCAN0_BASE, &msgRAMConfigParams);


      // Take MCAN out of the SW initialization mode
      MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_NORMAL);

      while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(MCAN0_BASE));

      //Enable All Interrupts is marked, other flags are redundant
      MCAN_enableIntr(MCAN0_BASE,  MCAN_INTR_MASK_ALL, 1U);//MCAN_INTR_LINE_NUM_0 interrupt for line Zero
      MCAN_enableIntr(MCAN0_BASE,  MCAN_INTR_MASK_DISABLE, 0U);
      MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_SRC_RX_FIFO0_NEW_MSG | MCAN_INTR_SRC_TRANS_COMPLETE, MCAN_INTR_LINE_NUM_0); // MCAN_INTR_MASK_ALL
      MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_0, 1U);

      MCAN_txBufTransIntrEnable(MCAN0_BASE, 0, 1);
      MCAN_txBufTransIntrEnable(MCAN0_BASE, 1, 1);
      MCAN_txBufTransIntrEnable(MCAN0_BASE, 2, 1);
      MCAN_txBufTransIntrEnable(MCAN0_BASE, 3, 1);


      MCANFilterConfig();
}

Mcan ISR:

void Init_MCANIsr(void)
{
    Interrupt_register(INT_MCAN_0, &MCAN_Isr0);  //MCAN_INTR_LINE_NUM_0
    Interrupt_enable(INT_MCAN_0);

    ISRreceiveCnt  = 0;
    ISRtransmitCnt = 0;
    ISRerrorCnt = 0;
}

__interrupt void MCAN_Isr0(void)
{
    uint32 Localstatus;
    uint16 txMsgType, LocalInterrptLevel;
    LocalInterrptLevel = IER;
    IER &= 0x000F;
    EINT;

    Localstatus = MCAN_getIntrStatus(MCAN_MSG_RAM_BASE);

    if(Localstatus == MCAN_INTR_SRC_RX_FIFO0_NEW_MSG)
    {
        ISRreceiveCnt++;
        CcpMonitor();
        MCAN_clearIntrStatus(MCAN_MSG_RAM_BASE, MCAN_INTR_SRC_RX_FIFO0_NEW_MSG);
        MCAN_clearIntrStatus(MCAN_MSG_RAM_BASE, MCAN_INTR_SRC_TRANS_COMPLETE);
    }
    else if(Localstatus == MCAN_INTR_SRC_TRANS_COMPLETE)
    {
        txMsgType = MCAN_getTxBufTransmissionStatus(MCAN_MSG_RAM_BASE);

        if(txMsgType == TX_MSG_DAQ1)
        {
            CcpDaqListTransmitter(DAQ_FAST);
            MCAN_clearIntrStatus(MCAN_MSG_RAM_BASE, MCAN_INTR_SRC_TRANS_COMPLETE);
        }
        else if(txMsgType == TX_MSG_DAQ2)
        {
            CcpDaqListTransmitter(DAQ_MED);
            MCAN_clearIntrStatus(MCAN_MSG_RAM_BASE, MCAN_INTR_SRC_TRANS_COMPLETE);
        }
        else if(txMsgType == TX_MSG_DAQ3)
        {
            Spy_DaqListTransmitter();
            MCAN_clearIntrStatus(MCAN_MSG_RAM_BASE, MCAN_INTR_SRC_TRANS_COMPLETE);
        }
    }

    IER = LocalInterrptLevel;
    // Update the flag value.
    
    
    // Acknowledge this interrupt located in group 9
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}