@@ -668,20 +668,22 @@ uart_t *uartBegin(
668
668
if (uart_nr >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
669
669
if (uart -> _uart_clock_source > 0 ) {
670
670
uart_config .lp_source_clk = (soc_periph_lp_uart_clk_src_t ) uart -> _uart_clock_source ; // use user defined LP UART clock
671
+ log_v ("Setting UART%d to user defined LP clock source (%d) " , uart_nr , uart -> _uart_clock_source );
671
672
} else {
672
673
uart_config .lp_source_clk = LP_UART_SCLK_DEFAULT ; // use default LP clock
674
+ log_v ("Setting UART%d to Default LP clock source" , uart_nr );
673
675
}
674
- log_v ("Setting UART%d to use LP clock (%d) " , uart_nr , uart_config .lp_source_clk );
675
676
} else
676
- #endif
677
+ #endif // SOC_UART_LP_NUM >= 1
677
678
{
678
679
#if CONFIG_ARDUINO_SERIAL_FORCE_IDF_DEFAULT_CLOCK_SOURCE
679
680
// Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6|P4
680
681
uart_config .source_clk = UART_SCLK_DEFAULT ; // baudrate may change with the APB Frequency!
681
682
log_v ("Setting UART%d to use DEFAULT clock" , uart_nr );
682
683
#else
683
- if (uart -> _uart_clock_source > 0 ) {
684
+ if (uart -> _uart_clock_source >= 0 ) {
684
685
uart_config .source_clk = (soc_module_clk_t ) uart -> _uart_clock_source ; // use user defined HP UART clock
686
+ log_v ("Setting UART%d to user defined HP clock source (%d) " , uart_nr , uart -> _uart_clock_source );
685
687
} else {
686
688
// there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
687
689
// therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
@@ -700,9 +702,9 @@ uart_t *uartBegin(
700
702
// Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6|P4
701
703
uart_config .source_clk = UART_SCLK_DEFAULT ; // baudrate may change with the APB Frequency!
702
704
log_v ("Setting UART%d to use DEFAULT clock" , uart_nr );
703
- #endif
704
- #endif
705
+ #endif // SOC_UART_SUPPORT_XTAL_CLK
705
706
}
707
+ #endif // CONFIG_ARDUINO_SERIAL_FORCE_IDF_DEFAULT_CLOCK_SOURCE
706
708
}
707
709
708
710
UART_MUTEX_LOCK ();
@@ -731,6 +733,7 @@ uart_t *uartBegin(
731
733
uart -> _tx_buffer_size = tx_buffer_size ;
732
734
uart -> has_peek = false;
733
735
uart -> peek_byte = 0 ;
736
+ uart -> _uart_clock_source = uart_config .source_clk ;
734
737
}
735
738
UART_MUTEX_UNLOCK ();
736
739
@@ -990,22 +993,58 @@ bool uartSetBaudRate(uart_t *uart, uint32_t baud_rate) {
990
993
return false;
991
994
}
992
995
bool retCode = true;
993
- UART_MUTEX_LOCK ();
994
- #if SOC_UART_SUPPORT_XTAL_CLK // ESP32-S3, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-H2 and ESP32-P4
995
- soc_module_clk_t newClkSrc = UART_SCLK_XTAL ;
996
+ soc_module_clk_t newClkSrc = UART_SCLK_DEFAULT ;
997
+ uint8_t previousClkSrc = uart -> _uart_clock_source ;
996
998
#if SOC_UART_LP_NUM >= 1
997
- if (uart -> num >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
998
- newClkSrc = LP_UART_SCLK_DEFAULT ; // use default LP clock
999
+ if (uart_nr >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
1000
+ if (uart -> _uart_clock_source > 0 ) {
1001
+ newClkSrc = (soc_periph_lp_uart_clk_src_t ) uart -> _uart_clock_source ; // use user defined LP UART clock
1002
+ log_v ("Setting UART%d to user defined LP clock source (%d) " , uart -> num , newClkSrc );
1003
+ } else {
1004
+ newClkSrc = LP_UART_SCLK_DEFAULT ; // use default LP clock
1005
+ log_v ("Setting UART%d to Default LP clock source" , uart -> num );
1006
+ }
1007
+ } else
1008
+ #endif // SOC_UART_LP_NUM >= 1
1009
+ {
1010
+ #if CONFIG_ARDUINO_SERIAL_FORCE_IDF_DEFAULT_CLOCK_SOURCE
1011
+ // Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6|P4
1012
+ // newClkSrc already set in the variable declaration
1013
+ log_v ("Setting UART%d to use DEFAULT clock" , uart -> num );
1014
+ #else
1015
+ if (uart -> _uart_clock_source >= 0 ) {
1016
+ newClkSrc = (soc_module_clk_t ) uart -> _uart_clock_source ; // use user defined HP UART clock
1017
+ log_v ("Setting UART%d to use HP clock source (%d) " , uart -> num , newClkSrc );
1018
+ } else {
1019
+ // there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
1020
+ // therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
1021
+ #if SOC_UART_SUPPORT_XTAL_CLK
1022
+ newClkSrc = UART_SCLK_XTAL ; // valid for C2, S3, C3, C6, H2 and P4
1023
+ log_v ("Setting UART%d to use XTAL clock" , uart -> num );
1024
+ #elif SOC_UART_SUPPORT_REF_TICK
1025
+ if (baudrate <= REF_TICK_BAUDRATE_LIMIT ) {
1026
+ newClkSrc = UART_SCLK_REF_TICK ; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
1027
+ log_v ("Setting UART%d to use REF_TICK clock" , uart -> num );
1028
+ } else {
1029
+ newClkSrc = UART_SCLK_APB ; // baudrate may change with the APB Frequency!
1030
+ log_v ("Setting UART%d to use APB clock" , uart -> num );
1031
+ }
1032
+ #else
1033
+ // Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6|P4
1034
+ // using newClkSrc = UART_SCLK_DEFAULT as defined in the variable declaration
1035
+ log_v ("Setting UART%d to use DEFAULT clock" , uart -> num );
1036
+ #endif // SOC_UART_SUPPORT_XTAL_CLK
1037
+ }
1038
+ #endif // CONFIG_ARDUINO_SERIAL_FORCE_IDF_DEFAULT_CLOCK_SOURCE
999
1039
}
1000
- #endif
1001
- // ESP32-P4 demands an atomic operation for setting the clock source
1002
- HP_UART_SRC_CLK_ATOMIC () {
1003
- uart_ll_set_sclk (UART_LL_GET_HW (uart -> num ), newClkSrc );
1040
+ UART_MUTEX_LOCK ();
1041
+ // if necessary, set the correct UART Clock Source before changing the baudrate
1042
+ if (previousClkSrc != newClkSrc ) {
1043
+ HP_UART_SRC_CLK_ATOMIC () {
1044
+ uart_ll_set_sclk (UART_LL_GET_HW (uart -> num ), newClkSrc );
1045
+ }
1046
+ uart -> _uart_clock_source = newClkSrc ;
1004
1047
}
1005
- #else // ESP32, ESP32-S2
1006
- soc_module_clk_t newClkSrc = baud_rate <= REF_TICK_BAUDRATE_LIMIT ? SOC_MOD_CLK_REF_TICK : SOC_MOD_CLK_APB ;
1007
- uart_ll_set_sclk (UART_LL_GET_HW (uart -> num ), newClkSrc );
1008
- #endif
1009
1048
if (uart_set_baudrate (uart -> num , baud_rate ) == ESP_OK ) {
1010
1049
log_v ("Setting UART%d baud rate to %ld." , uart -> num , baud_rate );
1011
1050
uart -> _baudrate = baud_rate ;
0 commit comments