CAN ID hardware acceptance filtering
Posted: Fri Feb 26, 2021 3:35 pm
I'm having issues correctly setting the CAN acceptance filter to accept only messages with a particular ID.
Say for example, I want to set the CAN controller to only accept messages with an ID of 0x10 (that's 0b000 0001 0000 as an 11 bit CAN ID). My understanding of the documentation (particularly the "Multiple ID Filter Configuration" section) suggests that I would need to build my can_filter_config_t used in can_driver_install() as below.
However, this results in the CAN controller not accepting messages with any ID that I've tried, including 0x10.
I've tried a number of options for the mask, each with no success.
Based on acceptance_mask and acceptance_code both being uint32_ts I tried left padding the mask with 1s so that the mask should allow any value in the bits outside of the ID range, but still care about the 11 bits of ID itself.
This again results in the CAN controller not accepting messages with any ID that I've tried, including 0x10.
I then tried right padding the mask instead (which would make more sense to me than left padding based on the format of a CAN message)
This results in the CAN controller accepting messages with the ID 0x10, but also accepting all other messages I tried! Close, but still not right...
Finally, just to check my understanding of the mask, I tried using
As expected, this accepts all messages regardless of ID.
Any pointers on what I might be missing here? I don't know what to try next!
Otherwise I'm stuck wasting clock cycles on software filtering...
Say for example, I want to set the CAN controller to only accept messages with an ID of 0x10 (that's 0b000 0001 0000 as an 11 bit CAN ID). My understanding of the documentation (particularly the "Multiple ID Filter Configuration" section) suggests that I would need to build my can_filter_config_t used in can_driver_install() as below.
Code: Select all
can_filter_config_t fConfig = {
.acceptance_code = 0b00000010000, //0x10
.acceptance_mask = 0, //For a perfect match (aka no 'don't care' bits)
.single_filter = true,
};
I've tried a number of options for the mask, each with no success.
Based on acceptance_mask and acceptance_code both being uint32_ts I tried left padding the mask with 1s so that the mask should allow any value in the bits outside of the ID range, but still care about the 11 bits of ID itself.
Code: Select all
.acceptance_mask = 0b11111111111111111111100000000000
This again results in the CAN controller not accepting messages with any ID that I've tried, including 0x10.
I then tried right padding the mask instead (which would make more sense to me than left padding based on the format of a CAN message)
Code: Select all
.acceptance_mask = 0b00000000000111111111111111111111
Finally, just to check my understanding of the mask, I tried using
Code: Select all
.acceptance_mask = 0b11111111111111111111111111111111
Any pointers on what I might be missing here? I don't know what to try next!
Otherwise I'm stuck wasting clock cycles on software filtering...