Hello Everyone,
I have an interesting problem when I try to use RXFifo ( using interrupt) feature of FLEXCAN. I hope to find a solution as soon as possible.
I have initialized CAN driver with below configuration,
const flexcan_user_config_t canCom1_InitConfig0 = {
.fd_enable = false,
.pe_clock = FLEXCAN_CLK_SOURCE_FXOSC,
.max_num_mb = 96,
.num_id_filters = FLEXCAN_RX_FIFO_ID_FILTERS_128,
.is_rx_fifo_needed = true,
.flexcanMode = FLEXCAN_NORMAL_MODE,
.payload = FLEXCAN_PAYLOAD_SIZE_8,
.bitrate = {
.propSeg = 7,
.phaseSeg1 = 4,
.phaseSeg2 = 1,
.preDivider = 4,
.rJumpwidth = 1
},
.bitrate_cbt = {
.propSeg = 7,
.phaseSeg1 = 4,
.phaseSeg2 = 1,
.preDivider = 4,
.rJumpwidth = 1
},
.transfer_type = FLEXCAN_RXFIFO_USING_INTERRUPTS,
.rxFifoDMAChannel = 0U
};
I changed flexcan_id_table_t structure like that,
typedef struct {
bool isRemoteFrame; /*!< Remote frame*/
bool isExtendedFrame[128]; /*!< Extended frame*/
uint32_t idFilter[128]; /*!< Rx FIFO ID filter elements*/
} flexcan_id_table_t;
I filled id filter table,
rx_fifo_id_filter_table.isRemoteFrame = false;
for(id_counter=0;id_counter<128;id_counter++)
{
rx_fifo_id_filter_table.isExtendedFrame[id_counter] = (id_counter % 2);
rx_fifo_id_filter_table.idFilter[id_counter] = id_counter +1 ;
}
Here is the Flexcan Init function,
FLEXCAN_DRV_Init(INST_CANCOM1, &canCom1_State, &canCom1_InitConfig0);
I configured RX fifo and mask like that,
FLEXCAN_DRV_ConfigRxFifo(INST_CANCOM1, FLEXCAN_RX_FIFO_ID_FORMAT_A, &rx_fifo_id_filter_table);
FLEXCAN_DRV_SetRxMaskType(INST_CANCOM1, FLEXCAN_RX_MASK_INDIVIDUAL);
for(id_counter=0;id_counter<32;id_counter++)
FLEXCAN_DRV_SetRxIndividualMask(INST_CANCOM1, FLEXCAN_MSG_ID_EXT, id_counter, 0xFFFFFFFF);
FLEXCAN_DRV_SetRxFifoGlobalMask(INST_CANCOM1, FLEXCAN_MSG_ID_EXT, 0xFFFFFFFF);
Also I changed FLEXCAN_SetRxFifoFilter(only updated Format A side, because I use this format) function called in FLEXCAN_DRV_ConfigRxFifo function, because I need to filter both STD and Extended ID at the same time.
Here is the updated function,
void FLEXCAN_SetRxFifoFilter(
CAN_Type * base,
flexcan_rx_fifo_id_element_format_t idFormat,
const flexcan_id_table_t *idFilterTable)
{
DEV_ASSERT(idFilterTable != NULL);
/* Set RX FIFO ID filter table elements*/
uint32_t i, j, numOfFilters;
uint32_t val1 = 0, val2 = 0, val = 0U;
volatile uint32_t *filterTable = &base->RAMn[RxFifoFilterTableOffset];
numOfFilters = (((base->CTRL2) & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
switch(idFormat)
{
case (FLEXCAN_RX_FIFO_ID_FORMAT_A):
/* One full ID (standard and extended) per ID Filter Table element.*/
(base->MCR) = (((base->MCR) & ~(CAN_MCR_IDAM_MASK)) | ( (((uint32_t)(((uint32_t)(FLEXCAN_RX_FIFO_ID_FORMAT_A))<<CAN_MCR_IDAM_SHIFT))&CAN_MCR_IDAM_MASK)));
if (idFilterTable->isRemoteFrame)
{
val = FlexCanRxFifoAcceptRemoteFrame << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT;
}
for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++)
{
if (idFilterTable->isExtendedFrame[i])
{
val |= FlexCanRxFifoAcceptExtFrame << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT;
}
else
val = 0U;
if(idFilterTable->isExtendedFrame[i])
{
filterTable[i] = val + ((idFilterTable->idFilter[i] <<
FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT) &
FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
}
else
{
filterTable[i] = val + ((idFilterTable->idFilter[i] <<
FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT) &
FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
}
}
break;
Up to this side is init part of my project,
This is forever part of my code,
FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff);
With these configuration I expected that I can receive message with id that is defined in id table. It is working by step by debug operation. I have tried to receive and interrupt service with one by one defined ID.
After that, I have tried continues test with debug control sometimes. I have faced that a little time after, all interrupts are generated, rx warnig, rx overflow, rx frame avaliable. And CPU gets IVOR0_handler(), it is not avaliable now.
Here is the screen shot of my project status at that time,
Also your SDK interrupt service routine is not able to reset rx warning and rx overflow interrupt flag.
I changed for this aim your sdk interrupt service function like that,
if(flag_reg != 0U)
{
bool rxfifoEnabled = FLEXCAN_IsRxFifoEnabled(base);
if ((mb_idx == FEATURE_CAN_RXFIFO_FRAME_AVAILABLE || mb_idx ==FEATURE_CAN_RXFIFO_WARNING || mb_idx==FEATURE_CAN_RXFIFO_OVERFLOW ) && rxfifoEnabled)
{
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_RX_BUSY || true)
{
/* Get RX FIFO field values */
FLEXCAN_ReadRxFifo(base, state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mb_message);
/* Complete receive data */
FLEXCAN_CompleteRxMessageFifoData(instance);
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
/* Invoke callback */
if (state->callback != NULL)
{
state->callback(instance, FLEXCAN_EVENT_RXFIFO_COMPLETE, state);
}
}
}
As a result,
- According to your experience, which operation am I doing wrong? How can I fix this problem,
- My expectatiton from RX Fifo with interrupts feature, CPU can generate interrupt and gather data related message with up to 128 ID ( both STD and EXT with suitable mask operation).(Altough on the bus with %90 load(this is only for test)) Is it correct?
My project that I am working on is attached.
I am looking forward your comments,
Best regards,
Eyup,
Hi Eyup,
which SDK version do you use? Generally it is not recommended to modify the driver, we cannot guaranty the functionality then.
For example FLEXCAN_DRV_ConfigRxFifo in the SDK RTM 1.0.0 is properly filling the ID filter element so no modification is needed.
I created simple demo base on flexcan_mpc5748g example in this SDK version and it runs properly.
You can refer to https://community.nxp.com/docs/DOC-342882
BR, Petr