cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 CAN filter range of ID's

Smdeint
Associate III

Hello, I have a set of extended CAN ID's I need to pas the bxCAN filter. I looked at some examples where one ID is passed the filter, but could not figure out how to allow a set of ID's. If my understanding is correct the mask is used to determine which bits of the ID are important. How can I configure the filter so that I can pass a set of different ID's?

These are the ID's:

// 0x0CF00400
// 0x0CFD9200
// 0x18FEE500
// 0x18FEEE00
// 0x18FEEF00
// 0x18FEF200
// 0x18FEF700
// 0x18FEFC00

 

This is what my filter config looks like:

	can_fil.FilterBank = 0;
	can_fil.FilterMode = CAN_FILTERMODE_IDLIST;
	can_fil.FilterFIFOAssignment = CAN_RX_FIFO0;
	can_fil.FilterIdHigh = 0;
	can_fil.FilterIdLow = 0;
	can_fil.FilterMaskIdHigh = 0;
	can_fil.FilterMaskIdLow = 0;
	can_fil.FilterScale = CAN_FILTERSCALE_32BIT;
	can_fil.FilterActivation = ENABLE;
	can_fil.SlaveStartFilterBank = 13;

 

1 ACCEPTED SOLUTION

Accepted Solutions
SofLit
ST Employee

Hello,

I think for your case, ID mask is not suitable as there are many differences in your ID list mainly the first ones. But here you need to use ID list but you need more than one filter to configure. Each filter can set 2 IDs. So you need four 32-bit filters in your case.

This is an example of a filter configuring your first two IDs:

#define REMOTE_FRAME   0 /* If = 1 the frame should be a remote frame. If = 0 the frame will be a data frame */
#define EXTID          1 /* If = 0 the frame should be a frame with standard ID. If = 1 the frame should be a frame with extended ID */

#define ID1   0x0CF00400
#define ID2   0x0CFD9200

#define FILTER_ID    ((ID1 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))  // ID1 = 0x0CF00400 (FxFR1[31:0])
#define FILTER_MASK  ((ID2 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))  // ID2 = 0x0CFD9200 (FxFR2[31:0])
  
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = (FILTER_ID >> 16);          // Filter ID2 LSB   (FxFR2[0:15])
  sFilterConfig.FilterIdLow = (FILTER_ID & 0xFFFF);        // Filter ID1 LSB   (FxFR1[0:15])
  sFilterConfig.FilterMaskIdHigh = (FILTER_MASK >> 16);    // Filter ID2 MSB   (FxFR2[16:31])
  sFilterConfig.FilterMaskIdLow = (FILTER_MASK & 0xFFFF);  // Filter ID1 MSB   (FxFR1[16:31])

 

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.

View solution in original post

10 REPLIES 10
SofLit
ST Employee

Hello,

I think for your case, ID mask is not suitable as there are many differences in your ID list mainly the first ones. But here you need to use ID list but you need more than one filter to configure. Each filter can set 2 IDs. So you need four 32-bit filters in your case.

This is an example of a filter configuring your first two IDs:

#define REMOTE_FRAME   0 /* If = 1 the frame should be a remote frame. If = 0 the frame will be a data frame */
#define EXTID          1 /* If = 0 the frame should be a frame with standard ID. If = 1 the frame should be a frame with extended ID */

#define ID1   0x0CF00400
#define ID2   0x0CFD9200

#define FILTER_ID    ((ID1 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))  // ID1 = 0x0CF00400 (FxFR1[31:0])
#define FILTER_MASK  ((ID2 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))  // ID2 = 0x0CFD9200 (FxFR2[31:0])
  
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = (FILTER_ID >> 16);          // Filter ID2 LSB   (FxFR2[0:15])
  sFilterConfig.FilterIdLow = (FILTER_ID & 0xFFFF);        // Filter ID1 LSB   (FxFR1[0:15])
  sFilterConfig.FilterMaskIdHigh = (FILTER_MASK >> 16);    // Filter ID2 MSB   (FxFR2[16:31])
  sFilterConfig.FilterMaskIdLow = (FILTER_MASK & 0xFFFF);  // Filter ID1 MSB   (FxFR1[16:31])

 

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.

And how can I configure more filters at once? 

As I said using several filters.

For each filter (new filter configuration) you need to increment .FilterBank:

sFilterConfig.FilterBank = 0; -> filter number 0

sFilterConfig.FilterBank = 1; -> filter number 1

sFilterConfig.FilterBank = 2; -> filter number 2 etc ..

 

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.

I didn't understand it the first time. Now I understand and got it working. This is how I implemented it:

void CAN_filter_config(uint8_t filter_index, uint32_t ID, uint32_t MASK) {
	CAN_FilterTypeDef sFilter_config; // Create a new filter config structure for each call
	sFilter_config.FilterBank = filter_index;
	sFilter_config.FilterMode = CAN_FILTERMODE_IDLIST;
	sFilter_config.FilterScale = CAN_FILTERSCALE_32BIT;
	sFilter_config.FilterIdHigh = (ID >> 16);
	sFilter_config.FilterIdLow = (ID & 0xFFFF);
	sFilter_config.FilterMaskIdHigh = (MASK >> 16);
	sFilter_config.FilterMaskIdLow = (MASK & 0xFFFF);
	sFilter_config.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	sFilter_config.FilterActivation = ENABLE;

	if (HAL_CAN_ConfigFilter(&hcan, &sFilter_config) != HAL_OK) {
		CAN_error();
	}
}

 

Mask and ID filter

#define FILTER_ID1    		((ID1 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_MASK1  		((ID2 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))

#define FILTER_ID2    		((ID3 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_MASK2  		((ID4 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))

#define FILTER_ID3    		((ID5 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_MASK3  		((ID6 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))

#define FILTER_ID4    		((ID7 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_MASK4  		((ID8 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))

 

SofLit
ST Employee

Nice!

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.

But better balance the FIFO usage so the first 4 IDs will be received by FIFO0 and the second 4 IDs will be received by FIFO1. So let your API to select the FIFO number and add it as argument to your API to set this parameter:

FilterFIFOAssignment

 

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.

What difference does this make for receiving the ID's?

No difference in term of ID acceptance but the frame will be received by the FIFO of which the filter was assigned to. 

sFilter_config.FilterFIFOAssignment = CAN_FILTER_FIFO0; -> the frame will be received by FIFO0
sFilter_config.FilterFIFOAssignment = CAN_FILTER_FIFO1; -> the frame will be received by FIFO1

In your function you're forcing the FIFO to FIFO0 while you can also use FIFO1 to offload FIFO0.

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.

I tried adding more filters, because I need the following ID's: 

#define ID9					(0x18EAFF00U)
#define ID10				(0x18EEFF00U)
#define ID11				(0x18ECFF00U)
#define ID12				(0x18EBFF00U)

 

For this I added more filters:

#define FILTER_ID5    		((ID9 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_MASK5  		((ID10 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_ID6    		((ID11 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))
#define FILTER_MASK6  		((ID12 << 3) | (REMOTE_FRAME<<1) | (EXTID <<2))

 

This is how I call them:

  CAN_filter(0, FILTER_ID1, FILTER_MASK1, CAN_RX_FIFO0, &hcan);
  CAN_filter(1, FILTER_ID2, FILTER_MASK2, CAN_RX_FIFO0, &hcan);
  CAN_filter(2, FILTER_ID3, FILTER_MASK3, CAN_RX_FIFO1, &hcan);
  CAN_filter(3, FILTER_ID4, FILTER_MASK4, CAN_RX_FIFO1, &hcan);
  CAN_filter(4, FILTER_ID5, FILTER_MASK5, CAN_RX_FIFO1, &hcan);
  CAN_filter(5, FILTER_ID6, FILTER_MASK6, CAN_RX_FIFO1, &hcan);

 

I can still receive the ID's of the first 4 filters, but the 5th & 6th are not making it. Why can't I get the other filters to work?