Skip to content

Commit 9c811b1

Browse files
committed
修复滤波设置问题,根据标志帧和扩展帧判别所需位移,根据滤波模式判别CAN_FxR2[3:0]设置。
1 parent 69a347f commit 9c811b1

File tree

1 file changed

+69
-7
lines changed

1 file changed

+69
-7
lines changed

bsp/stm32/libraries/HAL_Drivers/drv_can.c

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* fix bug.port to BSP [stm32]
1212
* 2019-03-27 YLZ support double can channels, support stm32F4xx (only Legacy mode).
1313
* 2019-06-17 YLZ port to new STM32F1xx HAL V1.1.3.
14+
* 2021-02-02 YuZhe XU fix bug in filter config
1415
*/
1516

1617
#include "drv_can.h"
@@ -292,6 +293,13 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
292293
}
293294
break;
294295
case RT_CAN_CMD_SET_FILTER:
296+
{
297+
rt_uint32_t id_h = 0;
298+
rt_uint32_t id_l = 0;
299+
rt_uint32_t mask_h = 0;
300+
rt_uint32_t mask_l = 0;
301+
rt_uint32_t mask_l_tail = 0; //CAN_FxR2 bit [2:0]
302+
295303
if (RT_NULL == arg)
296304
{
297305
/* default filter config */
@@ -311,19 +319,73 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
311319
{
312320
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
313321
}
314-
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
315-
drv_can->FilterConfig.FilterIdHigh = (filter_cfg->items[i].id >> 13) & 0xFFFF;
316-
drv_can->FilterConfig.FilterIdLow = ((filter_cfg->items[i].id << 3) |
317-
(filter_cfg->items[i].ide << 2) |
318-
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
319-
drv_can->FilterConfig.FilterMaskIdHigh = (filter_cfg->items[i].mask >> 16) & 0xFFFF;
320-
drv_can->FilterConfig.FilterMaskIdLow = filter_cfg->items[i].mask & 0xFFFF;
322+
/**
323+
* struct rt_can_filter_item {
324+
* rt_uint32_t id : 29; // 报文 ID
325+
* rt_uint32_t ide : 1; // 扩展帧标识位
326+
* rt_uint32_t rtr : 1; // 远程帧标识位
327+
* rt_uint32_t mode : 1; // 过滤表模式
328+
* rt_uint32_t mask; // ID 掩码,0 表示对应的位不关心,1 表示对应的位必须匹配
329+
* rt_int32_t hdr; // -1 表示不指定过滤表号,对应的过滤表控制块也不会被初始化,正数为过滤表号,对应的过滤表控制块会被初始化
330+
* #ifdef RT_CAN_USING_HDR // 过滤表回调函数
331+
* rt_err_t (*ind)(rt_device_t dev, void *args , rt_int32_t hdr, rt_size_t size); // 回调函数参数
332+
* void *args;
333+
* #endif
334+
* };
335+
* ID | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
336+
* MASK | CAN_FxR2[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
337+
* STD ID | STID[10:3] | STDID[2:0] |<- 21bit ->|
338+
* EXT ID | EXTID[28:21] | EXTID[20:13] | EXTID[12:5] | EXTID[4:0] IDE RTR 0|
339+
* @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
340+
* -> but the id bit of struct rt_can_filter_item is 29,
341+
* -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
342+
* -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
343+
* -> FilterIdLow: ((STDid << 18) or (EXT id << 3)) & 0xFFFF.
344+
* @note the mask bit of struct rt_can_filter_item is 32,
345+
* -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF
346+
* -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF
347+
*/
348+
if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDMASK)
349+
{
350+
/* make sure the CAN_FxR1[2:0](IDE RTR) work */
351+
mask_l_tail = 0x06;
352+
}
353+
else if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDLIST)
354+
{
355+
/* same as CAN_FxR1 */
356+
mask_l_tail = (filter_cfg->items[i].ide << 2) |
357+
(filter_cfg->items[i].rtr << 1);
358+
}
359+
if (filter_cfg->items[i].ide == RT_CAN_STDID)
360+
{
361+
id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
362+
id_l = ((filter_cfg->items[i].id << 18) |
363+
(filter_cfg->items[i].ide << 2) |
364+
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
365+
mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
366+
mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
367+
}
368+
else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
369+
{
370+
id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
371+
id_l = ((filter_cfg->items[i].id << 3) |
372+
(filter_cfg->items[i].ide << 2) |
373+
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
374+
mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
375+
mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
376+
}
377+
drv_can->FilterConfig.FilterIdHigh = id_h;
378+
drv_can->FilterConfig.FilterIdLow = id_l;
379+
drv_can->FilterConfig.FilterMaskIdHigh = mask_h;
380+
drv_can->FilterConfig.FilterMaskIdLow = mask_l;
381+
321382
drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
322383
/* Filter conf */
323384
HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
324385
}
325386
}
326387
break;
388+
}
327389
case RT_CAN_CMD_SET_MODE:
328390
argval = (rt_uint32_t) arg;
329391
if (argval != RT_CAN_MODE_NORMAL &&

0 commit comments

Comments
 (0)