Skip to content

Add an option to force IDF's default UART clock source #11191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Apr 9, 2025
Merged
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ddc95d9
Add an option to force IDF's default UART clock source
gonzabrusco Mar 27, 2025
a990f65
Merge branch 'master' into serial_clk_select
gonzabrusco Mar 28, 2025
bb136c8
Merge branch 'master' into serial_clk_select
SuGlider Mar 31, 2025
f64ded2
feat(uart): adds function to set clock source
SuGlider Apr 2, 2025
00e9826
Merge branch 'master' into serial_clk_select
SuGlider Apr 2, 2025
baced53
feat(uart): add uart clock source selection method
SuGlider Apr 2, 2025
36efd18
feat(uart): add uart hall function to set the uart clock source
SuGlider Apr 2, 2025
d860572
feat(uart): add function to set the uart clock source
SuGlider Apr 2, 2025
667dcac
feat(uart): set clock source as necessary
SuGlider Apr 2, 2025
720747f
fix(uart): missing class qualifier declaration
SuGlider Apr 2, 2025
e9bf067
fix(uart): fixing a typo and non LP UART SoC clk src setting
SuGlider Apr 2, 2025
858c0c2
fix(uart): variable name, typo error
SuGlider Apr 2, 2025
a7c6054
fix(uart): retores previous identation reducing diff load
SuGlider Apr 2, 2025
d8526f8
feat(uart): apply CONFIG_ARDUINO_SERIAL_FORCE_IDF_DEFAULT_CLOCK_SOURC…
SuGlider Apr 2, 2025
513d67f
feat(uart): adds option for UART_CLK_SRC_DEFAULT
SuGlider Apr 2, 2025
0fe2b60
feat(uart): adds option for setting default uart clock source from IDF
SuGlider Apr 2, 2025
3264693
feat(uart): documents UART_CLK_SRC_DEFAULT as option in header file
SuGlider Apr 2, 2025
4d7afe8
feat(uart): documents using the IDF default uart clock source
SuGlider Apr 2, 2025
673eff2
fix(uart): type missmatch may cause error
SuGlider Apr 2, 2025
5ed541d
fix(uart): type missmatch may cause error, test for -1
SuGlider Apr 2, 2025
530fcd0
feat(uart): considering both HP and LP default uart clock source
SuGlider Apr 2, 2025
7715d40
feat(uart): improve the defined value for UART_CLK_SRC_DEFAULT
SuGlider Apr 2, 2025
4c6d92c
fix(uart): using uart_sclk_t as hal level parameter
SuGlider Apr 2, 2025
291358d
feat(uart): apply default LP uart clock source
SuGlider Apr 2, 2025
3e549d6
fix(uart): considers that it may set the LP UART as well
SuGlider Apr 2, 2025
0651cd5
feat(uart): using UART SCLK enum for uart clock source values
SuGlider Apr 2, 2025
145b0a1
fix(uart): using UART_CLK_SRC_RTC now
SuGlider Apr 2, 2025
5857606
fix(uart): documentation using UART_CLK_SRC_RTC now
SuGlider Apr 2, 2025
4a93111
fix(uart): fix old commentary that is not correct anymore
SuGlider Apr 3, 2025
25b0326
fix(uart): wrong identation in code line
SuGlider Apr 3, 2025
05337af
fix(uart): using uart number as argument instead
SuGlider Apr 3, 2025
aa7a37f
fix(uart): using uart number as argument in setClockSource()
SuGlider Apr 3, 2025
57410d8
fix(uart): using uart number as parameter in uartSetClockSource()
SuGlider Apr 3, 2025
9e1ae8e
feat(uart): update Kconfig.projbuild to reflect functionality
SuGlider Apr 4, 2025
4279699
feat(uart): removing Kconfig.projbuild option to force default clk src
SuGlider Apr 4, 2025
589fa60
feat(uart): removes kconfig option to force uart default clk src
SuGlider Apr 4, 2025
f5918e1
Merge branch 'master' into serial_clk_select
SuGlider Apr 5, 2025
84da5d8
fix(uart): replacing #if #endif by #if #elif #endif for the same enum
SuGlider Apr 6, 2025
3e78c46
ci(pre-commit): Apply automatic fixes
pre-commit-ci-lite[bot] Apr 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(uart): add function to set the uart clock source
  • Loading branch information
SuGlider authored Apr 2, 2025
commit d86057255075463e86a459b356249d1a6845e482
92 changes: 66 additions & 26 deletions cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct uart_struct_t {
uint16_t _rx_buffer_size, _tx_buffer_size; // UART RX and TX buffer sizes
bool _inverted; // UART inverted signal
uint8_t _rxfifo_full_thrhd; // UART RX FIFO full threshold
int8_t _uart_clock_source; // UART Clock Source used when it is started using uartBegin()
};

#if CONFIG_DISABLE_HAL_LOCKS
Expand All @@ -66,21 +67,21 @@ struct uart_struct_t {
#define UART_MUTEX_UNLOCK()

static uart_t _uart_bus_array[] = {
{0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#if SOC_UART_NUM > 1
{1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 2
{2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 3
{3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 4
{4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 5
{5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
};

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

static uart_t _uart_bus_array[] = {
{NULL, 0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{NULL, 0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#if SOC_UART_NUM > 1
{NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 2
{NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 3
{NULL, 3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{NULL, 3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 4
{NULL, 4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{NULL, 4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 5
{NULL, 5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
{NULL, 5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
};

Expand Down Expand Up @@ -665,8 +666,12 @@ uart_t *uartBegin(
uart_config.baud_rate = baudrate;
#if SOC_UART_LP_NUM >= 1
if (uart_nr >= SOC_UART_HP_NUM) { // it is a LP UART NUM
uart_config.lp_source_clk = LP_UART_SCLK_DEFAULT; // use default LP clock
log_v("Setting UART%d to use LP clock", uart_nr);
if (uart->_uart_clock_source > 0) {
uart_config.lp_source_clk = (soc_periph_lp_uart_clk_src_t) uart->_uart_clock_source; // use user defined LP UART clock
} else {
uart_config.lp_source_clk = LP_UART_SCLK_DEFAULT; // use default LP clock
}
log_v("Setting UART%d to use LP clock (%d) ", uart_nr, uart_config.lp_source_clk);
} else
#endif
{
Expand All @@ -675,25 +680,29 @@ uart_t *uartBegin(
uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use DEFAULT clock", uart_nr);
#else
if (uart->_uart_clock_source > 0) {
uart_config.source_clk = (soc_module_clk_t) uart->_uart_clock_source; // use user defined HP UART clock
} else {
// there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
// therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
#if SOC_UART_SUPPORT_XTAL_CLK
uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4
log_v("Setting UART%d to use XTAL clock", uart_nr);
uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4
log_v("Setting UART%d to use XTAL clock", uart_nr);
#elif SOC_UART_SUPPORT_REF_TICK
if (baudrate <= REF_TICK_BAUDRATE_LIMIT) {
uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
log_v("Setting UART%d to use REF_TICK clock", uart_nr);
} else {
uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use APB clock", uart_nr);
}
if (baudrate <= REF_TICK_BAUDRATE_LIMIT) {
uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
log_v("Setting UART%d to use REF_TICK clock", uart_nr);
} else {
uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use APB clock", uart_nr);
}
#else
// 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
uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use DEFAULT clock", uart_nr);
// 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
uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use DEFAULT clock", uart_nr);
#endif
#endif
}
}

UART_MUTEX_LOCK();
Expand Down Expand Up @@ -1090,6 +1099,37 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) {
return retCode;
}

// this function will set the uart clock source
// it must be called before uartBegin(), otherwise it won't change any thing.
bool uartSetClockSource(uart_t *uart, uart_sclk_t clkSrc) {
if (uart == NULL) {
return false;
}
if (uart_is_driver_installed(uart->num)) {
log_e("No Clock Source change was done. This function must be called before beginning UART%d.", uart->num);
return false;
}
#if SOC_UART_LP_NUM >= 1
if (uart->num > >= SOC_UART_HP_NUM) {
switch (clkSrc) {
case UART_SCLK_XTAL:
uart->_uart_clock_source = SOC_MOD_CLK_XTAL_D2;
break;
case UART_SCLK_RTC:
uart->_uart_clock_source = SOC_MOD_CLK_RTC_FAST;
break;
default:
uart->_uart_clock_source = -1;
}
} else
#else
{
uart->_uart_clock_source = clkSrc;
}
#endif
return true;
}

void uartSetDebug(uart_t *uart) {
// LP UART is not supported for debug
if (uart == NULL || uart->num >= SOC_UART_HP_NUM) {
Expand Down
Loading