Skip to content

Commit 9aec924

Browse files
authored
Merge pull request #28 from arduino/fix-can-filter
Fix CAN filtering: extended CAN IDs can smaller than 0x800 and still be an extended CAN ID
2 parents 11cd9bb + 3124379 commit 9aec924

File tree

2 files changed

+55
-73
lines changed

2 files changed

+55
-73
lines changed

include/can.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ extern "C" {
2828
* INCLUDE
2929
**************************************************************************************/
3030

31+
#include <stdbool.h>
3132
#include <inttypes.h>
3233

3334
#include "can_util.h"
@@ -43,14 +44,18 @@ extern "C" {
4344
* TYPEDEF
4445
**************************************************************************************/
4546

46-
typedef enum
47+
union x8h7_can_filter_message
4748
{
48-
CANStandard = 0,
49-
CANExtended = 1,
50-
CANAny = 2
51-
} CANFormat;
49+
struct __attribute__((packed))
50+
{
51+
uint32_t idx;
52+
uint32_t id;
53+
uint32_t mask;
54+
} field;
55+
uint8_t buf[sizeof(uint32_t) /* idx */ + sizeof(uint32_t) /* id */ + sizeof(uint32_t) /* mask */];
56+
};
5257

53-
union x8h7_can_message
58+
union x8h7_can_frame_message
5459
{
5560
struct __attribute__((packed))
5661
{
@@ -76,9 +81,9 @@ void can_handle_data();
7681
void can_init_device(FDCAN_HandleTypeDef * handle, CANName peripheral, CanNominalBitTimingResult const can_bit_timing);
7782
int can_frequency(FDCAN_HandleTypeDef * handle, uint32_t const can_bitrate);
7883

79-
void can_write(FDCAN_HandleTypeDef * handle, union x8h7_can_message const * msg);
80-
int can_read(FDCAN_HandleTypeDef * handle, union x8h7_can_message *msg);
81-
int can_filter(FDCAN_HandleTypeDef * handle, uint32_t id, uint32_t mask, CANFormat format, int32_t filter_index);
84+
void can_write(FDCAN_HandleTypeDef * handle, union x8h7_can_frame_message const * msg);
85+
int can_read(FDCAN_HandleTypeDef * handle, union x8h7_can_frame_message *msg);
86+
int can_filter(FDCAN_HandleTypeDef * handle, uint32_t const filter_index, uint32_t const id, uint32_t const mask, bool const is_extended_id);
8287
unsigned char can_rderror(FDCAN_HandleTypeDef * handle);
8388
unsigned char can_tderror(FDCAN_HandleTypeDef * handle);
8489

src/can.c

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -164,21 +164,21 @@ void fdcan1_handler(uint8_t opcode, uint8_t *data, uint16_t size) {
164164
}
165165
else if (opcode == CAN_FILTER)
166166
{
167-
uint32_t const * info = (uint32_t*)data;
168-
169-
uint32_t const handle = info[0];
170-
uint32_t const id = info[1];
171-
uint32_t const mask = info[2];
172-
173-
CANFormat const format = (id < 0x800) ? CANStandard : CANExtended;
174-
175-
if (!can_filter(&fdcan_1, id, mask, format, handle)) {
176-
dbg_printf("fdcan1_handler: can_filter failed for id: %ld, mask: %ld, format: %d, handle %ld\n", id, mask, format, handle);
167+
union x8h7_can_filter_message x8h7_msg;
168+
memcpy(x8h7_msg.buf, data, sizeof(x8h7_msg.buf));
169+
170+
if (!can_filter(&fdcan_1,
171+
x8h7_msg.field.idx,
172+
x8h7_msg.field.id,
173+
x8h7_msg.field.mask,
174+
x8h7_msg.field.id & CAN_EFF_FLAG))
175+
{
176+
dbg_printf("fdcan1_handler: can_filter failed for idx: %ld, id: %lX, mask: %lX\n", x8h7_msg.field.idx, x8h7_msg.field.id, x8h7_msg.field.mask);
177177
}
178178
}
179179
else if (opcode == CAN_TX_FRAME)
180180
{
181-
union x8h7_can_message msg;
181+
union x8h7_can_frame_message msg;
182182
memcpy(&msg, data, size);
183183

184184
dbg_printf("fdcan1_handler: sending CAN message to %x, size %d, content[0]=0x%02X\n", msg.id, msg.len, msg.data[0]);
@@ -199,21 +199,21 @@ void fdcan2_handler(uint8_t opcode, uint8_t *data, uint16_t size) {
199199
}
200200
else if (opcode == CAN_FILTER)
201201
{
202-
uint32_t const * info = (uint32_t*)data;
203-
204-
uint32_t const handle = info[0];
205-
uint32_t const id = info[1];
206-
uint32_t const mask = info[2];
207-
208-
CANFormat const format = (id < 0x800) ? CANStandard : CANExtended;
209-
210-
if (!can_filter(&fdcan_2, id, mask, format, handle)) {
211-
dbg_printf("fdcan2_handler: can_filter failed for id: %ld, mask: %ld, format: %d, handle %ld\n", id, mask, format, handle);
212-
}
202+
union x8h7_can_filter_message x8h7_msg;
203+
memcpy(x8h7_msg.buf, data, sizeof(x8h7_msg.buf));
204+
205+
if (!can_filter(&fdcan_2,
206+
x8h7_msg.field.idx,
207+
x8h7_msg.field.id,
208+
x8h7_msg.field.mask,
209+
x8h7_msg.field.id & CAN_EFF_FLAG))
210+
{
211+
dbg_printf("fdcan2_handler: can_filter failed for idx: %ld, id: %lX, mask: %lX\n", x8h7_msg.field.idx, x8h7_msg.field.id, x8h7_msg.field.mask);
212+
}
213213
}
214214
else if (opcode == CAN_TX_FRAME)
215215
{
216-
union x8h7_can_message msg;
216+
union x8h7_can_frame_message msg;
217217
memcpy(&msg, data, size);
218218

219219
dbg_printf("fdcan2_handler: sending CAN message to %x, size %d, content[0]=0x%02X\n", msg.id, msg.len, msg.data[0]);
@@ -253,7 +253,7 @@ void can_init()
253253

254254
void can_handle_data()
255255
{
256-
union x8h7_can_message msg;
256+
union x8h7_can_frame_message msg;
257257

258258
if (can_read(&fdcan_1, &msg)) {
259259
enqueue_packet(PERIPH_FDCAN1, DATA, sizeof(msg.buf), msg.buf);
@@ -276,11 +276,11 @@ int can_internal_init(FDCAN_HandleTypeDef * handle)
276276
error("HAL_FDCAN_Init error\n");
277277
}
278278

279-
if (can_filter(handle, 0, 0, CANStandard, 0) == 0) {
279+
if (can_filter(handle, 0, 0, 0, false) == 0) {
280280
error("can_filter error\n");
281281
}
282282

283-
if (can_filter(handle, 0, 0, CANExtended, 0) == 0) {
283+
if (can_filter(handle, 0, 0, 0, true) == 0) {
284284
error("can_filter error\n");
285285
}
286286

@@ -378,49 +378,26 @@ int can_frequency(FDCAN_HandleTypeDef * handle, uint32_t const can_bitrate)
378378
}
379379

380380

381-
/** Filter out incoming messages
382-
*
383-
* @param obj CAN object
384-
* @param id the id to filter on
385-
* @param mask the mask applied to the id
386-
* @param format format to filter on
387-
* @param handle message filter handle (not supported yet)
388-
*
389-
* @returns
390-
* 0 if filter change failed or unsupported,
391-
* new filter handle if successful (not supported yet => returns 1)
392-
*/
393-
int can_filter(FDCAN_HandleTypeDef * handle, uint32_t id, uint32_t mask, CANFormat format, int32_t filter_index)
381+
int can_filter(FDCAN_HandleTypeDef * handle, uint32_t const filter_index, uint32_t const id, uint32_t const mask, bool const is_extended_id)
394382
{
395-
FDCAN_FilterTypeDef sFilterConfig = {0};
396-
397-
if (format == CANStandard) {
398-
sFilterConfig.IdType = FDCAN_STANDARD_ID;
399-
sFilterConfig.FilterIndex = filter_index;
400-
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
401-
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
402-
sFilterConfig.FilterID1 = id;
403-
sFilterConfig.FilterID2 = mask;
404-
} else if (format == CANExtended) {
405-
sFilterConfig.IdType = FDCAN_EXTENDED_ID;
406-
sFilterConfig.FilterIndex = filter_index;
407-
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
408-
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
409-
sFilterConfig.FilterID1 = id;
410-
sFilterConfig.FilterID2 = mask;
411-
} else { // Filter for CANAny format cannot be configured for STM32
412-
return 0;
413-
}
383+
FDCAN_FilterTypeDef sFilterConfig = {0};
414384

415-
if (HAL_FDCAN_ConfigFilter(handle, &sFilterConfig) != HAL_OK) {
416-
return 0;
417-
}
385+
sFilterConfig.IdType = is_extended_id ? FDCAN_EXTENDED_ID : FDCAN_STANDARD_ID;
386+
sFilterConfig.FilterIndex = filter_index;
387+
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
388+
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
389+
sFilterConfig.FilterID1 = is_extended_id ? (id & CAN_EFF_MASK) : (id & CAN_SFF_MASK);
390+
sFilterConfig.FilterID2 = is_extended_id ? (mask & CAN_EFF_MASK) : (mask & CAN_SFF_MASK);
418391

419-
return 1;
392+
if (HAL_FDCAN_ConfigFilter(handle, &sFilterConfig) != HAL_OK) {
393+
return 0;
394+
}
395+
396+
return 1;
420397
}
421398

422399

423-
void can_write(FDCAN_HandleTypeDef * handle, union x8h7_can_message const * msg)
400+
void can_write(FDCAN_HandleTypeDef * handle, union x8h7_can_frame_message const * msg)
424401
{
425402
FDCAN_TxHeaderTypeDef TxHeader = {0};
426403

@@ -479,7 +456,7 @@ void can_write(FDCAN_HandleTypeDef * handle, union x8h7_can_message const * msg)
479456
}
480457
}
481458

482-
int can_read(FDCAN_HandleTypeDef * handle, union x8h7_can_message *msg)
459+
int can_read(FDCAN_HandleTypeDef * handle, union x8h7_can_frame_message *msg)
483460
{
484461
static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
485462

0 commit comments

Comments
 (0)