FlexCAN in non-polling mode / no interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FlexCAN in non-polling mode / no interrupts

874 Views
olesalscheider
Contributor I

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.

In this is my code:

#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?

0 Kudos
1 Reply

865 Views
olesalscheider
Contributor I

Without setting the target cores I get the interrupt, but then I'm stuck in the `undefined_handler`.

If I modify the `Vector_Table.s` file to point to my handlers for interrupts 39 and 43, then my handlers are called and the code works. But why does `IntCtrl_Ip_InstallHandler` not work? I wonder if there is a problem with the relocation of the vector to RAM or if it only registers the handlers for one of the cores and the interrupt is processed on another core? Or are the handlers overwritten somewhere?

0 Kudos