FeraTaTa
FeraTaTa

Reputation: 31

How to configure my CAN filter in list mode?

I have written some code to transmit/receive CAN messages and I am having some issues with my filter. Firstly I'm going to say that I understand mask mode and have managed to get it working with the following configuration:

uint16_t id = 0x12; // 0001 0010
uint16_t mask = 0xFC; // 1111 1100

sFilterConfig.FilterBank=0;
sFilterConfig.FilterMode=CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale=CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh=id<<5;
sFilterConfig.FilterIdLow=0;
sFilterConfig.FilterMaskIdHigh=mask<<5;
sFilterConfig.FilterMaskIdLow=0;
sFilterConfig.FilterFIFOAssignment=0;
sFilterConfig.FilterActivation=ENABLE;

HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);

This accepts messages with ID 0x1X, where X is 0 to 3. I don't really understand the purpose of the final 2 bits of the ID since they are irrelevant to the mask, is my thinking there correct? Anyway that's not the main issue.

Now having read through RM0090 I'm trying to build a filter that will accept messages with ID 0x120 to 0x1FA with the below code:

uint16_t id = 0x120; // 0001 0010 0000
uint16_t mask = 0x1FA; // 0001 1111 1010

sFilterConfig.FilterBank=0;
sFilterConfig.FilterMode=CAN_FILTERMODE_IDLIST;
sFilterConfig.FilterScale=CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh=mask<<5;
sFilterConfig.FilterIdLow=id<<5;
sFilterConfig.FilterMaskIdHigh=0;//mask<<5;
sFilterConfig.FilterMaskIdLow=0;
sFilterConfig.FilterFIFOAssignment=0;
sFilterConfig.FilterActivation=ENABLE;

HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);

It doesn't work as expected, it only seems to accept IDs 0x120 and 0x00, is my understanding of list mode incorrect or my filter implementation? or both?

EDIT:

My understanding of Mask/List mode was wrong. I understand how to use masks but I thought list mode can be used to create a range of acceptable IDs but it seems that you can only use list mode to capture a couple specific IDs. I found this page quite helpful.

As the page I linked above says you can only get ranges in the form 2^N - (2^(N-1) - 1).

My question now becomes what is the point of Mask low/high and filterID low/high? Initially I thought maybe its the lower/higher 16 bits of the 32 bit register but each low/high variable is already uint32 so that idea didn't make sense to me. Any clarity will be appreciated.

Cheers!

Upvotes: 3

Views: 3304

Answers (1)

Mike
Mike

Reputation: 4288

I guess you are mixing filter and mask: The filter mask is used to determine which bits in the identifier of the received frame are compared with the filter

If a mask bit is set to a zero, the corresponding ID bit will automatically be accepted, regardless of the value of the filter bit.

If a mask bit is set to a one, the corresponding ID bit will be compare with the value of the filter bit; if they match it is accepted otherwise the frame is rejected.

Upvotes: 1

Related Questions