2021-07-07 12:40 PM
Hi, I am working with STM32F103 and configure CAN filter like this:
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_Start(&hcan) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
This uses only FIFO0 memory, correct? So I can receive only up to 3 messages at the same time, otherwise it would overflow?
Could I also use FIFO1 memory? To receive up to 6 messages at the same time?
How could I do that?
Solved! Go to Solution.
2021-07-07 01:49 PM
>> Or I dont understand something?
You attempt inject complexity where there isn't any?
Pretty sure it's a once and done thing, you're typically using an auto/local variable of limited life/scope
// Common initialization
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14; // Could be 28 if you're doing nothing with CAN2
sFilterConfig.FilterBank = 0;
// Init settings for First Filter
sFilterConfig.FilterIdHigh = ...;
sFilterConfig.FilterIdLow = ...;
sFilterConfig.FilterMaskIdHigh = ...;
sFilterConfig.FilterMaskIdLow = ...;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
sFilterConfig.FilterBank = 1;
// Init settings for Second Filter
sFilterConfig.FilterIdHigh = ...;
sFilterConfig.FilterIdLow = ...;
sFilterConfig.FilterMaskIdHigh = ...;
sFilterConfig.FilterMaskIdLow = ...;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
2021-07-07 12:54 PM
>>How could I do that?
Configure different filters to handle different subsets of the ID space, funnelling them into different FIFO's
You've basically created a single filter that takes everything and stuffs it in a single FIFO
You might want to optimize the code that you have consuming the FIFO content so it doesn't bottleneck in your processing code.
If you can't process the messages real-time, enqueue them in your own buffer management system, which you can make as deep as you need it.
2021-07-07 01:08 PM
@Community member
>>Configure different filters to handle different subsets of the ID space, funnelling them into different FIFO's
But one "CAN_HandleTypeDef hcan" can have only one filter "HAL_CAN_ConfigFilter(&hcan, &sFilterConfig)"?
Do I need to manually create second "CAN_HandleTypeDef hcan" object which would use same "hcan.Instance = CAN1" and other settings, the difference would be only "FilterFIFOAssignment = CAN_RX_FIFO1" and FilterMask/FilterId to handle different IDs? Also different banks? 0-14/15-29?
2021-07-07 01:18 PM
You could use one structure to initialize
sFilterConfig.FilterBank = 0; // Enumerate 0 thru 13 for CAN1, or change the slave split higher if not using/needing CAN2
Change the Filter ID/MASK to reflect the capturing window
Change the binning
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFOx;
Call once per filter you're adding
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
2021-07-07 01:36 PM
But wont assigning two filters to same "CAN_HandleTypeDef hcan" structure override each other?
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig1);
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig2);
This is the source code of "HAL_CAN_ConfigFilter" :
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
{
//...code skipped...
/* Filter FIFO assignment */
if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
{
/* FIFO 0 assignation for the filter */
CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
}
else
{
/* FIFO 1 assignation for the filter */
SET_BIT(can_ip->FFA1R, filternbrbitpos);
}
//...code skipped...
}
So setting different filters with different FIFO will override the same FFA1R value? Or I dont understand something?
Unless starting from different FilterBanks?
CAN_FilterTypeDef sFilterConfig1;
sFilterConfig1.FilterBank = 0;
sFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig1.FilterIdHigh = 0x0000; // will need to adjust
sFilterConfig1.FilterIdLow = 0x0000; // will need to adjust
sFilterConfig1.FilterMaskIdHigh = 0x0000; // will need to adjust
sFilterConfig1.FilterMaskIdLow = 0x0000; // will need to adjust
sFilterConfig1.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig1.FilterActivation = ENABLE;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig1) != HAL_OK)
{
Error_Handler();
}
CAN_FilterTypeDef sFilterConfig2;
sFilterConfig2.FilterBank = 14;
sFilterConfig2.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig2.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig2.FilterIdHigh = 0x0000; // will need to adjust
sFilterConfig2.FilterIdLow = 0x0000; // will need to adjust
sFilterConfig2.FilterMaskIdHigh = 0x0000; // will need to adjust
sFilterConfig2.FilterMaskIdLow = 0x0000; // will need to adjust
sFilterConfig2.FilterFIFOAssignment = CAN_RX_FIFO1;
sFilterConfig2.FilterActivation = ENABLE;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig2) != HAL_OK)
{
Error_Handler();
}
So then it would change different can_ip->FFA1R bit?
2021-07-07 01:49 PM
>> Or I dont understand something?
You attempt inject complexity where there isn't any?
Pretty sure it's a once and done thing, you're typically using an auto/local variable of limited life/scope
// Common initialization
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14; // Could be 28 if you're doing nothing with CAN2
sFilterConfig.FilterBank = 0;
// Init settings for First Filter
sFilterConfig.FilterIdHigh = ...;
sFilterConfig.FilterIdLow = ...;
sFilterConfig.FilterMaskIdHigh = ...;
sFilterConfig.FilterMaskIdLow = ...;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
sFilterConfig.FilterBank = 1;
// Init settings for Second Filter
sFilterConfig.FilterIdHigh = ...;
sFilterConfig.FilterIdLow = ...;
sFilterConfig.FilterMaskIdHigh = ...;
sFilterConfig.FilterMaskIdLow = ...;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
2021-07-07 02:10 PM
>>So setting different filters with different FIFO will override the same FFA1R value?
No, it's a bit vector with 28 positions (ON/OFF), the ownership split of CAN1 vs CAN2 is controlled by SlaveStartFilterBank
There are 28 FilterID/MASK registers, these should attempt to have different picks.
The filters can have overlap, but you're really trying to subdivide and prioritize a sub-set.
They are taken in ORDER, you should put your broadest, catch-all, filter as the last one.
2021-07-08 10:49 AM
@Community member
I want to catch all IDs or as many as possible. Splitting filters to odd and even IDs into FIFO0 and FIFO1 would give me better chance to catch all messages? (compared to my previous method catch all to FIFO0 only)
So with your help my could now looks like this:
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.SlaveStartFilterBank = 28;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
// odd IDs to FIFO0
sFilterConfig.FilterIdHigh = 0x00000020;
sFilterConfig.FilterIdLow = 0x00000000;
sFilterConfig.FilterMaskIdHigh = 0x00000020;
sFilterConfig.FilterMaskIdLow = 0x00000000;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
sFilterConfig.FilterBank = 1;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
// even IDs to FIFO1
sFilterConfig.FilterIdHigh = 0x00000000;
sFilterConfig.FilterIdLow = 0x00000000;
sFilterConfig.FilterMaskIdHigh = 0x00000020;
sFilterConfig.FilterMaskIdLow = 0x00000000;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_Start(&hcan) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
Did I get correct FilterIds and FilterMasks?