소스 검색

fix stm32 CAN的SCE中断中只在ACK错误检查发送完成导致小概率出错的问题 #10354

unnamed2 1 개월 전
부모
커밋
a1e865171b
1개의 변경된 파일50개의 추가작업 그리고 61개의 파일을 삭제
  1. 50 61
      bsp/stm32/libraries/HAL_Drivers/drivers/drv_can.c

+ 50 - 61
bsp/stm32/libraries/HAL_Drivers/drivers/drv_can.c

@@ -704,6 +704,55 @@ static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
     }
 }
 
+static void _can_check_tx_complete(struct rt_can_device *can)
+{
+    CAN_HandleTypeDef *hcan;
+    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(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
+        }
+        SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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*/
+    }
+
+    if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR1))
+    {
+        SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
+    }
+
+    if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR2))
+    {
+        SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
+    }
+}
+
 static void _can_sce_isr(struct rt_can_device *can)
 {
     CAN_HandleTypeDef *hcan;
@@ -721,45 +770,6 @@ static void _can_sce_isr(struct rt_can_device *can)
             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:
@@ -769,6 +779,7 @@ static void _can_sce_isr(struct rt_can_device *can)
             can->status.crcerrcnt++;
             break;
     }
+    _can_check_tx_complete(can);
 
     can->status.lasterrtype = errtype & 0x70;
     can->status.rcverrcnt = errtype >> 24;
@@ -908,28 +919,6 @@ void CAN2_SCE_IRQHandler(void)
 }
 #endif /* BSP_USING_CAN2 */
 
-/**
- * @brief  Error CAN callback.
- * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
- *         the configuration information for the specified CAN.
- * @retval None
- */
-void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
-{
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERROR_WARNING |
-                        CAN_IT_ERROR_PASSIVE |
-                        CAN_IT_BUSOFF |
-                        CAN_IT_LAST_ERROR_CODE |
-                        CAN_IT_ERROR |
-                        CAN_IT_RX_FIFO0_MSG_PENDING |
-                        CAN_IT_RX_FIFO0_OVERRUN |
-                        CAN_IT_RX_FIFO0_FULL |
-                        CAN_IT_RX_FIFO1_MSG_PENDING |
-                        CAN_IT_RX_FIFO1_OVERRUN |
-                        CAN_IT_RX_FIFO1_FULL |
-                        CAN_IT_TX_MAILBOX_EMPTY);
-}
-
 int rt_hw_can_init(void)
 {
     struct can_configure config = CANDEFAULTCONFIG;