From b62d47dff2137b72b6e7b2aa9cd8e3e73e9b3d31 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 28 Jan 2023 16:15:20 +0100 Subject: [PATCH] can: can_check_bittiming_failed(): introduce function to check bittiming --- include/can.h | 2 +- include/can_common.h | 1 + include/gs_usb.h | 29 +++++++++-------------------- src/can/bxcan.c | 37 +++++++++++++++---------------------- src/can_common.c | 17 +++++++++++++++++ src/usbd_gs_can.c | 7 +++++++ 6 files changed, 50 insertions(+), 43 deletions(-) diff --git a/include/can.h b/include/can.h index dcd4896..c94379e 100644 --- a/include/can.h +++ b/include/can.h @@ -49,7 +49,7 @@ typedef struct { extern const struct gs_device_bt_const CAN_btconst; void can_init(can_data_t *channel, CAN_TypeDef *instance); -bool can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing); +void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing); void can_enable(can_data_t *channel, uint32_t mode); void can_disable(can_data_t *channel); bool can_is_enabled(can_data_t *channel); diff --git a/include/can_common.h b/include/can_common.h index 7ca3447..329d4d7 100644 --- a/include/can_common.h +++ b/include/can_common.h @@ -31,6 +31,7 @@ THE SOFTWARE. #include "can.h" #include "usbd_gs_can.h" +bool can_check_bittiming_ok(const struct can_bittiming_const *btc, const struct gs_device_bittiming *timing); void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel); void CAN_ReceiveFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel); void CAN_HandleError(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel); diff --git a/include/gs_usb.h b/include/gs_usb.h index 7e3d5d3..1d1a616 100644 --- a/include/gs_usb.h +++ b/include/gs_usb.h @@ -247,9 +247,7 @@ struct gs_device_bittiming { u32 brp; } __packed __aligned(4); -struct gs_device_bt_const { - u32 feature; - u32 fclk_can; +struct can_bittiming_const { u32 tseg1_min; u32 tseg1_max; u32 tseg2_min; @@ -260,26 +258,17 @@ struct gs_device_bt_const { u32 brp_inc; } __packed __aligned(4); +struct gs_device_bt_const { + u32 feature; + u32 fclk_can; + struct can_bittiming_const btc; +} __packed __aligned(4); + struct gs_device_bt_const_extended { u32 feature; u32 fclk_can; - u32 tseg1_min; - u32 tseg1_max; - u32 tseg2_min; - u32 tseg2_max; - u32 sjw_max; - u32 brp_min; - u32 brp_max; - u32 brp_inc; - - u32 dtseg1_min; - u32 dtseg1_max; - u32 dtseg2_min; - u32 dtseg2_max; - u32 dsjw_max; - u32 dbrp_min; - u32 dbrp_max; - u32 dbrp_inc; + struct can_bittiming_const btc; + struct can_bittiming_const dbtc; } __packed __aligned(4); struct gs_identify_mode { diff --git a/src/can/bxcan.c b/src/can/bxcan.c index f7feb10..7c72ab8 100644 --- a/src/can/bxcan.c +++ b/src/can/bxcan.c @@ -45,14 +45,16 @@ const struct gs_device_bt_const CAN_btconst = { #endif , .fclk_can = CAN_CLOCK_SPEED, - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, + .btc = { + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, }; // The STM32F0 only has one CAN interface, define it as CAN1 as @@ -84,23 +86,14 @@ void can_init(can_data_t *channel, CAN_TypeDef *instance) device_can_init(channel, instance); } -bool can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing) +void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing) { const uint8_t tseg1 = timing->prop_seg + timing->phase_seg1; - if ( (timing->brp>0) && (timing->brp<=1024) - && (tseg1>0) && (tseg1<=16) - && (timing->phase_seg2>0) && (timing->phase_seg2<=8) - && (timing->sjw>0) && (timing->sjw<=4) - ) { - channel->brp = timing->brp & 0x3FF; - channel->phase_seg1 = tseg1; - channel->phase_seg2 = timing->phase_seg2; - channel->sjw = timing->sjw; - return true; - } else { - return false; - } + channel->brp = timing->brp; + channel->phase_seg1 = tseg1; + channel->phase_seg2 = timing->phase_seg2; + channel->sjw = timing->sjw; } void can_enable(can_data_t *channel, uint32_t mode) diff --git a/src/can_common.c b/src/can_common.c index 8634097..e17d102 100644 --- a/src/can_common.c +++ b/src/can_common.c @@ -29,6 +29,23 @@ THE SOFTWARE. #include "timer.h" #include "usbd_gs_can.h" +bool can_check_bittiming_ok(const struct can_bittiming_const *btc, + const struct gs_device_bittiming *timing) +{ + const uint32_t tseg1 = timing->prop_seg + timing->phase_seg1; + + if (tseg1 < btc->tseg1_min || + tseg1 > btc->tseg1_max || + timing->phase_seg2 < btc->tseg2_min || + timing->phase_seg2 > btc->tseg2_max || + timing->sjw > btc->sjw_max || + timing->brp < btc->brp_min || + timing->brp > btc->brp_max) + return false; + + return true; +} + void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel) { struct gs_host_frame_object *frame_object; diff --git a/src/usbd_gs_can.c b/src/usbd_gs_can.c index 5b046c9..a605403 100644 --- a/src/usbd_gs_can.c +++ b/src/usbd_gs_can.c @@ -28,6 +28,7 @@ THE SOFTWARE. #include #include "can.h" +#include "can_common.h" #include "compiler.h" #include "config.h" #include "gpio.h" @@ -490,6 +491,9 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) { case GS_USB_BREQ_BITTIMING: { const struct gs_device_bittiming *timing = (struct gs_device_bittiming *)hcan->ep0_buf; + if (!can_check_bittiming_ok(&CAN_btconst.btc, timing)) + goto out_fail; + can_set_bittiming(channel, timing); break; } @@ -540,6 +544,9 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) { req->bRequest = 0xFF; return USBD_OK; + +out_fail: + return USBD_FAIL; } static uint8_t USBD_GS_CAN_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) {