@@ -58,6 +58,7 @@ struct uart_struct_t {
58
58
uint16_t _rx_buffer_size , _tx_buffer_size ; // UART RX and TX buffer sizes
59
59
bool _inverted ; // UART inverted signal
60
60
uint8_t _rxfifo_full_thrhd ; // UART RX FIFO full threshold
61
+ int8_t _uart_clock_source ; // UART Clock Source used when it is started using uartBegin()
61
62
};
62
63
63
64
#if CONFIG_DISABLE_HAL_LOCKS
@@ -66,21 +67,21 @@ struct uart_struct_t {
66
67
#define UART_MUTEX_UNLOCK ()
67
68
68
69
static uart_t _uart_bus_array [] = {
69
- {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
70
+ {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
70
71
#if SOC_UART_NUM > 1
71
- {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
72
+ {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
72
73
#endif
73
74
#if SOC_UART_NUM > 2
74
- {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
75
+ {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
75
76
#endif
76
77
#if SOC_UART_NUM > 3
77
- {3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
78
+ {3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
78
79
#endif
79
80
#if SOC_UART_NUM > 4
80
- {4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
81
+ {4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
81
82
#endif
82
83
#if SOC_UART_NUM > 5
83
- {5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
84
+ {5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
84
85
#endif
85
86
};
86
87
@@ -95,21 +96,21 @@ static uart_t _uart_bus_array[] = {
95
96
xSemaphoreGive(uart->lock)
96
97
97
98
static uart_t _uart_bus_array [] = {
98
- {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
99
+ {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
99
100
#if SOC_UART_NUM > 1
100
- {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
101
+ {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
101
102
#endif
102
103
#if SOC_UART_NUM > 2
103
- {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
104
+ {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
104
105
#endif
105
106
#if SOC_UART_NUM > 3
106
- {NULL , 3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
107
+ {NULL , 3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
107
108
#endif
108
109
#if SOC_UART_NUM > 4
109
- {NULL , 4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
110
+ {NULL , 4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
110
111
#endif
111
112
#if SOC_UART_NUM > 5
112
- {NULL , 5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
113
+ {NULL , 5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
113
114
#endif
114
115
};
115
116
@@ -665,8 +666,12 @@ uart_t *uartBegin(
665
666
uart_config .baud_rate = baudrate ;
666
667
#if SOC_UART_LP_NUM >= 1
667
668
if (uart_nr >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
668
- uart_config .lp_source_clk = LP_UART_SCLK_DEFAULT ; // use default LP clock
669
- log_v ("Setting UART%d to use LP clock" , uart_nr );
669
+ if (uart -> _uart_clock_source > 0 ) {
670
+ uart_config .lp_source_clk = (soc_periph_lp_uart_clk_src_t ) uart -> _uart_clock_source ; // use user defined LP UART clock
671
+ } else {
672
+ uart_config .lp_source_clk = LP_UART_SCLK_DEFAULT ; // use default LP clock
673
+ }
674
+ log_v ("Setting UART%d to use LP clock (%d) " , uart_nr , uart_config .lp_source_clk );
670
675
} else
671
676
#endif
672
677
{
@@ -675,25 +680,29 @@ uart_t *uartBegin(
675
680
uart_config .source_clk = UART_SCLK_DEFAULT ; // baudrate may change with the APB Frequency!
676
681
log_v ("Setting UART%d to use DEFAULT clock" , uart_nr );
677
682
#else
683
+ if (uart -> _uart_clock_source > 0 ) {
684
+ uart_config .source_clk = (soc_module_clk_t ) uart -> _uart_clock_source ; // use user defined HP UART clock
685
+ } else {
678
686
// there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
679
687
// therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
680
688
#if SOC_UART_SUPPORT_XTAL_CLK
681
- uart_config .source_clk = UART_SCLK_XTAL ; // valid for C2, S3, C3, C6, H2 and P4
682
- log_v ("Setting UART%d to use XTAL clock" , uart_nr );
689
+ uart_config .source_clk = UART_SCLK_XTAL ; // valid for C2, S3, C3, C6, H2 and P4
690
+ log_v ("Setting UART%d to use XTAL clock" , uart_nr );
683
691
#elif SOC_UART_SUPPORT_REF_TICK
684
- if (baudrate <= REF_TICK_BAUDRATE_LIMIT ) {
685
- uart_config .source_clk = UART_SCLK_REF_TICK ; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
686
- log_v ("Setting UART%d to use REF_TICK clock" , uart_nr );
687
- } else {
688
- uart_config .source_clk = UART_SCLK_APB ; // baudrate may change with the APB Frequency!
689
- log_v ("Setting UART%d to use APB clock" , uart_nr );
690
- }
692
+ if (baudrate <= REF_TICK_BAUDRATE_LIMIT ) {
693
+ uart_config .source_clk = UART_SCLK_REF_TICK ; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
694
+ log_v ("Setting UART%d to use REF_TICK clock" , uart_nr );
695
+ } else {
696
+ uart_config .source_clk = UART_SCLK_APB ; // baudrate may change with the APB Frequency!
697
+ log_v ("Setting UART%d to use APB clock" , uart_nr );
698
+ }
691
699
#else
692
- // 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
693
- uart_config .source_clk = UART_SCLK_DEFAULT ; // baudrate may change with the APB Frequency!
694
- log_v ("Setting UART%d to use DEFAULT clock" , uart_nr );
700
+ // 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
+ uart_config .source_clk = UART_SCLK_DEFAULT ; // baudrate may change with the APB Frequency!
702
+ log_v ("Setting UART%d to use DEFAULT clock" , uart_nr );
695
703
#endif
696
704
#endif
705
+ }
697
706
}
698
707
699
708
UART_MUTEX_LOCK ();
@@ -1090,6 +1099,37 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) {
1090
1099
return retCode ;
1091
1100
}
1092
1101
1102
+ // this function will set the uart clock source
1103
+ // it must be called before uartBegin(), otherwise it won't change any thing.
1104
+ bool uartSetClockSource (uart_t * uart , uart_sclk_t clkSrc ) {
1105
+ if (uart == NULL ) {
1106
+ return false;
1107
+ }
1108
+ if (uart_is_driver_installed (uart -> num )) {
1109
+ log_e ("No Clock Source change was done. This function must be called before beginning UART%d." , uart -> num );
1110
+ return false;
1111
+ }
1112
+ #if SOC_UART_LP_NUM >= 1
1113
+ if (uart -> num > >= SOC_UART_HP_NUM ) {
1114
+ switch (clkSrc ) {
1115
+ case UART_SCLK_XTAL :
1116
+ uart -> _uart_clock_source = SOC_MOD_CLK_XTAL_D2 ;
1117
+ break ;
1118
+ case UART_SCLK_RTC :
1119
+ uart -> _uart_clock_source = SOC_MOD_CLK_RTC_FAST ;
1120
+ break ;
1121
+ default :
1122
+ uart -> _uart_clock_source = -1 ;
1123
+ }
1124
+ } else
1125
+ #else
1126
+ {
1127
+ uart -> _uart_clock_source = clkSrc ;
1128
+ }
1129
+ #endif
1130
+ return true;
1131
+ }
1132
+
1093
1133
void uartSetDebug (uart_t * uart ) {
1094
1134
// LP UART is not supported for debug
1095
1135
if (uart == NULL || uart -> num >= SOC_UART_HP_NUM ) {
0 commit comments