cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L433 CAN filtering using mask mode

agennart
Associate

Hello,

I am currently using a STM32l433 with the following configuration:

        CAN_FilterTypeDef  CAN_FilterInitStructure = {0};
        CAN_FilterInitStructure.FilterBank = filterNum;
        CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_16BIT;

        // 11-bits StdId left-aligned on the 32-bits word register
        CAN_FilterInitStructure.FilterIdHigh = id << 5;
        CAN_FilterInitStructure.FilterIdLow = 0;
        CAN_FilterInitStructure.FilterMaskIdHigh = mask << 5;
        CAN_FilterInitStructure.FilterMaskIdLow = 0;

        CAN_FilterInitStructure.FilterFIFOAssignment = CAN_FILTER_FIFO0;
        CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK;

 

It globally works. So if my ID is 0x701 and my mask 0xFFFF, the callback will be called for every message ID 0x701.

However, when I change the mask, for exaple to a value like 0x700, in order to only get the '7' from the standard ID, my callback is not called for every message with ID 0x7__.

I also notice the that the 16bit filter lenght require the RTR, IDE and EXID (see picture below). In my case everything is set to 0. Could it be those settings are wrong ?

 

Could it be that there is something wrong with the configuration that makes the mask invalid ?

Any help is appreciated !

Thanks

agennart_0-1744871209560.png

 

10 REPLIES 10
mƎALLEm
ST Employee

Hello,

I'm not sure what are you planning to do but if a bit in the mask is set to1 that means the filter must accept the corresponding value if the bit set in the ID.

For example, if the ID = 0x701 and the MASK = 0xFFF, this means that only the 0x701 ID will be accepted by the filter.

If you need all the IDs: from 0x700 to 0x7FF to be accepted you need to set the MASK ID = 0xF00.

0 in the Mask ID means don't care.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
agennart
Associate

Hello,

Thank you for your answer. It confirms that I understood correctly how masks were working for CAN in STM32.

However, with ID 0x700 and mask 0xF00, I only receive CAN message for ID 0x700. It looks like there is something else wrong with my configuration.

Is there any other reason that could make the mask to be ignored ?

Best regards,

Antoine


@agennart wrote:

However, with ID 0x700 and mask 0xF00, I only receive CAN message for ID 0x700. It looks like there is something else wrong with my configuration.


Please provide the filter configuration in this situation.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Here is my filter configuration (it was already present in my initial question)

        CAN_FilterTypeDef  CAN_FilterInitStructure = {0};
        CAN_FilterInitStructure.FilterBank = filterNum;
        CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_16BIT;

        // 11-bits StdId left-aligned on the 32-bits word register
        CAN_FilterInitStructure.FilterIdHigh = id << 5;
        CAN_FilterInitStructure.FilterIdLow = 0;
        CAN_FilterInitStructure.FilterMaskIdHigh = mask << 5;
        CAN_FilterInitStructure.FilterMaskIdLow = 0;

        CAN_FilterInitStructure.FilterFIFOAssignment = CAN_FILTER_FIFO0;
        CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK;

Avoid using variables (id and mask) for the moment and fix the values.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello,

In 16-bit filter, try this configuration:

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    sFilterConfig.FilterIdHigh = 0x0700<<5;
    sFilterConfig.FilterIdLow = 0x0700<<5;
    sFilterConfig.FilterMaskIdHigh = 0x0F00<<5;
    sFilterConfig.FilterMaskIdLow = 0x0F00<<5;

In fact in 16 bit mode you have two batch of filter configs:

- One is set in the High part and another in the Low part. For example we can set this configuration to receive all the IDs from 0x700 to 0x7FF and one from the ID = 0x300:

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    sFilterConfig.FilterIdHigh = 0x0700<<5;
    sFilterConfig.FilterIdLow = 0x0300<<5;
    sFilterConfig.FilterMaskIdHigh = 0x0F00<<5;
    sFilterConfig.FilterMaskIdLow = 0x0FFF<<5;

Otherwise, you can use 32-bit filter for one batch of ID filter:

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0700<<5;
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0F00<<5;
    sFilterConfig.FilterMaskIdLow = 0x0000;

Regarding your question:

"I also notice the that the 16bit filter lenght require the RTR, IDE and EXID (see picture below). In my case everything is set to 0. Could it be those settings are wrong ?"

In the filter configuration we shift left by 5, so only the ID itself is impacted and all type pf frames RTR, and extended could be accepted by the filter. If you need to be more selective you need to set their bits according to the figure you shared.

Hope that I've answered your question.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello,

I tried two different configurations, and for both configuration, the behavior is different than expected.

 

1. ID mask + 16bit

 

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    sFilterConfig.FilterIdHigh = 0x0702<<5;
    sFilterConfig.FilterIdLow = 0;
    sFilterConfig.FilterMaskIdHigh = 0x704<<5;
    sFilterConfig.FilterMaskIdLow = 0;

Exepected filter: Receive messages with ID 0x702, 0x701, 0x700 (non exhaustive)
Actual filter: Receive only messages with ID 0x702

2. ID list + 16 bit

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    sFilterConfig.FilterIdHigh = 0x0702<<5;
    sFilterConfig.FilterIdLow = 0;
    sFilterConfig.FilterMaskIdHigh = 0x704<<5;
    sFilterConfig.FilterMaskIdLow = 0;

Expected filter: Receive message with ID 0x702, 0x704

Actual filter: Receive only message with ID 0x702

 

Do you have any idea of what am I missing ?

Is there something to enable in STMCubeMx for the CAN filtering method to work as expected ?

Best regards,

Antoine

 

Now your configuration is in ID List mode for both:

sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;

What is the status of the previous configuration/question (mask mode)? Did you test my configuration or not? 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
agennart
Associate

Sorry for the typo, the first test was indeed in mask mode

1. ID mask + 16bit

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    sFilterConfig.FilterIdHigh = 0x0702<<5;
    sFilterConfig.FilterIdLow = 0;
    sFilterConfig.FilterMaskIdHigh = 0x704<<5;
    sFilterConfig.FilterMaskIdLow = 0;

 Expected filter: receiving message with ID 0x702, 0x701, 0x700 (not exhaustive)
 Actual filter: only receive message with ID 0x702

 

And yes, I also tested you configuration:

    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    sFilterConfig.FilterIdHigh = 0x0700<<5;
    sFilterConfig.FilterIdLow = 0x0700<<5;
    sFilterConfig.FilterMaskIdHigh = 0x0F00<<5;
    sFilterConfig.FilterMaskIdLow = 0x0F00<<5;

Expected filter: ID 0x700, 0x701, 0x702, ....

Actual filter: ID 0x700 only