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 */
@@ -303,19 +311,69 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
303311 /* get default filter */
304312 for (int i = 0 ; i < filter_cfg -> count ; i ++ )
305313 {
306- drv_can -> FilterConfig .FilterBank = filter_cfg -> items [i ].hdr ;
307- drv_can -> FilterConfig .FilterIdHigh = (filter_cfg -> items [i ].id >> 13 ) & 0xFFFF ;
308- drv_can -> FilterConfig .FilterIdLow = ((filter_cfg -> items [i ].id << 3 ) |
309- (filter_cfg -> items [i ].ide << 2 ) |
310- (filter_cfg -> items [i ].rtr << 1 )) & 0xFFFF ;
311- drv_can -> FilterConfig .FilterMaskIdHigh = (filter_cfg -> items [i ].mask >> 16 ) & 0xFFFF ;
312- drv_can -> FilterConfig .FilterMaskIdLow = filter_cfg -> items [i ].mask & 0xFFFF ;
314+ if (filter_cfg -> items [i ].hdr == -1 )
315+ {
316+ drv_can -> FilterConfig .FilterBank = i ;
317+ }
318+ else
319+ {
320+ drv_can -> FilterConfig .FilterBank = filter_cfg -> items [i ].hdr ;
321+ }
322+ /**
323+ * ID | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
324+ * MASK | CAN_FxR2[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
325+ * STD ID | STID[10:3] | STDID[2:0] |<- 21bit ->|
326+ * EXT ID | EXTID[28:21] | EXTID[20:13] | EXTID[12:5] | EXTID[4:0] IDE RTR 0|
327+ * @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
328+ * -> but the id bit of struct rt_can_filter_item is 29,
329+ * -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
330+ * -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
331+ * -> FilterIdLow: ((STDid << 18) or (EXT id << 3)) & 0xFFFF.
332+ * @note the mask bit of struct rt_can_filter_item is 32,
333+ * -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF
334+ * -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF
335+ */
336+ if (filter_cfg -> items [i ].mode == CAN_FILTERMODE_IDMASK )
337+ {
338+ /* make sure the CAN_FxR1[2:0](IDE RTR) work */
339+ mask_l_tail = 0x06 ;
340+ }
341+ else if (filter_cfg -> items [i ].mode == CAN_FILTERMODE_IDLIST )
342+ {
343+ /* same as CAN_FxR1 */
344+ mask_l_tail = (filter_cfg -> items [i ].ide << 2 ) |
345+ (filter_cfg -> items [i ].rtr << 1 );
346+ }
347+ if (filter_cfg -> items [i ].ide == RT_CAN_STDID )
348+ {
349+ id_h = ((filter_cfg -> items [i ].id << 18 ) >> 13 ) & 0xFFFF ;
350+ id_l = ((filter_cfg -> items [i ].id << 18 ) |
351+ (filter_cfg -> items [i ].ide << 2 ) |
352+ (filter_cfg -> items [i ].rtr << 1 )) & 0xFFFF ;
353+ mask_h = ((filter_cfg -> items [i ].mask << 21 ) >> 16 ) & 0xFFFF ;
354+ mask_l = ((filter_cfg -> items [i ].mask << 21 ) | mask_l_tail ) & 0xFFFF ;
355+ }
356+ else if (filter_cfg -> items [i ].ide == RT_CAN_EXTID )
357+ {
358+ id_h = (filter_cfg -> items [i ].id >> 13 ) & 0xFFFF ;
359+ id_l = ((filter_cfg -> items [i ].id << 3 ) |
360+ (filter_cfg -> items [i ].ide << 2 ) |
361+ (filter_cfg -> items [i ].rtr << 1 )) & 0xFFFF ;
362+ mask_h = ((filter_cfg -> items [i ].mask << 3 ) >> 16 ) & 0xFFFF ;
363+ mask_l = ((filter_cfg -> items [i ].mask << 3 ) | mask_l_tail ) & 0xFFFF ;
364+ }
365+ drv_can -> FilterConfig .FilterIdHigh = id_h ;
366+ drv_can -> FilterConfig .FilterIdLow = id_l ;
367+ drv_can -> FilterConfig .FilterMaskIdHigh = mask_h ;
368+ drv_can -> FilterConfig .FilterMaskIdLow = mask_l ;
369+
313370 drv_can -> FilterConfig .FilterMode = filter_cfg -> items [i ].mode ;
314371 /* Filter conf */
315372 HAL_CAN_ConfigFilter (& drv_can -> CanHandle , & drv_can -> FilterConfig );
316373 }
317374 }
318375 break ;
376+ }
319377 case RT_CAN_CMD_SET_MODE :
320378 argval = (rt_uint32_t ) arg ;
321379 if (argval != RT_CAN_MODE_NORMAL &&
0 commit comments