I'm try to use the acceptance filter from the SJA1000 CAN-Controller on a ESP23. The Messages should be filtered in a defined area (e.g. Arbitration ID from: 0x30 to: 0x35).
Example for filtering a single message (0x30):
#define CAN_FILTER_CONFIG_ACCEPT() {.acceptance_code = 0x1500000, .acceptance_mask = 0xffffff, .single_filter = true}
If I want to filter a defined area (0x30 - 0x35):
int calc_mask(int startID, int endID) {
int size_of_range = endID - startID;
unsigned int acceptance_mask = 0xFFFFFFFF;
int i;
for (i = startID; i <= endID; i++ {
acceptance_mask = ~(acceptance_mask & i);
}
return acceptance_mask;
}
acceptance_code = 0x30;
acceptance_mask = calc_mask(0x30, 0x35);
0x30 : 110000
NAND 0x31: 110001
NAND 0x32: 110010
NAND 0x33: 110011
NAND 0x34: 110100
NAND 0x35: 110101
0xF : 001111
acceptance_code = 0x6000000: 0000 0110 0000 0000 0000 0000 0000 0000
acceptance_mask = 0x1FFFFFF: 0000 0001 1111 1111 1111 1111 1111 1111
filtered Messages:
wanted:
14:21:17.754 -> CAN Message: 30 110000
14:21:17.754 -> CAN Message: 31 110001
14:21:17.787 -> CAN Message: 32 110010
14:21:17.787 -> CAN Message: 33 110011
14:21:17.787 -> CAN Message: 34 110100
14:21:17.821 -> CAN Message: 35 110101
unwanted:
14:21:17.821 -> CAN Message: 36 110110
14:21:17.821 -> CAN Message: 37 110111
14:21:17.855 -> CAN Message: 38 111000
14:21:17.855 -> CAN Message: 39 111001
14:21:17.855 -> CAN Message: 3A 111010
14:21:17.889 -> CAN Message: 3B 111011
14:21:17.889 -> CAN Message: 3C 111100
14:21:17.889 -> CAN Message: 3D 111101
14:21:17.923 -> CAN Message: 3E 111110
14:21:17.923 -> CAN Message: 3F 111111
Documentation ESP32 CAN-Controller (Acceptance Filter):
https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/can.html#acceptance-filter
Documentation SJA1000 CAN-Controller (6.4.15 Acceptance filter): https://www.nxp.com/docs/en/data-sheet/SJA1000.pdf
Does anyone have an idea how to get the not wanted Messages filtered?
It seems to me that what you are trying to achieve is not possible if you are using a single filter. For example, you could define
.acceptance_code = 0x30,
.acceptance_mask = 0x03,
This would accept IDs in the range 0x30 to 0x33 - but exclude 0x34 and 0x35.
On the other hand, with acceptance code = 0x34
and acceptance mask = 0x01
you would be allowing 0x34 and 0x35 - but excluding 0x30 - 0x33.
I notice that the acceptance filter can be placed in a dual filter mode, however - with the proviso that it can not be used to filter an extended ID. Maybe this will allow you to define complementary filters as defined above.
You probably cannot filter all unwanted messages. But you can narrow down a bit. For a suitable mask you must treat the ones and the zeros separately.
uint32 mask_ones = mask_zeros = ~0;
for (int id = startId; id < endId; id++)
{
mask_ones &= id;
mask_zeros &= ~id;
}
uint32 mask = mask_ones | mask_zeroes;
uint32 value = startId & mask;
This creates a mask which includes all bits that are set to 1 in every allowed value and also all bits that are set to 0 in every allowed value.
This should get rid of all values above 0x37
.
Example:
ones = zeros = 11111111
CAN Message: 30 110000 => mask_ones = 00110000; mask_zeros = 11001111
CAN Message: 31 110001 => mask_ones = 00110000; mask_zeros = 11001110
CAN Message: 32 110010 => mask_ones = 00110000; mask_zeros = 11001100
CAN Message: 33 110011 => mask_ones = 00110000; mask_zeros = 11001100
CAN Message: 34 110100 => mask_ones = 00110000; mask_zeros = 11001000
CAN Message: 35 110101 => mask_ones = 00110000; mask_zeros = 11001000
unwanted:
CAN Message: 36 110110
CAN Message: 37 110111
CAN Message: 38 111000
mask = 00110000 | 11001000 = 11111000 = 0xF8
value = 00110000 & 11111000 = 00110000 = 0x30
Update: The calculation above was broken. Fixed it.
User contributions licensed under CC BY-SA 3.0