* 2021-02-02 YuZhe XU fix bug in filter config
* 2021-8-25 SVCHAO The baud rate is configured according to the different APB1 frequencies. f4-series only.
This commit is contained in:
parent
caeea1f893
commit
0a037419dc
|
@ -11,6 +11,9 @@
|
||||||
* fix bug.port to BSP [stm32]
|
* fix bug.port to BSP [stm32]
|
||||||
* 2019-03-27 YLZ support double can channels, support stm32F4xx (only Legacy mode).
|
* 2019-03-27 YLZ support double can channels, support stm32F4xx (only Legacy mode).
|
||||||
* 2019-06-17 YLZ port to new STM32F1xx HAL V1.1.3.
|
* 2019-06-17 YLZ port to new STM32F1xx HAL V1.1.3.
|
||||||
|
* 2021-02-02 YuZhe XU fix bug in filter config
|
||||||
|
* 2021-8-25 SVCHAO The baud rate is configured according to the different APB1 frequencies.
|
||||||
|
f4-series only.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "drv_can.h"
|
#include "drv_can.h"
|
||||||
|
@ -33,10 +36,12 @@ static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)},
|
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)},
|
||||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 300)}
|
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 300)}
|
||||||
};
|
};
|
||||||
#elif defined (SOC_SERIES_STM32F4)/* APB1 45MHz(max) */
|
#elif defined (SOC_SERIES_STM32F4) /* 42MHz or 45MHz */
|
||||||
|
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
|
||||||
|
defined(STM32F401xC) || defined(STM32F401xE) /* 42MHz(max) */
|
||||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||||
{
|
{
|
||||||
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 3)},
|
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)},
|
||||||
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_5TQ | 4)},
|
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_5TQ | 4)},
|
||||||
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 6)},
|
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 6)},
|
||||||
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 12)},
|
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 12)},
|
||||||
|
@ -46,6 +51,24 @@ static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 150)},
|
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 150)},
|
||||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 300)}
|
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 300)}
|
||||||
};
|
};
|
||||||
|
#else /* APB1 45MHz(max) */
|
||||||
|
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||||
|
{
|
||||||
|
#ifdef BSP_USING_CAN168M
|
||||||
|
{CAN1MBaud, (CAN_SJW_1TQ | CAN_BS1_3TQ | CAN_BS2_3TQ | 6)},
|
||||||
|
#else
|
||||||
|
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 3)},
|
||||||
|
#endif
|
||||||
|
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_5TQ | 4)},
|
||||||
|
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 6)},
|
||||||
|
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 12)},
|
||||||
|
{CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 24)},
|
||||||
|
{CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 30)},
|
||||||
|
{CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 60)},
|
||||||
|
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 150)},
|
||||||
|
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 300)}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
#elif defined (SOC_SERIES_STM32F7)/* APB1 54MHz(max) */
|
#elif defined (SOC_SERIES_STM32F7)/* APB1 54MHz(max) */
|
||||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||||
{
|
{
|
||||||
|
@ -292,6 +315,13 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RT_CAN_CMD_SET_FILTER:
|
case RT_CAN_CMD_SET_FILTER:
|
||||||
|
{
|
||||||
|
rt_uint32_t id_h = 0;
|
||||||
|
rt_uint32_t id_l = 0;
|
||||||
|
rt_uint32_t mask_h = 0;
|
||||||
|
rt_uint32_t mask_l = 0;
|
||||||
|
rt_uint32_t mask_l_tail = 0; //CAN_FxR2 bit [2:0]
|
||||||
|
|
||||||
if (RT_NULL == arg)
|
if (RT_NULL == arg)
|
||||||
{
|
{
|
||||||
/* default filter config */
|
/* default filter config */
|
||||||
|
@ -303,19 +333,80 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
|
||||||
/* get default filter */
|
/* get default filter */
|
||||||
for (int i = 0; i < filter_cfg->count; i++)
|
for (int i = 0; i < filter_cfg->count; i++)
|
||||||
{
|
{
|
||||||
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
|
if (filter_cfg->items[i].hdr == -1)
|
||||||
drv_can->FilterConfig.FilterIdHigh = (filter_cfg->items[i].id >> 13) & 0xFFFF;
|
{
|
||||||
drv_can->FilterConfig.FilterIdLow = ((filter_cfg->items[i].id << 3) |
|
/* use default filter bank settings */
|
||||||
(filter_cfg->items[i].ide << 2) |
|
if (drv_can->name == "can1")
|
||||||
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
|
{
|
||||||
drv_can->FilterConfig.FilterMaskIdHigh = (filter_cfg->items[i].mask >> 16) & 0xFFFF;
|
/* can1 banks 0~13 */
|
||||||
drv_can->FilterConfig.FilterMaskIdLow = filter_cfg->items[i].mask & 0xFFFF;
|
drv_can->FilterConfig.FilterBank = i;
|
||||||
|
}
|
||||||
|
else if (drv_can->name == "can2")
|
||||||
|
{
|
||||||
|
/* can1 banks 14~27 */
|
||||||
|
drv_can->FilterConfig.FilterBank = i + 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* use user-defined filter bank settings */
|
||||||
|
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* ID | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
|
||||||
|
* MASK | CAN_FxR2[31:24] | CAN_FxR2[23:16] | CAN_FxR2[15:8] | CAN_FxR2[7:0] |
|
||||||
|
* STD ID | STID[10:3] | STDID[2:0] |<- 21bit ->|
|
||||||
|
* EXT ID | EXTID[28:21] | EXTID[20:13] | EXTID[12:5] | EXTID[4:0] IDE RTR 0|
|
||||||
|
* @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
|
||||||
|
* -> but the id bit of struct rt_can_filter_item is 29,
|
||||||
|
* -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
|
||||||
|
* -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
|
||||||
|
* -> FilterIdLow: ((STDid << 18) or (EXT id << 3)) & 0xFFFF.
|
||||||
|
* @note the mask bit of struct rt_can_filter_item is 32,
|
||||||
|
* -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF
|
||||||
|
* -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF
|
||||||
|
*/
|
||||||
|
if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDMASK)
|
||||||
|
{
|
||||||
|
/* make sure the CAN_FxR1[2:0](IDE RTR) work */
|
||||||
|
mask_l_tail = 0x06;
|
||||||
|
}
|
||||||
|
else if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDLIST)
|
||||||
|
{
|
||||||
|
/* same as CAN_FxR1 */
|
||||||
|
mask_l_tail = (filter_cfg->items[i].ide << 2) |
|
||||||
|
(filter_cfg->items[i].rtr << 1);
|
||||||
|
}
|
||||||
|
if (filter_cfg->items[i].ide == RT_CAN_STDID)
|
||||||
|
{
|
||||||
|
id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
|
||||||
|
id_l = ((filter_cfg->items[i].id << 18) |
|
||||||
|
(filter_cfg->items[i].ide << 2) |
|
||||||
|
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
|
||||||
|
mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
|
||||||
|
mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
|
||||||
|
}
|
||||||
|
else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
|
||||||
|
{
|
||||||
|
id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
|
||||||
|
id_l = ((filter_cfg->items[i].id << 3) |
|
||||||
|
(filter_cfg->items[i].ide << 2) |
|
||||||
|
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
|
||||||
|
mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
|
||||||
|
mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
|
||||||
|
}
|
||||||
|
drv_can->FilterConfig.FilterIdHigh = id_h;
|
||||||
|
drv_can->FilterConfig.FilterIdLow = id_l;
|
||||||
|
drv_can->FilterConfig.FilterMaskIdHigh = mask_h;
|
||||||
|
drv_can->FilterConfig.FilterMaskIdLow = mask_l;
|
||||||
|
|
||||||
drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
|
drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
|
||||||
/* Filter conf */
|
/* Filter conf */
|
||||||
HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
|
HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RT_CAN_CMD_SET_MODE:
|
case RT_CAN_CMD_SET_MODE:
|
||||||
argval = (rt_uint32_t) arg;
|
argval = (rt_uint32_t) arg;
|
||||||
if (argval != RT_CAN_MODE_NORMAL &&
|
if (argval != RT_CAN_MODE_NORMAL &&
|
||||||
|
@ -401,8 +492,6 @@ static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t
|
||||||
case CAN_TX_MAILBOX0:
|
case CAN_TX_MAILBOX0:
|
||||||
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
|
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
|
||||||
{
|
{
|
||||||
/* Change CAN state */
|
|
||||||
hcan->State = HAL_CAN_STATE_ERROR;
|
|
||||||
/* Return function status */
|
/* Return function status */
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -410,8 +499,6 @@ static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t
|
||||||
case CAN_TX_MAILBOX1:
|
case CAN_TX_MAILBOX1:
|
||||||
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
|
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
|
||||||
{
|
{
|
||||||
/* Change CAN state */
|
|
||||||
hcan->State = HAL_CAN_STATE_ERROR;
|
|
||||||
/* Return function status */
|
/* Return function status */
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -419,8 +506,6 @@ static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t
|
||||||
case CAN_TX_MAILBOX2:
|
case CAN_TX_MAILBOX2:
|
||||||
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
|
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
|
||||||
{
|
{
|
||||||
/* Change CAN state */
|
|
||||||
hcan->State = HAL_CAN_STATE_ERROR;
|
|
||||||
/* Return function status */
|
/* Return function status */
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -652,6 +737,10 @@ void CAN1_TX_IRQHandler(void)
|
||||||
/* Write 0 to Clear transmission status flag RQCPx */
|
/* Write 0 to Clear transmission status flag RQCPx */
|
||||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
|
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
|
||||||
|
}
|
||||||
rt_interrupt_leave();
|
rt_interrupt_leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,6 +776,7 @@ void CAN1_SCE_IRQHandler(void)
|
||||||
errtype = hcan->Instance->ESR;
|
errtype = hcan->Instance->ESR;
|
||||||
|
|
||||||
rt_interrupt_enter();
|
rt_interrupt_enter();
|
||||||
|
|
||||||
HAL_CAN_IRQHandler(hcan);
|
HAL_CAN_IRQHandler(hcan);
|
||||||
|
|
||||||
switch ((errtype & 0x70) >> 4)
|
switch ((errtype & 0x70) >> 4)
|
||||||
|
@ -772,6 +862,10 @@ void CAN2_TX_IRQHandler(void)
|
||||||
/* Write 0 to Clear transmission status flag RQCPx */
|
/* Write 0 to Clear transmission status flag RQCPx */
|
||||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
|
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
|
||||||
|
}
|
||||||
rt_interrupt_leave();
|
rt_interrupt_leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue