@@ -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+
355381static 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
395415static 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.
0 commit comments