I'm trying to use the FlexCAN interface in non-polling mode using interrupts on the NXP gold box, but I can't get it to work. The interrupt handlers are never called and therefore the transfers do not complete.
#include "Clock_Ip.h"
#include "IntCtrl_Ip.h"
#include "Siul2_Port_Ip.h"
#include "Siul2_Dio_Ip.h"
#include "FlexCAN_Ip.h"
#include "FreeRTOS.h"
#include "task.h"
#define CAN0 0
#define CAN1 1
#define CAN_MB_SEND 0
#define CAN_MB_RECV 1
/* The polling mode works as expected, but non-polling does not work:
* The interrupt handlers are never called. */
#define CAN_POLLING 0
#define MSG_ID 20
#define main_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
volatile int exit_code = 0;
extern void CAN0_ORED_0_7_MB_IRQHandler(void);
extern void CAN1_ORED_0_7_MB_IRQHandler(void);
ISR(CAN0_IRQHandler)
{
Siul2_Dio_Ip_TogglePins(PTA, (1 << 6));
CAN0_ORED_0_7_MB_IRQHandler();
}
ISR(CAN1_IRQHandler)
{
Siul2_Dio_Ip_TogglePins(PTA, (1 << 6));
CAN1_ORED_0_7_MB_IRQHandler();
}
Flexcan_Ip_MsgBuffType rxData;
void CanRecvTask(void *pvParameters)
{
(void) pvParameters;
for( ;; )
{
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
#if CAN_POLLING
bool polling = true;
#else
bool polling = false;
#endif
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_ERROR;
rxData.data[0] = 0;
status = FlexCAN_Ip_ReceiveBlocking(CAN1, CAN_MB_RECV, &rxData, polling, 200);
if (status == FLEXCAN_STATUS_ERROR)
{
while(1); /* Error */
}
#if CAN_POLLING
else if (status == FLEXCAN_STATUS_SUCCESS)
{
if (rxData.data[0] == 6)
{
Siul2_Dio_Ip_TogglePins(PTA, (1 << 6));
}
}
#endif
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(50));
}
}
void CanSendTask(void *pvParameters)
{
(void) pvParameters;
for( ;; )
{
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const Flexcan_Ip_DataInfoType tx_info = {
.msg_id_type = FLEXCAN_MSG_ID_EXT,
.data_length = 8u,
.is_polling = true,
.is_remote = false
};
uint8 data[8];
data[0] = 6u;
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_ERROR;
status = FlexCAN_Ip_SendBlocking(CAN0, CAN_MB_SEND, &tx_info, MSG_ID, data, 200);
if (status == FLEXCAN_STATUS_ERROR)
{
while(1); /* Error */
}
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(100));
}
}
int main(void)
{
/* Initialize Os Interface */
OsIf_Init(NULL_PTR);
/* Initialize Clock */
Clock_Ip_StatusType Status_Init_Clock = CLOCK_IP_ERROR;
Status_Init_Clock = Clock_Ip_Init(Mcu_aClockConfigPB);
if (Status_Init_Clock != CLOCK_IP_SUCCESS)
{
while(1); /* Error during initialization. */
}
/* Initialize the Port driver */
Siul2_Port_Ip_PortStatusType Status_Init_Port = SIUL2_PORT_ERROR;
Status_Init_Port = Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
if(Status_Init_Port != SIUL2_PORT_SUCCESS)
{
while(1); /* Error during initialization. */
}
/* Initialize FlexCAN driver */
Flexcan_Ip_StatusType Status_Flexcan = FLEXCAN_STATUS_ERROR;
Status_Flexcan = FlexCAN_Ip_Init(CAN0, &FlexCAN_State0, &FlexCAN_Config0);
if(Status_Flexcan != FLEXCAN_STATUS_SUCCESS)
{
while(1); /* Error during initialization. */
}
Status_Flexcan = FlexCAN_Ip_Init(CAN1, &FlexCAN_State1, &FlexCAN_Config1);
if(Status_Flexcan != FLEXCAN_STATUS_SUCCESS)
{
while(1); /* Error during initialization. */
}
/* The following lines enable the reception of all CAN messages in
* a message buffer, by advising the hardware to ignore the passed ID */
/* Enable message buffer global masking */
FlexCAN_Ip_SetRxMaskType(CAN0, FLEXCAN_RX_MASK_GLOBAL);
FlexCAN_Ip_SetRxMaskType(CAN1, FLEXCAN_RX_MASK_GLOBAL);
/* Set the global mask as "don't care" for each message buffer */
FlexCAN_Ip_SetRxMbGlobalMask(CAN0, 0u);
FlexCAN_Ip_SetRxMbGlobalMask(CAN1, 0u);
/* Start FlexCAN */
FlexCAN_Ip_SetStartMode(CAN0);
FlexCAN_Ip_SetStartMode(CAN1);
/* Configure RX MB */
const Flexcan_Ip_DataInfoType rx_info = {
.msg_id_type = FLEXCAN_MSG_ID_EXT,
.data_length = 8u,
};
FlexCAN_Ip_ConfigRxMb(CAN0, CAN_MB_RECV, &rx_info, MSG_ID);
FlexCAN_Ip_ConfigRxMb(CAN1, CAN_MB_RECV, &rx_info, MSG_ID);
/* FlexCAN interrupt handlers */
IntCtrl_Ip_InstallHandler(CAN0_ORED_0_7_MB_IRQn, CAN0_IRQHandler, NULL_PTR);
IntCtrl_Ip_InstallHandler(CAN1_ORED_0_7_MB_IRQn, CAN1_IRQHandler, NULL_PTR);
IntCtrl_Ip_SetTargetCores(CAN0_ORED_0_7_MB_IRQn, 0x1);
IntCtrl_Ip_SetTargetCores(CAN1_ORED_0_7_MB_IRQn, 0x1);
IntCtrl_Ip_EnableIrq(CAN0_ORED_0_7_MB_IRQn);
IntCtrl_Ip_EnableIrq(CAN1_ORED_0_7_MB_IRQn);
/* Create tasks and start the scheduler */
xTaskCreate(CanSendTask, "CanSend" , configMINIMAL_STACK_SIZE, NULL_PTR, main_TASK_PRIORITY + 2, NULL_PTR);
xTaskCreate(CanRecvTask, "CanRecv" , configMINIMAL_STACK_SIZE, NULL_PTR, main_TASK_PRIORITY + 1, NULL_PTR);
vTaskStartScheduler();
/* Main loop */
for ( ;; )
{
if (exit_code != 0)
{
break;
}
}
/* De-initialize FlexCAN */
FlexCAN_Ip_SetStopMode(CAN0);
FlexCAN_Ip_SetStopMode(CAN1);
FlexCAN_Ip_Deinit(CAN0);
FlexCAN_Ip_Deinit(CAN1);
return exit_code;
}
Is there something wrong in the way I try to use the interface? Do I need to do anything else to enable the interrupts?