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