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