Skip to content

Commit d860572

Browse files
authored
feat(uart): add function to set the uart clock source
1 parent 36efd18 commit d860572

File tree

1 file changed

+66
-26
lines changed

1 file changed

+66
-26
lines changed

cores/esp32/esp32-hal-uart.c

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct uart_struct_t {
5858
uint16_t _rx_buffer_size, _tx_buffer_size; // UART RX and TX buffer sizes
5959
bool _inverted; // UART inverted signal
6060
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()
6162
};
6263

6364
#if CONFIG_DISABLE_HAL_LOCKS
@@ -66,21 +67,21 @@ struct uart_struct_t {
6667
#define UART_MUTEX_UNLOCK()
6768

6869
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},
7071
#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},
7273
#endif
7374
#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},
7576
#endif
7677
#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},
7879
#endif
7980
#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},
8182
#endif
8283
#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},
8485
#endif
8586
};
8687

@@ -95,21 +96,21 @@ static uart_t _uart_bus_array[] = {
9596
xSemaphoreGive(uart->lock)
9697

9798
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},
99100
#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},
101102
#endif
102103
#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},
104105
#endif
105106
#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},
107108
#endif
108109
#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},
110111
#endif
111112
#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},
113114
#endif
114115
};
115116

@@ -665,8 +666,12 @@ uart_t *uartBegin(
665666
uart_config.baud_rate = baudrate;
666667
#if SOC_UART_LP_NUM >= 1
667668
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);
670675
} else
671676
#endif
672677
{
@@ -675,25 +680,29 @@ uart_t *uartBegin(
675680
uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency!
676681
log_v("Setting UART%d to use DEFAULT clock", uart_nr);
677682
#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 {
678686
// there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
679687
// therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
680688
#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);
683691
#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+
}
691699
#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);
695703
#endif
696704
#endif
705+
}
697706
}
698707

699708
UART_MUTEX_LOCK();
@@ -1090,6 +1099,37 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) {
10901099
return retCode;
10911100
}
10921101

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+
10931133
void uartSetDebug(uart_t *uart) {
10941134
// LP UART is not supported for debug
10951135
if (uart == NULL || uart->num >= SOC_UART_HP_NUM) {

0 commit comments

Comments
 (0)