cancel
Showing results for 
Search instead for 
Did you mean: 

Help with CAN filter on stm32f767

Vaclav Zajic
Associate II
Posted on April 12, 2018 at 10:21

Hello, I would like to be able to receive CAN message 0x200(CAN_ID_RX is 0x200) and I have a CAN filter configured like this:

sFilterConfig.FilterBank = 0;

sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterIdHigh = CAN_ID_RX << 5;

sFilterConfig.FilterIdLow = 0x0000;

sFilterConfig.FilterMaskIdHigh = 0x0000;;

sFilterConfig.FilterMaskIdLow = 0x0000;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.SlaveStartFilterBank = 14;

I don't receive any messages and by using debugger I found out that the function HAL_CAN_IRQHandler in stm32f7xx_hal_can.c is never called.

Can you help me?

Thanks 

Vaclav

#bxcan #can-filter #stm32f7
7 REPLIES 7
Vaclav Zajic
Associate II
Posted on April 12, 2018 at 14:36

I found it out. 

sFilterConfig.FilterMode must be set to 

CAN_FILTERMODE_IDMASK in my case. Vaclav

Ben K
Senior III
Posted on April 12, 2018 at 14:51

1. Are you using CAN2 by any chance? If so, make sure that sFilterConfig.FilterBank >= sFilterConfig.SlaveStartFilterBank.

2. Keep in mind that you are configuring a filter bank, therefore each field will be used as a filter, depending on which type you use. For 32 bit list mode 1 filter bank = 2 filters, for 16 bit list mode 1 filter bank = 4 filters. Therefore leaving those fields empty will result in receiving frames with ID = 0.

So here's the correct setting for only passing 0x200 (the filter bank numbering is left for you to correct):

sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh = CAN_ID_RX << 5;
sFilterConfig.FilterIdLow = CAN_ID_RX << 5;
sFilterConfig.FilterMaskIdHigh = CAN_ID_RX << 5;
sFilterConfig.FilterMaskIdLow = CAN_ID_RX << 5;�?�?�?�?�?�?

or using 32 bit mode:

sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = CAN_ID_RX << 5;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = CAN_ID_RX << 5;
sFilterConfig.FilterMaskIdLow = 0x0000;�?�?�?�?�?�?

Posted on April 12, 2018 at 16:04

I am using CAN1.

The filter setup is now:

FilterConfig.FilterBank = 0;

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterIdHigh = CAN_ID_RX << 5;

sFilterConfig.FilterIdLow = 0x0000;

sFilterConfig.FilterMaskIdHigh = CAN_ID_RX << 5;

sFilterConfig.FilterMaskIdLow = 0x0000;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.SlaveStartFilterBank = 14;

I put a breakpoint in function HAL_CAN_RxFifo0MsgPendingCallback.

When I sent a message with StdID lower than 0x200, the breakpoint is not reached and when the StdID is higher than 0x200, the breakpoint is reached.   

When the breakpoint is reached, value of StdID is still shown as 0 at the watch window.

Thanks for help  

Posted on April 16, 2018 at 14:06

Any ideas?

Posted on April 17, 2018 at 03:19

CAN filters take a bit of getting used to.  I believe your problem is this:

BenK gave you an example using IDList. 

The code you posted last is using the IDMask filter type.  For ID Mask mode, the message ID will get a bitwise AND performed with your ID mask.  The result will then be compared to your Filter ID.

In your case

ID mask= 0x200 = 0b1000000000

Therefore, the mask will 'check' the 10th bit of the message id.

Next, you have your Filter Id as 0x200, so the result of the  will be compared to 0b1000000000

If you think about this, any message id that meets 0b1xxxxxxxxx will pass your filter test, hence why messages less than 0x200 were rejected.  Messages over 0x200 will be accepted assuming bit 10 is set.

To see what messages will pass you filter, just use the following:

(MessageID & IDMask)==FilterID

Assuming you are using standard IDs, to fix your code, replace

sFilterConfig.FilterMaskIdHigh = CAN_ID_RX << 5;

with

sFilterConfig.FilterMaskIdHigh = 0b11111111111 << 5;

Now only message CAN_ID_RX (0x200) will be accepted.

Posted on April 17, 2018 at 08:50

Thank you, Kale,

it works(only message with ID 0x200 passes the filter) but do you know why the received message StdId is shown as 0 in the debugger?

Vaclav

Vaclav Zajic
Associate II
Posted on April 20, 2018 at 17:26

There was a problem with the USB to CAN interface setup. I mismatched StdID and ExtID in the program for sending and receiving messages. Everything works now. Vaclav