Skip to content

Commit af6f1dc

Browse files
committed
fix(driver_twai): fixed clock source enable/disable
1 parent e6fcaf4 commit af6f1dc

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

components/esp_driver_twai/esp_twai_onchip.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ static esp_err_t _node_delete(twai_node_handle_t node)
320320
_node_release_io(twai_ctx);
321321
twai_hal_deinit(twai_ctx->hal);
322322
_twai_rcc_clock_ctrl(twai_ctx->ctrlr_id, false);
323+
// curr_clk_src must not NULL as we already set to Default in twai_new_node_onchip
324+
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(twai_ctx->curr_clk_src, false), TAG, "disable clock source failed");
323325
_node_destroy(twai_ctx);
324326
return ESP_OK;
325327
}
@@ -352,6 +354,30 @@ static esp_err_t _node_check_timing_valid(twai_onchip_ctx_t *twai_ctx, const twa
352354
return ESP_OK;
353355
}
354356

357+
static esp_err_t _node_set_clock_source(twai_node_handle_t node, twai_clock_source_t clock_src)
358+
{
359+
twai_onchip_ctx_t *twai_ctx = __containerof(node, twai_onchip_ctx_t, api_base);
360+
if (clock_src != twai_ctx->curr_clk_src) {
361+
// Order of operations is important here.
362+
// First enable and switch to the new clock source, then disable the old one.
363+
// To ensure the clock to controller is continuous.
364+
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(clock_src, true), TAG, "enable clock source failed");
365+
_twai_rcc_clock_sel(twai_ctx->ctrlr_id, clock_src);
366+
if (twai_ctx->curr_clk_src) {
367+
// Disable previous clock source
368+
esp_err_t err = esp_clk_tree_enable_src(twai_ctx->curr_clk_src, false);
369+
if (err != ESP_OK) {
370+
ESP_LOGE(TAG, "disable previous clock source failed, err: %d", err);
371+
esp_clk_tree_enable_src(clock_src, false);
372+
return err;
373+
}
374+
}
375+
twai_ctx->curr_clk_src = clock_src;
376+
ESP_LOGD(TAG, "set clock source to %d", clock_src);
377+
}
378+
return ESP_OK;
379+
}
380+
355381
static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing_advanced_config_t *timing, const twai_timing_advanced_config_t *timing_fd)
356382
{
357383
twai_onchip_ctx_t *twai_ctx = __containerof(node, twai_onchip_ctx_t, api_base);
@@ -383,13 +409,7 @@ static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing
383409
}
384410
#endif
385411

386-
if (new_clock_src != twai_ctx->curr_clk_src) {
387-
// TODO: IDF-13144
388-
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(new_clock_src), true));
389-
twai_ctx->curr_clk_src = new_clock_src;
390-
_twai_rcc_clock_sel(twai_ctx->ctrlr_id, new_clock_src);
391-
}
392-
return ESP_OK;
412+
return _node_set_clock_source(node, new_clock_src);
393413
}
394414

395415
static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_source_t clk_src, const twai_timing_basic_config_t *timing, const twai_timing_basic_config_t *timing_fd)
@@ -617,6 +637,8 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
617637
ESP_GOTO_ON_ERROR(esp_intr_alloc(twai_periph_signals[ctrlr_id].irq_id, intr_flags, _node_isr_main, (void *)node, &node->intr_hdl),
618638
err, TAG, "Alloc interrupt failed");
619639

640+
// Set default clock source first
641+
ESP_RETURN_ON_ERROR(_node_set_clock_source(&node->api_base, TWAI_CLK_SRC_DEFAULT), TAG, "enable default clock source failed");
620642
// Enable bus clock and reset controller
621643
_twai_rcc_clock_ctrl(ctrlr_id, true);
622644
// Initialize HAL and configure register defaults.

components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "esp_attr.h"
1313
#include "esp_log.h"
1414
#include "esp_heap_caps.h"
15+
#include "esp_clk_tree.h"
1516
#include "freertos/FreeRTOS.h"
1617
#include "esp_twai.h"
1718
#include "esp_twai_onchip.h"
@@ -115,6 +116,7 @@ static void test_twai_baudrate_correctness(twai_clock_source_t clk_src, uint32_t
115116
};
116117
TEST_ESP_OK(twai_new_node_onchip(&node_config, &twai_node));
117118
TEST_ESP_OK(twai_node_enable(twai_node));
119+
printf("TWAI driver installed @ %ld Hz\n", test_bitrate);
118120

119121
// We use the UART baudrate detection submodule to measure the TWAI baudrate
120122
uart_bitrate_detect_config_t detect_config = {
@@ -148,8 +150,13 @@ static void test_twai_baudrate_correctness(twai_clock_source_t clk_src, uint32_t
148150
TEST_CASE("twai baudrate measurement", "[twai]")
149151
{
150152
twai_clock_source_t twai_available_clk_srcs[] = SOC_TWAI_CLKS;
153+
uint32_t source_freq = 0;
151154
for (size_t i = 0; i < sizeof(twai_available_clk_srcs) / sizeof(twai_available_clk_srcs[0]); i++) {
155+
TEST_ESP_OK(esp_clk_tree_src_get_freq_hz(twai_available_clk_srcs[i], ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &source_freq));
156+
printf("Test clock source %d frequency: %ld Hz\n", twai_available_clk_srcs[i], source_freq);
152157
test_twai_baudrate_correctness(twai_available_clk_srcs[i], 200000);
158+
159+
test_twai_baudrate_correctness(twai_available_clk_srcs[i], 1000000);
153160
}
154161
}
155162

0 commit comments

Comments
 (0)