mirror of https://github.com/RT-Thread/rt-thread
fix stm32 CAN的SCE中断中只在ACK错误检查发送完成导致小概率出错的问题 #10354
This commit is contained in:
parent
251910aa0e
commit
a1e865171b
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue