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

This commit is contained in:
unnamed2 2025-07-02 14:50:24 +08:00 committed by GitHub
parent 251910aa0e
commit a1e865171b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 50 additions and 61 deletions

View File

@ -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) static void _can_sce_isr(struct rt_can_device *can)
{ {
CAN_HandleTypeDef *hcan; CAN_HandleTypeDef *hcan;
@ -721,45 +770,6 @@ static void _can_sce_isr(struct rt_can_device *can)
break; break;
case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */ case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
can->status.ackerrcnt++; 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; break;
case RT_CAN_BUS_IMPLICIT_BIT_ERR: case RT_CAN_BUS_IMPLICIT_BIT_ERR:
case RT_CAN_BUS_EXPLICIT_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++; can->status.crcerrcnt++;
break; break;
} }
_can_check_tx_complete(can);
can->status.lasterrtype = errtype & 0x70; can->status.lasterrtype = errtype & 0x70;
can->status.rcverrcnt = errtype >> 24; can->status.rcverrcnt = errtype >> 24;
@ -908,28 +919,6 @@ void CAN2_SCE_IRQHandler(void)
} }
#endif /* BSP_USING_CAN2 */ #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) int rt_hw_can_init(void)
{ {
struct can_configure config = CANDEFAULTCONFIG; struct can_configure config = CANDEFAULTCONFIG;