FLEXCAN RXFIFO and Gobal Mask Filter Behaviour Incorrect?

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

FLEXCAN RXFIFO and Gobal Mask Filter Behaviour Incorrect?

Jump to solution
2,976 Views
chris_evans
Contributor III

I have included below snippet of initialization code used with FLEXCAN on the MXRT1064-EVK board with MCUXpresso IDE. We have 19 filters, so there should be 12 filters (0-11) that can be individually masked, and the remaining 7 filters should be covered by the global mask. The intent is as follows:

11 bit IDs should be an exact match.

The next 8 29 bit IDs should be an exact PGN match

The remaining 29 bit IDs should only be an MSB match.

In accordance with 43.9.20 Rx Individual Mask Registers (FLEXCANx_RXIMRn) in IMXRT1064RM v.,,....

For Rx FIFO ID Filter Table Element, refer to Rx FIFO Global Mask Register.

So mask should take the format:

FLEXCANMask.png

What has been found is that using these filters in the code removes any filtering on the IDs so that all IDs are received and stored.

If the masks used are all set to 0x00FFFF00, then we get partial filtering. Some IDs are received correctly, others can be received correctly or in parts, others not at all. Why does the masking not follow what is documented? Has some setting been missed? Code initialization below:

void CAN_HAL_Init(void)
{
   flexcan_config_t flexcanConfig;
   flexcan_rx_fifo_config_t fifoconfig;

   // Create filter table, exact PGNs for parsed 11 bit and TP PGNs, partial for remaining due to limited filter space.
   uint32_t filterTable[] =
   {
      FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(0x10C, 0, 1),          // -
      FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(0x28C, 0, 1),          // |
      FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(0x7E0, 0, 1),          // |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00010000, 0, 0), // |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00DC4A00, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EA4A00, 0, 0),// | - Masked by individual filters 0 - 11
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EAFF00, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EB4A00, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EBFF00, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EC4A00, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00ECFF00, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00E00000, 0, 0),// -
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EE0000, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00EF0000, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00F00000, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00FC0000, 0, 0),// | - Masked by global filter
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00FD0000, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00FE0000, 0, 0),// |
      FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(0x00FF0000, 0, 0),// -
   };

// Create mask table.
// Match exact PGNs for 11 bit.
// Match PGN value for TP PGNs that apply to the unit.
// Match partial upper byte of PGN for other parsed values.
// See 43.9.13 Control 2 Register (FLEXCANx_CTRL2) for details on which filters are covered
// by which masks.
uint32_t maskTable[] =
{
   FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(0x7FF, 0, 1),
   FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(0x7FF, 0, 1),
   FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(0x7FF, 0, 1),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
   FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(0xFFFF00, 0, 0),
};

/*Clock setting for FLEXCAN*/
CLOCK_SetMux(kCLOCK_CanMux, FLEXCAN_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_CanDiv, FLEXCAN_CLOCK_SOURCE_DIVIDER);

/* Get FlexCAN module default Configuration. */
/*
* flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc;
* flexcanConfig.baudRate = 1000000U;
* flexcanConfig.baudRateFD = 2000000U;
* flexcanConfig.maxMbNum = 16;
* flexcanConfig.enableLoopBack = false;
* flexcanConfig.enableSelfWakeup = false;
* flexcanConfig.enableIndividMask = false;
* flexcanConfig.enableDoze = false;
* flexcanConfig.timingConfig = timingConfig;
*/
FLEXCAN_GetDefaultConfig(&flexcanConfig);
flexcanConfig.baudRate = 250000;
flexcanConfig.maxMbNum = 64;
flexcanConfig.enableIndividMask = true;
flexcanConfig.disableSelfReception = true;
FLEXCAN_Init(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ);

FLEXCAN_Enable(EXAMPLE_CAN, true);

/* Create FlexCAN handle structure and set call back function. */
FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);

/* Setup Rx Message Buffer. */
fifoconfig.idFilterNum = sizeof(filterTable) / sizeof(filterTable[0u]);
fifoconfig.idFilterType = kFLEXCAN_RxFifoFilterTypeA; // Need to have a filter type defined
fifoconfig.idFilterTable = filterTable;
fifoconfig.priority = kFLEXCAN_RxFifoPrioHigh;

FLEXCAN_SetRxFifoConfig(EXAMPLE_CAN, &fifoconfig, true);

// Write masks for filters
for(uint32_t u32Loop = 0u; u32Loop < (sizeof(maskTable)/4); u32Loop++)
{
   FLEXCAN_SetRxIndividualMask(EXAMPLE_CAN, u32Loop, maskTable[u32Loop]);
}

FLEXCAN_SetRxFifoGlobalMask(EXAMPLE_CAN,

                                                       FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(0xFF0000, 0, 0));

   // Setup Tx Message Buffers.
   for(uint8_t u8Loop = TX_MESSAGE_BUFFER_MIN; u8Loop < TX_MESSAGE_BUFFER_MAX; u8Loop++)
   {
      FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, u8Loop, true);
   }

   xfer.frame = &frame;

   FLEXCAN_TransferReceiveFifoNonBlocking(EXAMPLE_CAN, &flexcanHandle, &xfer);

   return;
}

Labels (1)
0 Kudos
1 Solution
2,604 Views
chris_evans
Contributor III

Solution was to invert the IDE bit, as suggested by Ramanathan SG (many thanks for spotting this one), so:

FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(PGN_xxxxx7E0, 0, 1), 
FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(PGN_xx0100xx & PGN_FILTER_MASK, 0, 0),

have their IDE bits inverted to become:

FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(PGN_xxxxx7E0, 0, 0), 
FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(PGN_xx0100xx & PGN_FILTER_MASK, 0, 1),

This also applies the FIFO masking it seems so the STD mask:

FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(STD_ID_MASK, 0, 1),

becomes 

FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(STD_ID_MASK, 0, 0),

But I have left the IDE for the extended mask as 1.

Finally, the global mask was configured incorrectly. It was using the FLEXCAN_RX_FIFO_STD_MASK_TYPE_A macro and should have been using the FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A macro.

View solution in original post

0 Kudos
12 Replies
2,605 Views
chris_evans
Contributor III

Solution was to invert the IDE bit, as suggested by Ramanathan SG (many thanks for spotting this one), so:

FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(PGN_xxxxx7E0, 0, 1), 
FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(PGN_xx0100xx & PGN_FILTER_MASK, 0, 0),

have their IDE bits inverted to become:

FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(PGN_xxxxx7E0, 0, 0), 
FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(PGN_xx0100xx & PGN_FILTER_MASK, 0, 1),

This also applies the FIFO masking it seems so the STD mask:

FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(STD_ID_MASK, 0, 1),

becomes 

FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(STD_ID_MASK, 0, 0),

But I have left the IDE for the extended mask as 1.

Finally, the global mask was configured incorrectly. It was using the FLEXCAN_RX_FIFO_STD_MASK_TYPE_A macro and should have been using the FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A macro.

0 Kudos
2,604 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Chris,

 

I am sorry for the late reply. I have been checking this issue with my MIMXRT1064-EVK but using Mailbox Global Mask and analyzing the behavior when using Individual filters.

 

My results were that when using Individual mask and Global mask at the same time, Global mask is ignored.

 

However, I found the following statement in Reference Manual.

FlexCAN also supports an alternate masking scheme with only four mask registers (RXFGMASK, RXMGMASK, RX14MASK, and RX15MASK) for backwards compatibility with legacy applications. This alternate masking scheme is enabled when the IRMQ bit in the MCR register is negated.

As it is mentioned these four mask registers are not enabled when the Individual Rx Masking is enabled. Sorry for the inconvenience this may cause you.

 

I hope this information is useful.

 

Best regards,

Felipe

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,604 Views
chris_evans
Contributor III

Hi Felipe,

Thank you for taking the time to investigate. Is this a silicon, driver or documentation issue in that case? This does not fit the description of the FLEXCANx_CTRL2 register operation, which is described in Table 44-22, page 2622 of the reference manual.

Regards,

Chris

0 Kudos
2,604 Views
FelipeGarcia
NXP Employee
NXP Employee

Global filters worked correct when I was not using Individual Masks. The fact that they cannot be used together is a driver limitation. Sorry for the inconveniences.

 

Best regards,

Felipe

0 Kudos
2,604 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Christopher,

 

Does it work correct if you only enable individual mask or FIFO global mask by itself? Not both at the same time.

 

Best regards,

Felipe

0 Kudos
2,604 Views
chris_evans
Contributor III

Hi Felipe,

If I do not configure the FIFO global mask:

The 11 bit PGNs are no longer processed, unless I send the following:

0x100, 0x200, 0x400, 0x500, 0x600

Which I have not configured - this makes no sense to me.

I can receive all PGNs that are covered by the individual mask and the masking appears to cover the correct part of the PGN (I can change the SA etc. and still receive the message as it should) - exactly what I required and as expected.

The remaining PGNs require exact matches, since there is no masking on the incoming data - this is not acceptable, but is as expected.

If I just configure the FIFO global mask, it is as if there is no filtering again.

Note: For this test I have not changed the values of the filters or masks, I just commented them out / added them in.

Regards,

Chris

0 Kudos
2,604 Views
chris_evans
Contributor III

Has anyone else seen similar issues?

Regards,

Chris

0 Kudos
2,604 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello Chris,

 

I am sorry for the late reply. We have been under a big workload.

 

According to my understanding you are trying to filter according to maskTable in your code, but when you set individual masks to 0xFFFF00 and global to 0xFF0000 you get Some IDs are received correctly and others that do not work.

 

Could you please specify in which circumstances and which IDs do not work as they should after you enable the filters?

 

In addition, I did not get your latest reply, you mentioned:

I can receive all PGNs that are covered by the individual mask and the masking appears to cover the correct part of the PGN (I can change the SA etc. and still receive the message as it should) - exactly what I required and as expected.

You mean individual masks work as they should and the issues begin when you enable FIFO global mask?

 

If you have any update or additional information please let me know.

 

Best regards,

Felipe

0 Kudos
2,604 Views
chris_evans
Contributor III

Hi Felipe,

No problem, I gather things must be hectic at the moment!

Could you please specify in which circumstances and which IDs do not work as they should after you enable the filters?

Using the init code as per my original question appears to have no filtering effect. Whatever I send on the CAN bus gets processed.

You mean individual masks work as they should and the issues begin when you enable FIFO global mask?

Correct. Individual masks work perfectly when FIFO global mask is disabled. 

Regards,

Chris

0 Kudos
2,604 Views
ram_ald
Contributor II

Dear Christopher Evans, 

We are also started with flexCAN Rx fifo implementaion on i.Mx RT board, could you please share the link of document which you quoted in "FLEXCAN RXFIFO and Gobal Mask Filter Behaviour Incorrect?" query. "In accordance with 43.9.20 Rx Individual Mask Registers (FLEXCANx_RXIMRn)"

When we try to receive multiple CAN ID, we are unable to receive the multiple CAN IDs, we need to have more calrity on the mask/filter settings. 

It will help us to understand the Rx FIFO and its masks/filter details. 

0 Kudos
2,604 Views
chris_evans
Contributor III

Dear Ramanathan,

That comes from the iMXRT1064 Processor Reference Manual Rev 0.1, which was what we were working with when we started development. It should be on the product page somewhere on NXPs website.

Regards,

Chris

0 Kudos
2,604 Views
ram_ald
Contributor II

Dear Sir,

Thank you so much for sharing manual details.

Also, in your code, last argument for FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A supposed to be zero (ide) for the standard filter as per the manual page# 2570 (below Table 44-12). Please check for it. We worked out to receive multiple CAN ids using FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A where we passed canid, rtr=0 & ide=0 arguments.

It worked fine. We have not configured any maskings.  

This is for your kind information.