修复hc32f460的can总线在bus off状态时死机问题,修复can滤波器设置失效问题 (#6083)

* [bsp][hc32]fix can bus driver bug.

1. 更改硬件滤波器数量为8,和手册描述一致。
2. 修复_can_control()函数,RT_CAN_CMD_SET_FILTER指令,当应用层ID超出29bit时导致滤波器失效的问题。
3. 修改_can_control()函数,RT_CAN_CMD_SET_FILTER指令,
可同时支持标准帧和扩展帧。
4. 修复can总线故障关闭时,程序一直卡在中断中无法退出的问题。
5. 针对can收发器硬件STB引脚,增加宏定义CAN1_STB_FUNC_ENABLE,适配没有STB引脚的收发器。

This reverts commit 7fcd8e9afc.
This commit is contained in:
梁生 2022-06-21 11:12:35 +08:00 committed by GitHub
parent 774efb0c5b
commit f41cb5636f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 22 deletions

View File

@ -60,11 +60,15 @@ rt_err_t rt_hw_board_uart_init(CM_USART_TypeDef *USARTx)
} }
#endif #endif
#if defined(RT_USING_CAN) #if defined(BSP_USING_CAN)
void CanPhyEnable(void) void CanPhyEnable(void)
{ {
#if defined(BSP_USING_CAN1)
#ifdef CAN1_STB_FUNC_ENABLE
GPIO_ResetPins(CAN_STB_PORT, CAN_STB_PIN); GPIO_ResetPins(CAN_STB_PORT, CAN_STB_PIN);
GPIO_OutputCmd(CAN_STB_PORT, CAN_STB_PIN, ENABLE); GPIO_OutputCmd(CAN_STB_PORT, CAN_STB_PIN, ENABLE);
#endif
#endif
} }
rt_err_t rt_hw_board_can_init(CM_CAN_TypeDef *CANx) rt_err_t rt_hw_board_can_init(CM_CAN_TypeDef *CANx)
{ {

View File

@ -61,6 +61,7 @@
#define CAN1_RX_PIN (GPIO_PIN_06) #define CAN1_RX_PIN (GPIO_PIN_06)
#define CAN1_RX_PIN_FUNC (GPIO_FUNC_51) #define CAN1_RX_PIN_FUNC (GPIO_FUNC_51)
#define CAN1_STB_FUNC_ENABLE
#define CAN_STB_PORT (GPIO_PORT_D) #define CAN_STB_PORT (GPIO_PORT_D)
#define CAN_STB_PIN (GPIO_PIN_15) #define CAN_STB_PIN (GPIO_PIN_15)
#endif #endif

View File

@ -9,6 +9,7 @@
* 2022-04-28 CDT first version * 2022-04-28 CDT first version
* 2022-06-07 xiaoxiaolisunny add hc32f460 series * 2022-06-07 xiaoxiaolisunny add hc32f460 series
* 2022-06-08 CDT fix a bug of RT_CAN_CMD_SET_FILTER * 2022-06-08 CDT fix a bug of RT_CAN_CMD_SET_FILTER
* 2022-06-15 lianghongquan fix bug, FILTER_COUNT, RT_CAN_CMD_SET_FILTER, interrupt setup and processing.
*/ */
#include "drv_can.h" #include "drv_can.h"
@ -29,7 +30,7 @@
#endif #endif
#if defined (HC32F460) #if defined (HC32F460)
#define FILTER_COUNT (16) #define FILTER_COUNT (8)
#define CAN1_INT_SRC (INT_SRC_CAN_INT) #define CAN1_INT_SRC (INT_SRC_CAN_INT)
#endif #endif
@ -213,14 +214,14 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
switch (argval) switch (argval)
{ {
case RT_DEVICE_FLAG_INT_RX: case RT_DEVICE_FLAG_INT_RX:
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX, DISABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_WARN, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_WARN, DISABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_FULL, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_FULL, DISABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_OVERRUN, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_OVERRUN, DISABLE);
break; break;
case RT_DEVICE_FLAG_INT_TX: case RT_DEVICE_FLAG_INT_TX:
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_STB_TX, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_STB_TX, DISABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_PTB_TX, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_PTB_TX, DISABLE);
break; break;
case RT_DEVICE_CAN_INT_ERR: case RT_DEVICE_CAN_INT_ERR:
CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, DISABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, DISABLE);
@ -237,14 +238,14 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
switch (argval) switch (argval)
{ {
case RT_DEVICE_FLAG_INT_RX: case RT_DEVICE_FLAG_INT_RX:
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX, ENABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_WARN, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_WARN, ENABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_BUF_FULL, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_BUF_FULL, ENABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_RX_OVERRUN, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_RX_OVERRUN, ENABLE);
break; break;
case RT_DEVICE_FLAG_INT_TX: case RT_DEVICE_FLAG_INT_TX:
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_STB_TX, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_STB_TX, ENABLE);
CAN_IntCmd(p_can_dev->instance, CAN_FLAG_PTB_TX, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_PTB_TX, ENABLE);
break; break;
case RT_DEVICE_CAN_INT_ERR: case RT_DEVICE_CAN_INT_ERR:
CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, ENABLE); CAN_IntCmd(p_can_dev->instance, CAN_INT_ERR_INT, ENABLE);
@ -273,15 +274,21 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
p_can_dev->ll_init.u16FilterSelect = _get_filter_idx(filter_cfg); p_can_dev->ll_init.u16FilterSelect = _get_filter_idx(filter_cfg);
for (int i = 0; i < filter_cfg->count; i++) for (int i = 0; i < filter_cfg->count; i++)
{ {
p_can_dev->ll_init.pstcFilter[i].u32ID = filter_cfg->items[i].id; p_can_dev->ll_init.pstcFilter[i].u32ID = filter_cfg->items[i].id & 0x1FFFFFFF;
p_can_dev->ll_init.pstcFilter[i].u32IDMask = filter_cfg->items[i].mask; /* rt-thread CAN mask, 1 mean filer, 0 mean ignore. *
if (filter_cfg->items[i].ide == RT_CAN_STDID) * HDSC HC32 CAN mask, 0 mean filer, 1 mean ignore. */
p_can_dev->ll_init.pstcFilter[i].u32IDMask = (~filter_cfg->items[i].mask) & 0x1FFFFFFF;
switch (filter_cfg->items[i].ide)
{ {
case (RT_CAN_STDID):
p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_STD; p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_STD;
} break;
else case (RT_CAN_EXTID):
{
p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_EXT; p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_EXT;
break;
default:
p_can_dev->ll_init.pstcFilter[i].u32IDType = CAN_ID_STD_EXT;
break;
} }
} }
} }
@ -453,6 +460,21 @@ static void _can_isr(can_device *p_can_dev)
{ {
/* BUS OFF. */ /* BUS OFF. */
} }
if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_ERR_INT) == SET)
{
/* ERROR. */
CAN_ClearStatus(p_can_dev->instance, CAN_FLAG_ERR_INT);
}
if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_BUS_ERR) == SET)
{
/* BUS ERROR. */
CAN_ClearStatus(p_can_dev->instance, CAN_FLAG_BUS_ERR);
}
if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_ERR_PASSIVE) == SET)
{
/* error-passive to error-active or error-active to error-passive. */
CAN_ClearStatus(p_can_dev->instance, CAN_FLAG_ERR_PASSIVE);
}
if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_RX_BUF_OVF) == SET) if (CAN_GetStatus(p_can_dev->instance, CAN_FLAG_RX_BUF_OVF) == SET)
{ {