mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(driver_twai): fixed twaifd slow bitrate trans faile on correct bitrate
This commit is contained in:
@@ -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
|
* 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) {
|
if (total_div != tseg * pre_div) {
|
||||||
continue; // no integer tseg
|
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;
|
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 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 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;
|
uint16_t tseg_1 = (tseg * sample_point) / 1000 - 1;
|
||||||
tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max));
|
tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max + hw_limit->prop_max));
|
||||||
uint16_t tseg_2 = tseg - tseg_1 - 1;
|
uint16_t phase_seg2 = tseg - tseg_1 - 1;
|
||||||
tseg_2 = MAX(hw_limit->tseg2_min, MIN(tseg_2, hw_limit->tseg2_max));
|
phase_seg2 = MAX(hw_limit->tseg2_min, MIN(phase_seg2, hw_limit->tseg2_max));
|
||||||
uint16_t prop = MAX(1, tseg_1 / 4); // prop_seg is usually shorter than tseg_1 and at least 1
|
uint16_t phase_seg1 = (tseg_1 * 3) / 4; // phase_seg1 is usually larger than prop_seg
|
||||||
tseg_1 -= prop;
|
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->brp = pre_div;
|
||||||
out_param->prop_seg = prop;
|
out_param->prop_seg = prop;
|
||||||
out_param->tseg_1 = tseg_1;
|
out_param->tseg_1 = phase_seg1;
|
||||||
out_param->tseg_2 = tseg_2;
|
out_param->tseg_2 = phase_seg2;
|
||||||
out_param->sjw = MAX(1, MIN(tseg_2 >> 1, hw_limit->sjw_max));
|
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
|
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)
|
esp_err_t twai_node_enable(twai_node_handle_t node)
|
||||||
|
|||||||
@@ -399,6 +399,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, const twai_t
|
|||||||
twai_timing_constraint_t hw_const = {
|
twai_timing_constraint_t hw_const = {
|
||||||
.brp_min = TWAI_LL_BRP_MIN,
|
.brp_min = TWAI_LL_BRP_MIN,
|
||||||
.brp_max = TWAI_LL_BRP_MAX,
|
.brp_max = TWAI_LL_BRP_MAX,
|
||||||
|
.prop_max = TWAI_LL_PROP_MAX,
|
||||||
.tseg1_min = TWAI_LL_TSEG1_MIN,
|
.tseg1_min = TWAI_LL_TSEG1_MIN,
|
||||||
.tseg1_max = TWAI_LL_TSEG1_MAX,
|
.tseg1_max = TWAI_LL_TSEG1_MAX,
|
||||||
.tseg2_min = TWAI_LL_TSEG2_MIN,
|
.tseg2_min = TWAI_LL_TSEG2_MIN,
|
||||||
@@ -417,6 +418,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 = {};
|
twai_timing_advanced_config_t timing_adv_fd = {};
|
||||||
if (timing_fd->bitrate) {
|
if (timing_fd->bitrate) {
|
||||||
hw_const.brp_max = TWAI_LL_BRP_MAX_FD;
|
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.tseg1_max = TWAI_LL_TSEG1_MAX_FD;
|
||||||
hw_const.tseg2_max = TWAI_LL_TSEG2_MAX_FD;
|
hw_const.tseg2_max = TWAI_LL_TSEG2_MAX_FD;
|
||||||
hw_const.sjw_max = TWAI_LL_SJW_MAX_FD;
|
hw_const.sjw_max = TWAI_LL_SJW_MAX_FD;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t brp_min; /* Bit-rate prescaler */
|
uint32_t brp_min; /* Bit-rate prescaler */
|
||||||
uint32_t brp_max;
|
uint32_t brp_max;
|
||||||
|
uint8_t prop_max; /* Propagation segment */
|
||||||
uint8_t tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */
|
uint8_t tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */
|
||||||
uint8_t tseg1_max;
|
uint8_t tseg1_max;
|
||||||
uint8_t tseg2_min; /* Time segment 2 = phase_seg2 */
|
uint8_t tseg2_min; /* Time segment 2 = phase_seg2 */
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ static uint32_t twai_ll_get_brp_max(void);
|
|||||||
#define TWAI_LL_BRP_MAX twai_ll_get_brp_max() // max brp of esp32 is depends on chip version
|
#define TWAI_LL_BRP_MAX twai_ll_get_brp_max() // max brp of esp32 is depends on chip version
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX 16 //the max register value
|
||||||
#define TWAI_LL_TSEG2_MAX 8
|
#define TWAI_LL_TSEG2_MAX 8
|
||||||
#define TWAI_LL_SJW_MAX 4
|
#define TWAI_LL_SJW_MAX 4
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ extern "C" {
|
|||||||
#define TWAI_LL_BRP_MAX 16384
|
#define TWAI_LL_BRP_MAX 16384
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX 16 //the max register value
|
||||||
#define TWAI_LL_TSEG2_MAX 8
|
#define TWAI_LL_TSEG2_MAX 8
|
||||||
#define TWAI_LL_SJW_MAX 4
|
#define TWAI_LL_SJW_MAX 4
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ extern "C" {
|
|||||||
#define TWAI_LL_BRP_MAX 32768
|
#define TWAI_LL_BRP_MAX 32768
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1)
|
||||||
#define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1)
|
#define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1)
|
||||||
#define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1)
|
#define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ extern "C" {
|
|||||||
#define TWAI_LL_BRP_MAX 32768
|
#define TWAI_LL_BRP_MAX 32768
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1)
|
||||||
#define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1)
|
#define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1)
|
||||||
#define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1)
|
#define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ extern "C" {
|
|||||||
#define TWAI_LL_BRP_MAX 32768
|
#define TWAI_LL_BRP_MAX 32768
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX (TWAI_TIME_SEGMENT1 + 1)
|
||||||
#define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1)
|
#define TWAI_LL_TSEG2_MAX (TWAI_TIME_SEGMENT2 + 1)
|
||||||
#define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1)
|
#define TWAI_LL_SJW_MAX (TWAI_SYNC_JUMP_WIDTH + 1)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ extern "C" {
|
|||||||
#define TWAI_LL_BRP_MAX 32768
|
#define TWAI_LL_BRP_MAX 32768
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX 16 //the max register value
|
||||||
#define TWAI_LL_TSEG2_MAX 8
|
#define TWAI_LL_TSEG2_MAX 8
|
||||||
#define TWAI_LL_SJW_MAX 4
|
#define TWAI_LL_SJW_MAX 4
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ extern "C" {
|
|||||||
#define TWAI_LL_BRP_MAX 16384
|
#define TWAI_LL_BRP_MAX 16384
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_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_TSEG1_MAX 16 //the max register value
|
||||||
#define TWAI_LL_TSEG2_MAX 8
|
#define TWAI_LL_TSEG2_MAX 8
|
||||||
#define TWAI_LL_SJW_MAX 4
|
#define TWAI_LL_SJW_MAX 4
|
||||||
|
|||||||
Reference in New Issue
Block a user