修复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:
parent
774efb0c5b
commit
f41cb5636f
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue