CAN-Controller acceptance filtering with the SJA1000 (ESP32)

4

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?

c
filter
mask
can-bus
esp32
asked on Stack Overflow Jun 5, 2019 by Philipp Fu

2 Answers

1

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.

answered on Stack Overflow Jun 5, 2019 by David Collins
1

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.

answered on Stack Overflow Jun 5, 2019 by Gerhardh • edited Jun 7, 2019 by Gerhardh

User contributions licensed under CC BY-SA 3.0