FlexCAN Address Filtering example

cancel
Showing results for 
Search instead for 
Did you mean: 

FlexCAN Address Filtering example

623 Views
Contributor II

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++;
 }
}
Labels (1)
Tags (3)
0 Kudos
6 Replies

34 Views
Contributor II

fredrikeriksen

Hi Fredrik,

What is your 

can_enableSelfReception(dev->base, false);

function doing in this scenario, and what does the code look like please?

Thanks,

Graham.

0 Kudos

34 Views
Contributor V

Hi Fredrik Eriksen,

solved your problems ?

I have the same problem to solve, filtering 3/10.

thanks,

Carlos.

0 Kudos

34 Views
NXP TechSupport
NXP TechSupport

Hi,

Customer can call below two FlexCAN functions to filter RX CAN message frame:

/*!
 * brief Sets the FlexCAN receive message buffer global mask.
 *
 * This function sets the global mask for the FlexCAN message buffer in a matching process.
 * The configuration is only effective when the Rx individual mask is disabled in the FLEXCAN_Init().
 *
 * param base FlexCAN peripheral base address.
 * param mask Rx Message Buffer Global Mask value.
 */
void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask)

And

/*!
 * brief Sets the FlexCAN receive individual mask.
 *
 * This function sets the individual mask for the FlexCAN matching process.
 * The configuration is only effective when the Rx individual mask is enabled in the FLEXCAN_Init().
 * If the Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer.
 * If the Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to
 * the Rx Filter with the same index. Note that only the first 32
 * individual masks can be used as the Rx FIFO filter mask.
 *
 * param base FlexCAN peripheral base address.
 * param maskIdx The Index of individual Mask.
 * param mask Rx Individual Mask value.
 */
void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)

Please refer <flexcan_interrupt_transfer> demo, which located with ..\SDK_2.5.0_EVK-MIMXRT1020\boards\evkmimxrt1020\driver_examples\flexcan\interrupt_transfer  path for related API function application.

    /* Set Rx Masking mechanism. */
    FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));

Wish it helps.

best regards,

Mike

0 Kudos

34 Views
Contributor II

Thank you for the response.

After further investigation it seems what we are actually after is not possible to do with the hardware capabilities of the FlexCAN.

The scenario we want to cover:

On CAN Bus these messages are being sent:
ID 0x00000170
ID 0x00000171
ID 0x00000672
ID 0x00000978
ID 0x00000299

ID 0x00000472

...
ID 0x00000278
ID 0x00000199

We want to offload the MCU and only read some of these messages by letting the HW filter out 
So the HW should only accept the following IDs: 0x00000170, 0x00000171 and maybe 10 more.

Now in software the only messages I see available is 0x00000170, 0x00000171 and the other ones. The other messages is invisible because hardware did not accept them.

It seems the HW filtering can only cover ranges and that if we want to allow only 10 specific IDs we cannot do it. It this conclusion correct? And if it is what is the best way to offload heavy CAN traffic from the MCU?

Thank you.

0 Kudos

34 Views
Contributor II

Hi Fredik,

I read your query. I have already worked on FLEXCAN driver. 

As per my understanding, we can configure 64 different RX messages.   

By using below functions, you can configure those 64 message buffers with different id's,

 /* Set Rx Masking mechanism. */
FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));

void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)

"It seems the HW filtering can only cover ranges and that if we want to allow only 10 specific IDs we cannot do it. It this conclusion correct? And if it is what is the best way to offload heavy CAN traffic from the MCU?"

If you want to receive data from 10 different id's, then configure 10 RX message buffers with 10 different id's (whatever id's you required). 


Hope this will help you.

Regards,

Yashwanth.

0 Kudos

34 Views
NXP TechSupport
NXP TechSupport

Hi,

In fact, FlexCAN ID can be flexible, that means your could filter/ignore any ID bits.

You also can do test with Rx Mailboxes Global Mask Register to set related ID bits checked or not.

pastedImage_1.png

Wish it helps.

best regards,

Mike

0 Kudos