Browse Source

修复hc32f460的can总线在bus off状态时死机问题,修复can滤波器设置失效问题 (#6083)

* [bsp][hc32]fix can bus driver bug.

1. 更改硬件滤波器数量为8,和手册描述一致。
2. 修复_can_control()函数,RT_CAN_CMD_SET_FILTER指令,当应用层ID超出29bit时导致滤波器失效的问题。
3. 修改_can_control()函数,RT_CAN_CMD_SET_FILTER指令,
可同时支持标准帧和扩展帧。
4. 修复can总线故障关闭时,程序一直卡在中断中无法退出的问题。
5. 针对can收发器硬件STB引脚,增加宏定义CAN1_STB_FUNC_ENABLE,适配没有STB引脚的收发器。

This reverts commit 7fcd8e9afc68eecf5fecc4cb6f9acc4fe76c2796.
梁生 3 years ago
parent
commit
f41cb5636f

+ 5 - 1
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.c

@@ -60,11 +60,15 @@ rt_err_t rt_hw_board_uart_init(CM_USART_TypeDef *USARTx)
 }
 }
 #endif
 #endif
 
 
-#if defined(RT_USING_CAN)
+#if defined(BSP_USING_CAN)
 void CanPhyEnable(void)
 void CanPhyEnable(void)
 {
 {
+#if defined(BSP_USING_CAN1)
+#ifdef CAN1_STB_FUNC_ENABLE
     GPIO_ResetPins(CAN_STB_PORT, CAN_STB_PIN);
     GPIO_ResetPins(CAN_STB_PORT, CAN_STB_PIN);
     GPIO_OutputCmd(CAN_STB_PORT, CAN_STB_PIN, ENABLE);
     GPIO_OutputCmd(CAN_STB_PORT, CAN_STB_PIN, ENABLE);
+#endif
+#endif
 }
 }
 rt_err_t rt_hw_board_can_init(CM_CAN_TypeDef *CANx)
 rt_err_t rt_hw_board_can_init(CM_CAN_TypeDef *CANx)
 {
 {

+ 1 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.h

@@ -61,6 +61,7 @@
     #define CAN1_RX_PIN                      (GPIO_PIN_06)
     #define CAN1_RX_PIN                      (GPIO_PIN_06)
     #define CAN1_RX_PIN_FUNC                 (GPIO_FUNC_51)
     #define CAN1_RX_PIN_FUNC                 (GPIO_FUNC_51)
 
 
+    #define CAN1_STB_FUNC_ENABLE
     #define CAN_STB_PORT                     (GPIO_PORT_D)
     #define CAN_STB_PORT                     (GPIO_PORT_D)
     #define CAN_STB_PIN                      (GPIO_PIN_15)
     #define CAN_STB_PIN                      (GPIO_PIN_15)
 #endif
 #endif

+ 43 - 21
bsp/hc32/libraries/hc32_drivers/drv_can.c

@@ -9,6 +9,7 @@
  * 2022-04-28     CDT                  first version
  * 2022-04-28     CDT                  first version
  * 2022-06-07     xiaoxiaolisunny      add hc32f460 series
  * 2022-06-07     xiaoxiaolisunny      add hc32f460 series
  * 2022-06-08     CDT                  fix a bug of RT_CAN_CMD_SET_FILTER
  * 2022-06-08     CDT                  fix a bug of RT_CAN_CMD_SET_FILTER
+ * 2022-06-15     lianghongquan        fix bug, FILTER_COUNT, RT_CAN_CMD_SET_FILTER, interrupt setup and processing.
  */
  */
 
 
 #include "drv_can.h"
 #include "drv_can.h"
@@ -29,7 +30,7 @@
 #endif
 #endif
 
 
 #if defined (HC32F460)
 #if defined (HC32F460)
-    #define FILTER_COUNT                                    (16)
+    #define FILTER_COUNT                                    (8)
     #define CAN1_INT_SRC                                    (INT_SRC_CAN_INT)
     #define CAN1_INT_SRC                                    (INT_SRC_CAN_INT)
 #endif
 #endif
 
 
@@ -213,14 +214,14 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
         switch (argval)
         switch (argval)
         {
         {
         case RT_DEVICE_FLAG_INT_RX:
         case RT_DEVICE_FLAG_INT_RX:
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX, DISABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_WARN, DISABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_FULL, DISABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_OVERRUN, DISABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX, DISABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_WARN, DISABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_FULL, DISABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_OVERRUN, DISABLE);
             break;
             break;
         case RT_DEVICE_FLAG_INT_TX:
         case RT_DEVICE_FLAG_INT_TX:
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_STB_TX, DISABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_PTB_TX, DISABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_STB_TX, DISABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_PTB_TX, DISABLE);
             break;
             break;
         case RT_DEVICE_CAN_INT_ERR:
         case RT_DEVICE_CAN_INT_ERR:
             CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, DISABLE);
             CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, DISABLE);
@@ -237,14 +238,14 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
         switch (argval)
         switch (argval)
         {
         {
         case RT_DEVICE_FLAG_INT_RX:
         case RT_DEVICE_FLAG_INT_RX:
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX, ENABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_WARN, ENABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_FULL, ENABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_OVERRUN, ENABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX, ENABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_WARN, ENABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_FULL, ENABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_OVERRUN, ENABLE);
             break;
             break;
         case RT_DEVICE_FLAG_INT_TX:
         case RT_DEVICE_FLAG_INT_TX:
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_STB_TX, ENABLE);
-            CAN_IntCmd(p_can_dev->instance, CAN_FLAG_PTB_TX, ENABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_STB_TX, ENABLE);
+            CAN_IntCmd(p_can_dev->instance, CAN_INT_PTB_TX, ENABLE);
             break;
             break;
         case RT_DEVICE_CAN_INT_ERR:
         case RT_DEVICE_CAN_INT_ERR:
             CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, ENABLE);
             CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, ENABLE);
@@ -273,15 +274,21 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
                 p_can_dev->ll_init.u16FilterSelect = _get_filter_idx(filter_cfg);
                 p_can_dev->ll_init.u16FilterSelect = _get_filter_idx(filter_cfg);
                 for (int i = 0; i < filter_cfg->count; i++)
                 for (int i = 0; i < filter_cfg->count; i++)
                 {
                 {
-                    p_can_dev->ll_init.pstcFilter[i].u32ID = filter_cfg->items[i].id;
-                    p_can_dev->ll_init.pstcFilter[i].u32IDMask = filter_cfg->items[i].mask;
-                    if (filter_cfg->items[i].ide == RT_CAN_STDID)
-                    {
-                        p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_STD;
-                    }
-                    else
+                    p_can_dev->ll_init.pstcFilter[i].u32ID = filter_cfg->items[i].id & 0x1FFFFFFF;
+                    /* rt-thread CAN mask, 1 mean filer, 0 mean ignore. *
+                     * HDSC HC32 CAN mask, 0 mean filer, 1 mean ignore. */
+                    p_can_dev->ll_init.pstcFilter[i].u32IDMask = (~filter_cfg->items[i].mask) & 0x1FFFFFFF;
+                    switch (filter_cfg->items[i].ide)
                     {
                     {
-                        p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_EXT;
+                        case (RT_CAN_STDID):
+                            p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_STD;
+                            break;
+                        case (RT_CAN_EXTID):
+                            p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_EXT;
+                            break;
+                        default:
+                            p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_STD_EXT;
+                            break;
                     }
                     }
                 }
                 }
             }
             }
@@ -453,6 +460,21 @@ static void _can_isr(can_device *p_can_dev)
     {
     {
         /* BUS OFF. */
         /* BUS OFF. */
     }
     }
+    if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_ERR_INT) == SET)
+    {
+        /* ERROR. */
+        CAN_ClearStatus(p_can_dev->instance, CAN_FLAG_ERR_INT);
+    }
+    if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_BUS_ERR) == SET)
+    {
+        /* BUS ERROR. */
+        CAN_ClearStatus(p_can_dev->instance, CAN_FLAG_BUS_ERR);
+    }
+    if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_ERR_PASSIVE) == SET)
+    {
+        /* error-passive to error-active or error-active to error-passive. */
+        CAN_ClearStatus(p_can_dev->instance, CAN_FLAG_ERR_PASSIVE);
+    }
 
 
     if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_RX_BUF_OVF) == SET)
     if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_RX_BUF_OVF) == SET)
     {
     {