Skip to main content
Visitor II
April 17, 2025
Solved

STM32L433 CAN filtering using mask mode

  • April 17, 2025
  • 3 replies
  • 1227 views

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

 

    This topic has been closed for replies.
    Best answer by mƎALLEm

    I don't know how you are receiving only 0x702 with this filter config:

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

    With this config you will receive all the IDs from 0x000 to 0x7FF because you have the second configuration is set to 0 for a 16-bit filter:

    sFilterConfig.FilterMaskIdHigh = 0;
    sFilterConfig.FilterMaskIdLow = 0;

    I'm suspecting something in your code. If you have other filter configs please remove them and keep only this one:

     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;

    With this config you will receive only the IDs from 0x700 to 0x7FF. Use loopback mode if it was not the case.

    3 replies

    Technical Moderator
    April 21, 2025

    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.

    agennartAuthor
    Visitor II
    April 22, 2025

    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

    Technical Moderator
    April 22, 2025

    @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.

    agennartAuthor
    Visitor II
    April 22, 2025

    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;
    agennartAuthor
    Visitor II
    April 22, 2025

    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

    mƎALLEmAnswer
    Technical Moderator
    April 22, 2025

    I don't know how you are receiving only 0x702 with this filter config:

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

    With this config you will receive all the IDs from 0x000 to 0x7FF because you have the second configuration is set to 0 for a 16-bit filter:

    sFilterConfig.FilterMaskIdHigh = 0;
    sFilterConfig.FilterMaskIdLow = 0;

    I'm suspecting something in your code. If you have other filter configs please remove them and keep only this one:

     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;

    With this config you will receive only the IDs from 0x700 to 0x7FF. Use loopback mode if it was not the case.