Browse Source

FIX: [bsp][stm32]CAN从ACK错误恢复后发送异常 (#6511)

* 修改ry命令,已便于自定义保存路径

* modified:   components/utilities/ymodem/ry_sy.c

* 修复从被动错误恢复后发送返回异常

* 修复在自动重传模式下,ACK异常阻塞线程
- 删除TX中断函数else分支。仅当RQCP位 置一才进入该中断
- 添加SCE中断函数中关于ACK_ERR的else判断。自动重传模式下会进入该判断,打断自动重传释放完成量。

* 增加对于CAN1与CAN2的SCE中断和TX中断的公共处理函数

* formatting格式化代码
wdfk-prog 2 năm trước cách đây
mục cha
commit
e59b6c7ab4
1 tập tin đã thay đổi với 98 bổ sung142 xóa
  1. 98 142
      bsp/stm32/libraries/HAL_Drivers/drv_can.c

+ 98 - 142
bsp/stm32/libraries/HAL_Drivers/drv_can.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -22,7 +22,7 @@
 #define LOG_TAG    "drv_can"
 #include <drv_log.h>
 
-/* attention !!! baud calculation example: Tclk / ((ss + bs1 + bs2) * brp)  36 / ((1 + 8 + 3) * 3) = 1MHz*/
+/* attention !!! baud calculation example: Tclk / ((ss + bs1 + bs2) * brp) = 36 / ((1 + 8 + 3) * 3) = 1MHz*/
 #if defined (SOC_SERIES_STM32F1)/* APB1 36MHz(max) */
 static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
 {
@@ -689,24 +689,94 @@ static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
     }
 }
 
-#ifdef BSP_USING_CAN1
-/**
- * @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
- */
-void CAN1_TX_IRQHandler(void)
+static void _can_sce_isr(struct rt_can_device *can)
+{
+    CAN_HandleTypeDef *hcan;
+    RT_ASSERT(can);
+    hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
+    rt_uint32_t errtype = hcan->Instance->ESR;
+
+    switch ((errtype & 0x70) >> 4)
+    {
+        case RT_CAN_BUS_BIT_PAD_ERR:
+            can->status.bitpaderrcnt++;
+            break;
+        case RT_CAN_BUS_FORMAT_ERR:
+            can->status.formaterrcnt++;
+            break;
+        case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
+            can->status.ackerrcnt++;
+            if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
+            {
+                if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
+                {
+                    rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
+                }
+                SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
+            }
+            else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
+            {
+                if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
+                {
+                    rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 1 << 8);
+                }
+                SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
+            }
+            else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
+            {
+                if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
+                {
+                    rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 2 << 8);
+                }
+                SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
+            }
+            else
+            {
+                if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR0))/*IF AutoRetransmission = ENABLE,ACK ERR handler*/
+                {
+                    SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);/*Abort the send request, trigger the TX interrupt,release completion quantity*/
+                }
+                else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR1))
+                {
+                    SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
+                }
+                else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR2))
+                {
+                    SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
+                }
+            }
+            break;
+        case RT_CAN_BUS_IMPLICIT_BIT_ERR:
+        case RT_CAN_BUS_EXPLICIT_BIT_ERR:
+            can->status.biterrcnt++;
+            break;
+        case RT_CAN_BUS_CRC_ERR:
+            can->status.crcerrcnt++;
+            break;
+    }
+
+    can->status.lasterrtype = errtype & 0x70;
+    can->status.rcverrcnt = errtype >> 24;
+    can->status.snderrcnt = (errtype >> 16 & 0xFF);
+    can->status.errcode = errtype & 0x07;
+    hcan->Instance->MSR |= CAN_MSR_ERRI;
+}
+
+static void _can_tx_isr(struct rt_can_device *can)
 {
-    rt_interrupt_enter();
     CAN_HandleTypeDef *hcan;
-    hcan = &drv_can1.CanHandle;
+    RT_ASSERT(can);
+    hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
+
     if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
     {
         if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
         {
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_DONE | 0 << 8);
+            rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 0 << 8);
         }
         else
         {
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
+            rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
         }
         /* Write 0 to Clear transmission status flag RQCPx */
         SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
@@ -715,11 +785,11 @@ void CAN1_TX_IRQHandler(void)
     {
         if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
         {
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_DONE | 1 << 8);
+            rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 1 << 8);
         }
         else
         {
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
+            rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 1 << 8);
         }
         /* Write 0 to Clear transmission status flag RQCPx */
         SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
@@ -728,19 +798,25 @@ void CAN1_TX_IRQHandler(void)
     {
         if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
         {
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_DONE | 2 << 8);
+            rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 2 << 8);
         }
         else
         {
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
+            rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 2 << 8);
         }
         /* Write 0 to Clear transmission status flag RQCPx */
         SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
     }
-    else
-    {
-      rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
-    }
+}
+
+#ifdef BSP_USING_CAN1
+/**
+ * @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
+ */
+void CAN1_TX_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    _can_tx_isr(&drv_can1.device);
     rt_interrupt_leave();
 }
 
@@ -769,46 +845,8 @@ void CAN1_RX1_IRQHandler(void)
  */
 void CAN1_SCE_IRQHandler(void)
 {
-    rt_uint32_t errtype;
-    CAN_HandleTypeDef *hcan;
-
-    hcan = &drv_can1.CanHandle;
-    errtype = hcan->Instance->ESR;
-
     rt_interrupt_enter();
-    HAL_CAN_IRQHandler(hcan);
-
-    switch ((errtype & 0x70) >> 4)
-    {
-    case RT_CAN_BUS_BIT_PAD_ERR:
-        drv_can1.device.status.bitpaderrcnt++;
-        break;
-    case RT_CAN_BUS_FORMAT_ERR:
-        drv_can1.device.status.formaterrcnt++;
-        break;
-    case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
-        drv_can1.device.status.ackerrcnt++;
-        if (!READ_BIT(drv_can1.CanHandle.Instance->TSR, CAN_FLAG_TXOK0))
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
-        else if (!READ_BIT(drv_can1.CanHandle.Instance->TSR, CAN_FLAG_TXOK1))
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
-        else if (!READ_BIT(drv_can1.CanHandle.Instance->TSR, CAN_FLAG_TXOK2))
-            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
-        break;
-    case RT_CAN_BUS_IMPLICIT_BIT_ERR:
-    case RT_CAN_BUS_EXPLICIT_BIT_ERR:
-        drv_can1.device.status.biterrcnt++;
-        break;
-    case RT_CAN_BUS_CRC_ERR:
-        drv_can1.device.status.crcerrcnt++;
-        break;
-    }
-
-    drv_can1.device.status.lasterrtype = errtype & 0x70;
-    drv_can1.device.status.rcverrcnt = errtype >> 24;
-    drv_can1.device.status.snderrcnt = (errtype >> 16 & 0xFF);
-    drv_can1.device.status.errcode = errtype & 0x07;
-    hcan->Instance->MSR |= CAN_MSR_ERRI;
+    _can_sce_isr(&drv_can1.device);
     rt_interrupt_leave();
 }
 #endif /* BSP_USING_CAN1 */
@@ -820,51 +858,7 @@ void CAN1_SCE_IRQHandler(void)
 void CAN2_TX_IRQHandler(void)
 {
     rt_interrupt_enter();
-    CAN_HandleTypeDef *hcan;
-    hcan = &drv_can2.CanHandle;
-    if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
-    {
-        if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
-        {
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_DONE | 0 << 8);
-        }
-        else
-        {
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
-        }
-        /* Write 0 to Clear transmission status flag RQCPx */
-        SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
-    }
-    else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
-    {
-        if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
-        {
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_DONE | 1 << 8);
-        }
-        else
-        {
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
-        }
-        /* Write 0 to Clear transmission status flag RQCPx */
-        SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
-    }
-    else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
-    {
-        if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
-        {
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_DONE | 2 << 8);
-        }
-        else
-        {
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
-        }
-        /* Write 0 to Clear transmission status flag RQCPx */
-        SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
-    }
-    else
-    {
-      rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
-    }
+    _can_tx_isr(&drv_can2.device);
     rt_interrupt_leave();
 }
 
@@ -893,46 +887,8 @@ void CAN2_RX1_IRQHandler(void)
  */
 void CAN2_SCE_IRQHandler(void)
 {
-    rt_uint32_t errtype;
-    CAN_HandleTypeDef *hcan;
-
-    hcan = &drv_can2.CanHandle;
-    errtype = hcan->Instance->ESR;
-
     rt_interrupt_enter();
-    HAL_CAN_IRQHandler(hcan);
-
-    switch ((errtype & 0x70) >> 4)
-    {
-    case RT_CAN_BUS_BIT_PAD_ERR:
-        drv_can2.device.status.bitpaderrcnt++;
-        break;
-    case RT_CAN_BUS_FORMAT_ERR:
-        drv_can2.device.status.formaterrcnt++;
-        break;
-    case RT_CAN_BUS_ACK_ERR:
-        drv_can2.device.status.ackerrcnt++;
-        if (!READ_BIT(drv_can2.CanHandle.Instance->TSR, CAN_FLAG_TXOK0))
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
-        else if (!READ_BIT(drv_can2.CanHandle.Instance->TSR, CAN_FLAG_TXOK1))
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
-        else if (!READ_BIT(drv_can2.CanHandle.Instance->TSR, CAN_FLAG_TXOK2))
-            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
-        break;
-    case RT_CAN_BUS_IMPLICIT_BIT_ERR:
-    case RT_CAN_BUS_EXPLICIT_BIT_ERR:
-        drv_can2.device.status.biterrcnt++;
-        break;
-    case RT_CAN_BUS_CRC_ERR:
-        drv_can2.device.status.crcerrcnt++;
-        break;
-    }
-
-    drv_can2.device.status.lasterrtype = errtype & 0x70;
-    drv_can2.device.status.rcverrcnt = errtype >> 24;
-    drv_can2.device.status.snderrcnt = (errtype >> 16 & 0xFF);
-    drv_can2.device.status.errcode = errtype & 0x07;
-    hcan->Instance->MSR |= CAN_MSR_ERRI;
+    _can_sce_isr(&drv_can2.device);
     rt_interrupt_leave();
 }
 #endif /* BSP_USING_CAN2 */