diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_can.c b/bsp/stm32/libraries/HAL_Drivers/drv_can.c index 83d58ec800674c5aa8f3da76ca9123c46f22866e..ec486bf74710fad407905aef5600f7aaf5691d48 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_can.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_can.c @@ -11,6 +11,9 @@ * fix bug.port to BSP [stm32] * 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. + * 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" @@ -33,10 +36,29 @@ static const struct stm32_baud_rate_tab can_baud_rate_tab[] = {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)}, {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[] = { + {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)}, + {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)} +}; +#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)}, @@ -46,6 +68,7 @@ static const struct stm32_baud_rate_tab can_baud_rate_tab[] = {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) */ 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; 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) { /* 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 */ for (int i = 0; i < filter_cfg->count; i++) { - drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr; - drv_can->FilterConfig.FilterIdHigh = (filter_cfg->items[i].id >> 13) & 0xFFFF; - drv_can->FilterConfig.FilterIdLow = ((filter_cfg->items[i].id << 3) | - (filter_cfg->items[i].ide << 2) | - (filter_cfg->items[i].rtr << 1)) & 0xFFFF; - drv_can->FilterConfig.FilterMaskIdHigh = (filter_cfg->items[i].mask >> 16) & 0xFFFF; - drv_can->FilterConfig.FilterMaskIdLow = filter_cfg->items[i].mask & 0xFFFF; + if (filter_cfg->items[i].hdr == -1) + { + /* use default filter bank settings */ + if (drv_can->name == "can1") + { + /* can1 banks 0~13 */ + 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; /* Filter conf */ HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig); } } break; + } case RT_CAN_CMD_SET_MODE: argval = (rt_uint32_t) arg; 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: 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 -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: 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 -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: 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 -RT_ERROR; } @@ -652,6 +737,10 @@ void CAN1_TX_IRQHandler(void) /* 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); + } rt_interrupt_leave(); } @@ -687,6 +776,7 @@ void CAN1_SCE_IRQHandler(void) errtype = hcan->Instance->ESR; rt_interrupt_enter(); + HAL_CAN_IRQHandler(hcan); switch ((errtype & 0x70) >> 4) @@ -772,6 +862,10 @@ void CAN2_TX_IRQHandler(void) /* 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); + } rt_interrupt_leave(); }