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); }