AnsweredAssumed Answered

FLEXCAN RXFIFO and Gobal Mask Filter Behaviour Incorrect?

Question asked by Christopher Evans on Jan 28, 2020
Latest reply on Feb 20, 2020 by Ramanathan SG

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:

FLEXCAN Mask Type A layout

 

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;
}

Outcomes