AnsweredAssumed Answered

STM32F0 bxCan Filters

Question asked by Artur Vieira on Mar 24, 2018
Latest reply on Mar 25, 2018 by Artur Vieira

Hello

 

Today i was playing around with the bxCan module in a NUCLEO-F091RC, and trying to understand how the filter works.

 

After rading some posts here in the forum i was able to understand the concept of ID and MASK, but while making some experiments i am having some problems.

 

As an example i was trying to setup filters to only accept CAN messages with ID '0x651' or ID between '0x7E8' and '0x7EF' and this was my code:

 

   CAN_FilterInitStructure.CAN_FilterNumber = 0;
   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
   CAN_FilterInitStructure.CAN_FilterIdLow = (0x7E8 << 5);
   CAN_FilterInitStructure.CAN_FilterIdHigh = (0x651 << 5);
   CAN_FilterInitStructure.CAN_FilterMaskIdLow = (0x7F8 << 5);
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (0x7FF << 5);
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
   CAN_FilterInit(&CAN_FilterInitStructure);

 

But nothing was being received (i am using a 'CANDOISO' device to simulate messages in the CAN BUS). The CANDOISO device is working, if i don't have any filters configured (or configure a MASK and ID as '0') i am able to receive messages.

 

The only way for it to work, was to modify the way the registers related to the filters are loaded, i had to change the ST provided driver from:

/* First 16-bit identifier and First 16-bit mask */
/* Or First 16-bit identifier and Second 16-bit identifier */
CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
     ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |
     (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);

/* Second 16-bit identifier and Second 16-bit mask */
/* Or Third 16-bit identifier and Fourth 16-bit identifier */
CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = ((0x0000FFFF & (uint32_t) CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16)
        | (0x0000FFFF & (uint32_t) CAN_FilterInitStruct->CAN_FilterIdHigh);

to:

/* First 16-bit identifier and First 16-bit mask */
    /* Or First 16-bit identifier and Second 16-bit identifier */
CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
        (0x0000FFFF & (uint32_t) CAN_FilterInitStruct->CAN_FilterMaskIdLow)
        | ((0x0000FFFF & (uint32_t) CAN_FilterInitStruct->CAN_FilterIdLow) << 16);

/* Second 16-bit identifier and Second 16-bit mask */
    /* Or Third 16-bit identifier and Fourth 16-bit identifier */
CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
        (0x0000FFFF & (uint32_t) CAN_FilterInitStruct->CAN_FilterMaskIdHigh)
         | ((0x0000FFFF & (uint32_t) CAN_FilterInitStruct->CAN_FilterIdHigh) << 16);

Basically switching the position of the Filter ID and Mask in the registers, that is going against what is states in the reference manual (section 29.7.4 Figure 315).

 

For using the filter in 16 bit mode the code at the moment with this modification is working, but i really need to have filters working for CAN 29 bit ID, and for this mode (using the filter in 32Bit mode) it is not working, even if i change the order of WORDs in the configuration registers.

 

This is the configuration i am trying to load in the case of 29 bit ID's (the goal is to only accepts ID 0x--FEEE--)

 

   CAN_FilterInitStructure.CAN_FilterNumber = 0;
   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
   CAN_FilterInitStructure.CAN_FilterIdHigh = ((0x00FEEE00) & 0x7FF) << 5;
   CAN_FilterInitStructure.CAN_FilterIdHigh |= (((0x00FEEE00) & 0x1F000000) >> 24);
   CAN_FilterInitStructure.CAN_FilterIdLow = (0x00FEEE00 & 0x00FF0000) >> 8;
   CAN_FilterInitStructure.CAN_FilterIdLow |= ((0x00FEEE00 & 0x0000F800) >> 8);
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = ((0x00FFFF00) & 0x7FF) << 5;
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh |= (((0x00FFFF00) & 0x1F000000) >> 24);
   CAN_FilterInitStructure.CAN_FilterMaskIdLow = (0x00FFFF00 & 0x00FF0000) >> 8;
   CAN_FilterInitStructure.CAN_FilterMaskIdLow |= ((0x00FFFF00 & 0x0000F800) >> 8);
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

 

I am using the SPL (v1.5.0) but i have checked the code in HAL v1.9.0 and the code for the filters setup is mostly the same, the same for the F4 family (was the other HAL library i had on the PC at the moment).

 

Any feedback is appreciated..

 

Artur

Outcomes