mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-27 17:45:13 +08:00
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格式化代码
This commit is contained in:
@@ -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)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
CAN_HandleTypeDef *hcan;
|
||||
hcan = &drv_can1.CanHandle;
|
||||
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)
|
||||
{
|
||||
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(&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 */
|
||||
|
||||
Reference in New Issue
Block a user