AnsweredAssumed Answered

FlexCAN Address Filtering example

Question asked by Fredrik Eriksen on Aug 13, 2019
Latest reply on Aug 14, 2019 by Hui_Ma

Hi,

 

We have an application running on RT1020 with dual CAN Bus enabled. And now with many devices on the network it is starting to get to a point where we cannot handle all requests because we are not doing any filtering, but firing interrupts  (flexcan_callback) for every message on the bus, and so we need to enable some kind of address filtering.

 

What we want to achieve is to have a list of approved messageIDs that must be matched by the incoming message for an interrupt to fire, and that all other messageIDs will be "invisible" to the processor.

 

Any leads on how to implement a simple address filtering scheme is greatly appreciated. If there are any details I can supply which would be useful towards a solution please let me know.

 

Thank you very much.

 

Best regards,

Fredrik

 

Currently how we initialize the CAN Driver:

static void canDriverInit(struct CanDevice *dev)
{
    /*Clock setting for FLEXCAN*/
    CLOCK_SetMux(kCLOCK_CanMux, FLEXCAN_CLOCK_SOURCE_SELECT);
    CLOCK_SetDiv(kCLOCK_CanDiv, FLEXCAN_CLOCK_SOURCE_DIVIDER);

    flexcan_config_t flexcanConfig;
    flexcan_rx_mb_config_t mbConfig;

    FLEXCAN_GetDefaultConfig(&flexcanConfig);
    flexcanConfig.baudRate = 250000U;
    FLEXCAN_Init(dev->base, &flexcanConfig, CAN_CLK_FREQ);

    FLEXCAN_TransferCreateHandle(dev->base, &dev->flexcanHandle, flexcanCallback, dev);
    FLEXCAN_SetRxMbGlobalMask(dev->base, FLEXCAN_RX_MB_EXT_MASK(0, 0, 0));
    can_enableSelfReception(dev->base, false);

    dev->txXfer.mbIdx = dev->txMessageBufferIndx;
    dev->txXfer.frame = &dev->txFlexcanFrame;

    mbConfig.format = kFLEXCAN_FrameFormatExtend;
    mbConfig.type = kFLEXCAN_FrameTypeData;
    mbConfig.id = FLEXCAN_ID_EXT(0);

    FLEXCAN_SetRxMbConfig(dev->base, dev->rxMessageBufferIndx, &mbConfig, true);
    FLEXCAN_SetTxMbConfig(dev->base, dev->txMessageBufferIndx, true);

     prepareRxMb(dev);
}

/**
* @brief Start a new RX operation on a CAN frame
* */
static inline void prepareRxMb(struct CanDevice *dev)
{
     /* Prepare the handle with mailbox ID and pointer to RX CAN frame */
     dev->rxXfer.mbIdx = dev->rxMessageBufferIndx;
     dev->rxXfer.frame = &dev->rxFlexcanFrame;

     /* Post the handle to the fsl_flexcan driver and return. This is a
      * non-blocking call, and the result will appear in the callback function */
     if (FLEXCAN_TransferReceiveNonBlocking(dev->base, &dev->flexcanHandle, &dev->rxXfer) != kStatus_Success)
     {
          /* Should not arrive here - will not attempt to post while RX active */
          dev->rxErrors.swBugEnableWhileBusy++;
     }
}

Outcomes