From 5223006ec7b7cbd313613dcd8a02b2780d239cb7 Mon Sep 17 00:00:00 2001 From: wanckl Date: Thu, 11 Jun 2026 20:40:17 +0800 Subject: [PATCH] fix(driver_twai): fixed twaifd slow bitrate trans faile on correct bitrate --- components/esp_driver_twai/esp_twai.c | 23 ++++++++++--------- components/esp_driver_twai/esp_twai_onchip.c | 2 ++ .../include/esp_private/twai_utils.h | 1 + .../esp_hal_twai/esp32/include/hal/twai_ll.h | 1 + .../esp32c3/include/hal/twai_ll.h | 1 + .../esp32c6/include/hal/twai_ll.h | 1 + .../esp32h2/include/hal/twai_ll.h | 1 + .../esp32h21/include/hal/twai_ll.h | 1 + .../esp32p4/include/hal/twai_ll.h | 1 + .../esp32s2/include/hal/twai_ll.h | 1 + .../esp32s3/include/hal/twai_ll.h | 1 + 11 files changed, 23 insertions(+), 11 deletions(-) diff --git a/components/esp_driver_twai/esp_twai.c b/components/esp_driver_twai/esp_twai.c index 9d2a086b4aa..26d86a5174b 100644 --- a/components/esp_driver_twai/esp_twai.c +++ b/components/esp_driver_twai/esp_twai.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,7 @@ uint32_t twai_node_timing_calc_param(const uint32_t source_freq, const twai_timi if (total_div != tseg * pre_div) { continue; // no integer tseg } - if ((tseg <= (hw_limit->tseg1_max + hw_limit->tseg2_max + 1)) && (tseg >= (hw_limit->tseg1_min + hw_limit->tseg2_min))) { + if ((tseg <= (hw_limit->tseg1_max + hw_limit->tseg2_max + hw_limit->prop_max + 1)) && (tseg >= (hw_limit->tseg1_min + hw_limit->tseg2_min + 1))) { break; } } @@ -44,20 +44,21 @@ uint32_t twai_node_timing_calc_param(const uint32_t source_freq, const twai_timi uint16_t default_point = (in_param->bitrate >= 800000) ? 750 : ((in_param->bitrate >= 500000) ? 800 : 875); uint16_t sample_point = in_param->sp_permill ? in_param->sp_permill : default_point; // default sample point based on bitrate if not configured uint16_t tseg_1 = (tseg * sample_point) / 1000 - 1; - tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max)); - uint16_t tseg_2 = tseg - tseg_1 - 1; - tseg_2 = MAX(hw_limit->tseg2_min, MIN(tseg_2, hw_limit->tseg2_max)); - uint16_t prop = MAX(1, tseg_1 / 4); // prop_seg is usually shorter than tseg_1 and at least 1 - tseg_1 -= prop; + tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max + hw_limit->prop_max)); + uint16_t phase_seg2 = tseg - tseg_1 - 1; + phase_seg2 = MAX(hw_limit->tseg2_min, MIN(phase_seg2, hw_limit->tseg2_max)); + uint16_t phase_seg1 = (tseg_1 * 3) / 4; // phase_seg1 is usually larger than prop_seg + phase_seg1 = MAX(hw_limit->tseg1_min, MIN(phase_seg1, hw_limit->tseg1_max)); + uint16_t prop = tseg_1 - phase_seg1; out_param->brp = pre_div; out_param->prop_seg = prop; - out_param->tseg_1 = tseg_1; - out_param->tseg_2 = tseg_2; - out_param->sjw = MAX(1, MIN(tseg_2 >> 1, hw_limit->sjw_max)); + out_param->tseg_1 = phase_seg1; + out_param->tseg_2 = phase_seg2; + out_param->sjw = MAX(1, MIN(phase_seg2 >> 1, hw_limit->sjw_max)); out_param->ssp_offset = (tseg * in_param->ssp_permill) / 1000; // ssp is optional, default 0 if not configured - return source_freq / (pre_div * (prop + tseg_1 + tseg_2 + 1)); + return source_freq / (pre_div * (prop + phase_seg1 + phase_seg2 + 1)); } esp_err_t twai_node_enable(twai_node_handle_t node) diff --git a/components/esp_driver_twai/esp_twai_onchip.c b/components/esp_driver_twai/esp_twai_onchip.c index 4bb78fa2901..92720e523c0 100644 --- a/components/esp_driver_twai/esp_twai_onchip.c +++ b/components/esp_driver_twai/esp_twai_onchip.c @@ -377,6 +377,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, const twai_t twai_timing_constraint_t hw_const = { .brp_min = TWAI_LL_BRP_MIN, .brp_max = TWAI_LL_BRP_MAX, + .prop_max = TWAI_LL_PROP_MAX, .tseg1_min = TWAI_LL_TSEG1_MIN, .tseg1_max = TWAI_LL_TSEG1_MAX, .tseg2_min = TWAI_LL_TSEG2_MIN, @@ -395,6 +396,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, const twai_t twai_timing_advanced_config_t timing_adv_fd = {}; if (timing_fd->bitrate) { hw_const.brp_max = TWAI_LL_BRP_MAX_FD; + hw_const.prop_max = TWAI_LL_PROP_MAX_FD; hw_const.tseg1_max = TWAI_LL_TSEG1_MAX_FD; hw_const.tseg2_max = TWAI_LL_TSEG2_MAX_FD; hw_const.sjw_max = TWAI_LL_SJW_MAX_FD; diff --git a/components/esp_driver_twai/include/esp_private/twai_utils.h b/components/esp_driver_twai/include/esp_private/twai_utils.h index 0b49a66d89d..587fc8a45f6 100644 --- a/components/esp_driver_twai/include/esp_private/twai_utils.h +++ b/components/esp_driver_twai/include/esp_private/twai_utils.h @@ -19,6 +19,7 @@ extern "C" { typedef struct { uint32_t brp_min; /* Bit-rate prescaler */ uint32_t brp_max; + uint8_t prop_max; /* Propagation segment */ uint8_t tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */ uint8_t tseg1_max; uint8_t tseg2_min; /* Time segment 2 = phase_seg2 */ diff --git a/components/esp_hal_twai/esp32/include/hal/twai_ll.h b/components/esp_hal_twai/esp32/include/hal/twai_ll.h index 286893afa37..02bb17750db 100644 --- a/components/esp_hal_twai/esp32/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32/include/hal/twai_ll.h @@ -61,6 +61,7 @@ static uint32_t twai_ll_get_brp_max(void); #define TWAI_LL_BRP_DIV_THRESH 128 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX 16 //the max register value #define TWAI_LL_TSEG2_MAX 8 #define TWAI_LL_SJW_MAX 4 diff --git a/components/esp_hal_twai/esp32c3/include/hal/twai_ll.h b/components/esp_hal_twai/esp32c3/include/hal/twai_ll.h index eb81fc4d42c..5f52f7c9b9c 100644 --- a/components/esp_hal_twai/esp32c3/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32c3/include/hal/twai_ll.h @@ -38,6 +38,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 16384 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX 16 //the max register value #define TWAI_LL_TSEG2_MAX 8 #define TWAI_LL_SJW_MAX 4 diff --git a/components/esp_hal_twai/esp32c6/include/hal/twai_ll.h b/components/esp_hal_twai/esp32c6/include/hal/twai_ll.h index 47b0fe786db..bf5f7b71455 100644 --- a/components/esp_hal_twai/esp32c6/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32c6/include/hal/twai_ll.h @@ -33,6 +33,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 32768 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1) #define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1) #define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1) diff --git a/components/esp_hal_twai/esp32h2/include/hal/twai_ll.h b/components/esp_hal_twai/esp32h2/include/hal/twai_ll.h index 909e8db2e2c..701b5e7f913 100644 --- a/components/esp_hal_twai/esp32h2/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32h2/include/hal/twai_ll.h @@ -33,6 +33,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 32768 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1) #define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1) #define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1) diff --git a/components/esp_hal_twai/esp32h21/include/hal/twai_ll.h b/components/esp_hal_twai/esp32h21/include/hal/twai_ll.h index 76aa0ffbda7..2e9001fd585 100644 --- a/components/esp_hal_twai/esp32h21/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32h21/include/hal/twai_ll.h @@ -33,6 +33,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 32768 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1) #define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1) #define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1) diff --git a/components/esp_hal_twai/esp32p4/include/hal/twai_ll.h b/components/esp_hal_twai/esp32p4/include/hal/twai_ll.h index 2e4b65b7a1f..762cb9e4ac4 100644 --- a/components/esp_hal_twai/esp32p4/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32p4/include/hal/twai_ll.h @@ -33,6 +33,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 32768 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1) #define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1) #define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1) diff --git a/components/esp_hal_twai/esp32s2/include/hal/twai_ll.h b/components/esp_hal_twai/esp32s2/include/hal/twai_ll.h index bb670d63b06..abd1ffba065 100644 --- a/components/esp_hal_twai/esp32s2/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32s2/include/hal/twai_ll.h @@ -38,6 +38,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 32768 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX 16 //the max register value #define TWAI_LL_TSEG2_MAX 8 #define TWAI_LL_SJW_MAX 4 diff --git a/components/esp_hal_twai/esp32s3/include/hal/twai_ll.h b/components/esp_hal_twai/esp32s3/include/hal/twai_ll.h index ddef2cbfc08..aad2bc7819a 100644 --- a/components/esp_hal_twai/esp32s3/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32s3/include/hal/twai_ll.h @@ -38,6 +38,7 @@ extern "C" { #define TWAI_LL_BRP_MAX 16384 #define TWAI_LL_TSEG1_MIN 1 #define TWAI_LL_TSEG2_MIN 1 +#define TWAI_LL_PROP_MAX 0 //hardware don't support prop_seg #define TWAI_LL_TSEG1_MAX 16 //the max register value #define TWAI_LL_TSEG2_MAX 8 #define TWAI_LL_SJW_MAX 4