After init the MCAN module and install callback, start receiving MCAN message by calling MCAN_DRV_RxFifo in callback function.
The init code :
MCAN_DRV_Init(CAN_CH1, &McanCom1_State, &McanCom1_mcan_user_config_t0);
MCAN_DRV_InstallEventCallback(CAN_CH1, (mcan_callback_t)Mcan1InterruptCallback, NULL);
MCAN_DRV_ConfigRxFifo(CAN_CH1, (mcan_id_table_t **)&McanCom1_mcan_id_table_t0[0], 1);
MCAN_DRV_RxFifo(CAN_CH1, 0, recvMsgBuff);
The fuction callback code:
static void Mcan1InterruptCallback(uint8_t instance,
mcan_event_type_t eventType,
uint32_t idx,
mcan_state_t *mcanState)
{
DEV_ASSERT(mcanState != NULL);
mcan_msgbuff_t *recvBuff = &s_mcanMsgBuff;
M_CAN_Type * base = g_mcanBase[instance];
uint8_t value = 0U;
switch (eventType)
{
case MCAN_EVENT_TX_COMPLETE:
break;
case MCAN_EVENT_RX0FIFO_COMPLETE:
MCAN_DRV_RxFifo(instance, 0, recvBuff);
break;
case MCAN_EVENT_RX0FIFO_WARNING:
MCAN_DRV_RxFifo(instance, 0, recvBuff);
break;
case MCAN_EVENT_RX0FIFO_OVERFLOW:
break;
default:
printf("other type = %d \r\n", eventType);
break;
}
}
When received CAN message, generated interrupt and called callback fucnftion Mcan1InterruptCallback, and eventType = MCAN_EVENT_RX0FIFO_COMPLETE, then called function MCAN_DRV_RxFifo(instance, 0, recvBuff). Line 1685-1707 in mcan_driver.c, if the number of received message is greater than 1, the callback function will call itself in mcan_driver.c line 1074 function static void MCAN_CompleteRxFIFO(uint8_t instance,mode_type_t type). If the number of CAN message is greater than 1 all the time, the callback fucntion will always call itself and will cause stack overflow.
Maybe I do not write the callback fucntion, If it is wrong, how do I write the callback function.
Hello,
What water mark level did you configured for generation of MCAN_EVENT_RX0FIFO_WARNING.
The overflow can be caused because if you call another receive from a callback function, this is not allowed because will not allow you to end current ISR. The callbacks are made only for notifications not for driver state changes.
volatile bool finished_transfer = false;
static void Mcan1InterruptCallback(uint8_t instance,
mcan_event_type_t eventType,
uint32_t idx,
mcan_state_t *mcanState)
{
DEV_ASSERT(mcanState != NULL);
mcan_msgbuff_t *recvBuff = &s_mcanMsgBuff;
M_CAN_Type * base = g_mcanBase[instance];
uint8_t value = 0U;
switch (eventType)
{
case MCAN_EVENT_TX_COMPLETE:
break;
case MCAN_EVENT_RX0FIFO_COMPLETE:
/* fall-true */
case MCAN_EVENT_RX0FIFO_WARNING:
finished_transfer = true;
break;
case MCAN_EVENT_RX0FIFO_OVERFLOW:
break;
default:
printf("other type = %d \r\n", eventType);
break;
}
}
somehere in your main loop
if (finished_transfer == true)
{
MCAN_DRV_RxFifo(instance, 0, recvBuff);
finished_transfer = false;
}
BR,
Alexandru Nan