Browse Source

修复滤波设置问题,根据标志帧和扩展帧判别所需位移,根据滤波模式判别CAN_FxR2[3:0]设置。

cosmo 4 years ago
parent
commit
9c811b19ba
1 changed files with 69 additions and 7 deletions
  1. 69 7
      bsp/stm32/libraries/HAL_Drivers/drv_can.c

+ 69 - 7
bsp/stm32/libraries/HAL_Drivers/drv_can.c

@@ -11,6 +11,7 @@
  *                             fix bug.port to BSP [stm32]
  *                             fix bug.port to BSP [stm32]
  * 2019-03-27     YLZ          support double can channels, support stm32F4xx (only Legacy mode).
  * 2019-03-27     YLZ          support double can channels, support stm32F4xx (only Legacy mode).
  * 2019-06-17     YLZ          port to new STM32F1xx HAL V1.1.3.
  * 2019-06-17     YLZ          port to new STM32F1xx HAL V1.1.3.
+ * 2021-02-02     YuZhe XU     fix bug in filter config
  */
  */
 
 
 #include "drv_can.h"
 #include "drv_can.h"
@@ -292,6 +293,13 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
         }
         }
         break;
         break;
     case RT_CAN_CMD_SET_FILTER:
     case RT_CAN_CMD_SET_FILTER:
+    {
+        rt_uint32_t id_h = 0;
+        rt_uint32_t id_l = 0;
+        rt_uint32_t mask_h = 0;
+        rt_uint32_t mask_l = 0;
+        rt_uint32_t mask_l_tail = 0;  //CAN_FxR2 bit [2:0]
+
         if (RT_NULL == arg)
         if (RT_NULL == arg)
         {
         {
             /* default filter config */
             /* default filter config */
@@ -311,19 +319,73 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
                 {
                 {
                     drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
                     drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
                 }
                 }
-                drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
-                drv_can->FilterConfig.FilterIdHigh = (filter_cfg->items[i].id >> 13) & 0xFFFF;
-                drv_can->FilterConfig.FilterIdLow = ((filter_cfg->items[i].id << 3) | 
-                                                    (filter_cfg->items[i].ide << 2) | 
-                                                    (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
-                drv_can->FilterConfig.FilterMaskIdHigh = (filter_cfg->items[i].mask >> 16) & 0xFFFF;
-                drv_can->FilterConfig.FilterMaskIdLow = filter_cfg->items[i].mask & 0xFFFF;
+                 /**
+                 * struct rt_can_filter_item { 
+                 *      rt_uint32_t id : 29; // 报文 ID  
+                 *      rt_uint32_t ide : 1; // 扩展帧标识位  
+                 *      rt_uint32_t rtr : 1; // 远程帧标识位  
+                 *      rt_uint32_t mode : 1; // 过滤表模式  
+                 *      rt_uint32_t mask; // ID 掩码,0 表示对应的位不关心,1 表示对应的位必须匹配  
+                 *      rt_int32_t hdr; // -1 表示不指定过滤表号,对应的过滤表控制块也不会被初始化,正数为过滤表号,对应的过滤表控制块会被初始化  
+                 *      #ifdef RT_CAN_USING_HDR // 过滤表回调函数  
+                 *      rt_err_t (*ind)(rt_device_t dev, void *args , rt_int32_t hdr, rt_size_t size); // 回调函数参数  
+                 *      void *args; 
+                 *      #endif
+                 * };
+                 * ID     | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0]       |
+                 * MASK   | CAN_FxR2[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0]       |
+                 * STD ID |     STID[10:3]  | STDID[2:0] |<-                21bit                  ->|
+                 * EXT ID |    EXTID[28:21] | EXTID[20:13]    | EXTID[12:5]    | EXTID[4:0] IDE RTR 0|
+                 * @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
+                 *       -> but the id bit of struct rt_can_filter_item is 29, 
+                 *       -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
+                 *       -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
+                 *       -> FilterIdLow:   ((STDid << 18) or (EXT id << 3)) & 0xFFFF. 
+                 * @note the mask bit of struct rt_can_filter_item is 32, 
+                 *       -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF  
+                 *       -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF  
+                 */
+                if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDMASK)
+                {
+                    /* make sure the CAN_FxR1[2:0](IDE RTR) work */
+                    mask_l_tail = 0x06;
+                }
+                else if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDLIST)
+                {
+                    /* same as CAN_FxR1 */
+                    mask_l_tail = (filter_cfg->items[i].ide << 2) | 
+                                   (filter_cfg->items[i].rtr << 1);
+                }
+                if (filter_cfg->items[i].ide == RT_CAN_STDID)
+                {
+                    id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
+                    id_l = ((filter_cfg->items[i].id << 18) | 
+                            (filter_cfg->items[i].ide << 2) | 
+                            (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
+                    mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
+                    mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
+                }
+                else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
+                {
+                    id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
+                    id_l = ((filter_cfg->items[i].id << 3)          | 
+                            (filter_cfg->items[i].ide << 2)  | 
+                            (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
+                    mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
+                    mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
+                }
+                drv_can->FilterConfig.FilterIdHigh = id_h;
+                drv_can->FilterConfig.FilterIdLow = id_l;
+                drv_can->FilterConfig.FilterMaskIdHigh = mask_h;
+                drv_can->FilterConfig.FilterMaskIdLow = mask_l;
+                    
                 drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
                 drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
                 /* Filter conf */
                 /* Filter conf */
                 HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
                 HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
             }
             }
         }
         }
         break;
         break;
+    }
     case RT_CAN_CMD_SET_MODE:
     case RT_CAN_CMD_SET_MODE:
         argval = (rt_uint32_t) arg;
         argval = (rt_uint32_t) arg;
         if (argval != RT_CAN_MODE_NORMAL &&
         if (argval != RT_CAN_MODE_NORMAL &&