Приемная фильтрация CAN-контроллера с помощью SJA1000 (ESP32) - PullRequest
4 голосов
/ 05 июня 2019

Я пытаюсь использовать фильтр приема от CAN-контроллера SJA1000 на ESP23.Сообщения должны быть отфильтрованы в определенной области (например, идентификатор арбитража от: 0x30 до: 0x35).

Пример фильтрации одного сообщения (0x30):

#define CAN_FILTER_CONFIG_ACCEPT()  {.acceptance_code = 0x1500000, .acceptance_mask = 0xffffff, .single_filter = true}

Если я хочуфильтровать определенную область (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
NAND0x34: 110100
NAND 0x35: 110101
0xF: 001111
коды_приемки = 0x6000000: 0000 0110 0000 0000 0000 0000 0000
маска_приемки = 0x1FFFFFF: 0000 0001 1111 1111 1111 1111 1111 1111

отфильтрованные сообщения:
требуемый:
14: 21: 17.754 -> CAN сообщение: 30 110000
14: 21: 17.754 -> CAN сообщение: 31 110001
14:21:17.787 -> Сообщение CAN: 32 110010
14: 21: 17.787 -> Сообщение CAN: 33 110011
14: 21: 17.787 -> Сообщение CAN: 34 110100
14: 21: 17.821 -> Сообщение CAN: 35 110101
нежелательные:
14: 21: 17.821 -> сообщение CAN: 36 110110
14: 21: 17.821 -> сообщение CAN: 37 110111
14: 21: 17,855 -> CСообщение AN: 38 111000
14: 21: 17.855 -> Сообщение CAN: 39 111001
14: 21: 17.855 -> Сообщение CAN: 3A 111010
14: 21: 17.889 -> Сообщение CAN: 3B 111011
14: 21: 17.889 -> Сообщение CAN: 3C 111100
14: 21: 17.889 -> Сообщение CAN: 3D 111101
14: 21: 17.923 -> Сообщение CAN: 3E 111110
14:21: 17.923 -> Сообщение CAN: 3F 111111

Документация CAN-контроллер ESP32 (фильтр приемки):
https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/can.html#acceptance-filter

Документация CAN-контроллер SJA1000 (6.4.15 фильтр приемки): https://www.nxp.com/docs/en/data-sheet/SJA1000.pdf

У кого-нибудь есть идеи, как отфильтровать ненужные сообщения?

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Возможно, вы не можете отфильтровать все нежелательные сообщения. Но вы можете немного сузить. Для подходящей маски вы должны обращаться с единицами и нулями отдельно.

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;

Это создает маску, которая включает все биты, которые установлены в 1 в каждом разрешенном значении, а также все биты, которые установлены в 0 в каждом допустимом значении. Это должно избавить от всех значений выше 0x37.

Пример:

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

Обновление: Расчет выше был нарушен. Исправлено.

1 голос
/ 05 июня 2019

Мне кажется, что то, что вы пытаетесь достичь, невозможно, если вы используете один фильтр. Например, вы можете определить

   .acceptance_code = 0x30,
   .acceptance_mask = 0x03,

Это позволило бы принимать идентификаторы в диапазоне от 0x30 до 0x33, но исключать 0x34 и 0x35.

С другой стороны, с acceptance code = 0x34 и acceptance mask = 0x01 вы могли бы разрешить 0x34 и 0x35 - но исключая 0x30 - 0x33.

Я заметил, что приемный фильтр можно перевести в режим фильтра dual , однако, при условии, что его нельзя использовать для фильтрации расширенного идентификатора. Может быть, это позволит вам определить дополнительные фильтры, как определено выше.

...