uart: move frequency of clock sources out of HAL

This commit is contained in:
Michael (XIAO Xufeng) 2022-07-28 10:47:13 +08:00
parent f8bcec07fa
commit 746f4b814c
26 changed files with 172 additions and 167 deletions

View File

@ -195,6 +195,18 @@ esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode);
*/ */
esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode);
/**
* @brief Get the frequency of a clock source for the UART
*
* @param sclk Clock source
* @param[out] out_freq_hz Output of frequency, in Hz
*
* @return
* - ESP_ERR_INVALID_ARG: if the clock source is not supported
* - otherwise ESP_OK
*/
esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz);
/** /**
* @brief Set UART baud rate. * @brief Set UART baud rate.
* *

View File

@ -17,6 +17,7 @@
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
#include "hal/uart_hal.h" #include "hal/uart_hal.h"
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/uart_periph.h" #include "soc/uart_periph.h"
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "driver/uart.h" #include "driver/uart.h"
@ -199,6 +200,47 @@ static void uart_module_disable(uart_port_t uart_num)
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
} }
esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz)
{
uint32_t freq;
switch (sclk) {
#if SOC_UART_SUPPORT_APB_CLK
case UART_SCLK_APB:
freq = esp_clk_apb_freq();
break;
#endif
#if SOC_UART_SUPPORT_AHB_CLK
case UART_SCLK_AHB:
freq = APB_CLK_FREQ; //This only exist on H2. Fix this when H2 MP is supported.
break;
#endif
#if SOC_UART_SUPPORT_PLL_F40M_CLK
case UART_SCLK_PLL_F40M:
freq = 40 * MHZ;
break;
#endif
#if SOC_UART_SUPPORT_REF_TICK
case UART_SCLK_REF_TICK:
freq = REF_CLK_FREQ;
break;
#endif
#if SOC_UART_SUPPORT_RTC_CLK
case UART_SCLK_RTC:
freq = RTC_CLK_FREQ;
break;
#endif
#if SOC_UART_SUPPORT_XTAL_CLK
case UART_SCLK_XTAL:
freq = esp_clk_xtal_freq();
break;
#endif
default:
return ESP_ERR_INVALID_ARG;
}
*out_freq_hz = freq;
return ESP_OK;
}
esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit)
{ {
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
@ -256,8 +298,16 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode)
esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
{ {
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
uart_sclk_t src_clk;
uint32_t sclk_freq;
uart_hal_get_sclk(&(uart_context[uart_num].hal), &src_clk);
esp_err_t err = uart_get_sclk_freq(src_clk, &sclk_freq);
assert(err == ESP_OK);
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate); uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate, sclk_freq);
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
return ESP_OK; return ESP_OK;
} }
@ -265,8 +315,16 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate) esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate)
{ {
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
uart_sclk_t src_clk;
uint32_t sclk_freq;
uart_hal_get_sclk(&(uart_context[uart_num].hal), &src_clk);
esp_err_t err = uart_get_sclk_freq(src_clk, &sclk_freq);
assert(err == ESP_OK);
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
uart_hal_get_baudrate(&(uart_context[uart_num].hal), baudrate); uart_hal_get_baudrate(&(uart_context[uart_num].hal), baudrate, sclk_freq);
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
return ESP_OK; return ESP_OK;
} }
@ -688,10 +746,14 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
periph_rtc_dig_clk8m_enable(); periph_rtc_dig_clk8m_enable();
} }
#endif #endif
uint32_t sclk_freq;
esp_err_t err = uart_get_sclk_freq(uart_config->source_clk, &sclk_freq);
assert(err == ESP_OK);
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
uart_hal_init(&(uart_context[uart_num].hal), uart_num); uart_hal_init(&(uart_context[uart_num].hal), uart_num);
uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_config->source_clk); uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_config->source_clk);
uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate); uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity); uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity);
uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits); uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits);
uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits); uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits);

View File

@ -17,6 +17,7 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/xtensa_timer.h" #include "freertos/xtensa_timer.h"
#include "driver/uart.h"
#include "unity.h" #include "unity.h"
#include "test_utils.h" #include "test_utils.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
@ -140,7 +141,10 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz)
esp_rom_uart_tx_wait_idle(uart_num); esp_rom_uart_tx_wait_idle(uart_num);
rtc_clk_cpu_freq_set_config(&new_config); rtc_clk_cpu_freq_set_config(&new_config);
uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_DEFAULT); uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_DEFAULT);
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud);
uint32_t sclk_freq;
TEST_ESP_OK(uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq));
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud, sclk_freq);
/* adjust RTOS ticks */ /* adjust RTOS ticks */
_xt_tick_divisor = cpu_freq_mhz * 1000000 / XT_TICK_PER_SEC; _xt_tick_divisor = cpu_freq_mhz * 1000000 / XT_TICK_PER_SEC;
vTaskDelay(2); vTaskDelay(2);
@ -153,7 +157,10 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz)
esp_rom_uart_tx_wait_idle(uart_num); esp_rom_uart_tx_wait_idle(uart_num);
rtc_clk_cpu_freq_set_config(&old_config); rtc_clk_cpu_freq_set_config(&old_config);
uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_DEFAULT); uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_DEFAULT);
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud);
uint32_t sclk_freq;
TEST_ESP_OK(uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq));
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud, sclk_freq);
_xt_tick_divisor = old_config.freq_mhz * 1000000 / XT_TICK_PER_SEC; _xt_tick_divisor = old_config.freq_mhz * 1000000 / XT_TICK_PER_SEC;
} }

View File

@ -20,6 +20,7 @@
#include "soc/rtc.h" #include "soc/rtc.h"
#include "hal/uart_ll.h" #include "hal/uart_ll.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "driver/uart.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
@ -732,7 +733,11 @@ void esp_pm_impl_init(void)
while(!uart_ll_is_tx_idle(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM))); while(!uart_ll_is_tx_idle(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM)));
/* When DFS is enabled, override system setting and use REFTICK as UART clock source */ /* When DFS is enabled, override system setting and use REFTICK as UART clock source */
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source); uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source);
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE);
uint32_t sclk_freq;
esp_err_t err = uart_get_sclk_freq(clk_source, &sclk_freq);
assert(err == ESP_OK);
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq);
#endif // CONFIG_ESP_CONSOLE_UART #endif // CONFIG_ESP_CONSOLE_UART
#ifdef CONFIG_PM_TRACE #ifdef CONFIG_PM_TRACE

View File

@ -15,6 +15,7 @@
#include "soc/gpio_periph.h" #include "soc/gpio_periph.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "hal/uart_ll.h" #include "hal/uart_ll.h"
#include "driver/uart.h"
#include "soc/rtc.h" // for wakeup trigger defines #include "soc/rtc.h" // for wakeup trigger defines
#include "soc/rtc_periph.h" // for read rtc registers directly (cause) #include "soc/rtc_periph.h" // for read rtc registers directly (cause)
#include "soc/soc.h" // for direct register read macros #include "soc/soc.h" // for direct register read macros
@ -208,7 +209,10 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
clk_source = UART_SCLK_XTAL; clk_source = UART_SCLK_XTAL;
#endif #endif
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source); uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source);
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE);
uint32_t sclk_freq;
TEST_ESP_OK(uart_get_sclk_freq(clk_source, &sclk_freq));
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq);
#endif #endif
rtc_cpu_freq_config_t config_xtal, config_default; rtc_cpu_freq_config_t config_xtal, config_default;

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for UART register operations. // The LL layer for UART register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
@ -89,31 +81,19 @@ FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
*source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK; *source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK;
} }
/**
* @brief Get the UART source clock frequency.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Current source clock frequency
*/
FORCE_INLINE_ATTR uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
{
return (hw->conf0.tick_ref_always_on) ? APB_CLK_FREQ : REF_CLK_FREQ;
}
/** /**
* @brief Configure the baud-rate. * @brief Configure the baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param baud The baud-rate to be set. When the source clock is APB, the max baud-rate is `UART_LL_BITRATE_MAX` * @param baud The baud-rate to be set. When the source clock is APB, the max baud-rate is `UART_LL_BITRATE_MAX`
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* @return None * @return None
*/ */
FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{ {
uint32_t sclk_freq, clk_div; uint32_t clk_div;
sclk_freq = uart_ll_get_sclk_freq(hw);
clk_div = ((sclk_freq) << 4) / baud; clk_div = ((sclk_freq) << 4) / baud;
// The baud-rate configuration register is divided into // The baud-rate configuration register is divided into
// an integer part and a fractional part. // an integer part and a fractional part.
@ -125,12 +105,12 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
* @brief Get the current baud-rate. * @brief Get the current baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return The current baudrate * @return The current baudrate
*/ */
FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw) FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
{ {
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
typeof(hw->clk_div) div_reg = hw->clk_div; typeof(hw->clk_div) div_reg = hw->clk_div;
return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag);
} }

View File

@ -11,7 +11,6 @@
#pragma once #pragma once
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "soc/uart_periph.h" #include "soc/uart_periph.h"
#include "hal/clk_tree_ll.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -142,38 +141,18 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
} }
} }
/**
* @brief Get the UART source clock frequency.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Current source clock frequency
*/
static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
{
switch (hw->clk_conf.sclk_sel) {
default:
case 1:
return APB_CLK_FREQ;
case 2:
return RTC_CLK_FREQ;
case 3:
return clk_ll_xtal_load_freq_mhz() * MHZ;
}
}
/** /**
* @brief Configure the baud-rate. * @brief Configure the baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set. * @param baud The baud rate to be set.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return None * @return None
*/ */
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{ {
#define DIV_UP(a, b) (((a) + (b) - 1) / (b)) #define DIV_UP(a, b) (((a) + (b) - 1) / (b))
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
int sclk_div = DIV_UP(sclk_freq, max_div * baud); int sclk_div = DIV_UP(sclk_freq, max_div * baud);
@ -190,12 +169,12 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
* @brief Get the current baud-rate. * @brief Get the current baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return The current baudrate * @return The current baudrate
*/ */
static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw) static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
{ {
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
typeof(hw->clk_div) div_reg = hw->clk_div; typeof(hw->clk_div) div_reg = hw->clk_div;
return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (hw->clk_conf.sclk_div_num + 1)); return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (hw->clk_conf.sclk_div_num + 1));
} }

View File

@ -144,38 +144,18 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
} }
} }
/**
* @brief Get the UART source clock frequency.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Current source clock frequency
*/
static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
{
switch (hw->clk_conf.sclk_sel) {
default:
case 1:
return APB_CLK_FREQ;
case 2:
return RTC_CLK_FREQ;
case 3:
return XTAL_CLK_FREQ;
}
}
/** /**
* @brief Configure the baud-rate. * @brief Configure the baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set. * @param baud The baud rate to be set.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return None * @return None
*/ */
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{ {
#define DIV_UP(a, b) (((a) + (b) - 1) / (b)) #define DIV_UP(a, b) (((a) + (b) - 1) / (b))
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
int sclk_div = DIV_UP(sclk_freq, max_div * baud); int sclk_div = DIV_UP(sclk_freq, max_div * baud);
@ -192,12 +172,12 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
* @brief Get the current baud-rate. * @brief Get the current baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return The current baudrate * @return The current baudrate
*/ */
static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw) static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
{ {
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
typeof(hw->clk_div) div_reg = hw->clk_div; typeof(hw->clk_div) div_reg = hw->clk_div;
return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1)); return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1));
} }

View File

@ -144,38 +144,18 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
} }
} }
/**
* @brief Get the UART source clock frequency.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Current source clock frequency
*/
static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
{
switch (hw->clk_conf.sclk_sel) {
default:
case 1:
return APB_CLK_FREQ;
case 2:
return RTC_CLK_FREQ;
case 3:
return XTAL_CLK_FREQ;
}
}
/** /**
* @brief Configure the baud-rate. * @brief Configure the baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set. * @param baud The baud rate to be set.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return None * @return None
*/ */
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{ {
#define DIV_UP(a, b) (((a) + (b) - 1) / (b)) #define DIV_UP(a, b) (((a) + (b) - 1) / (b))
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
int sclk_div = DIV_UP(sclk_freq, max_div * baud); int sclk_div = DIV_UP(sclk_freq, max_div * baud);
@ -192,12 +172,12 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
* @brief Get the current baud-rate. * @brief Get the current baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return The current baudrate * @return The current baudrate
*/ */
static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw) static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
{ {
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
typeof(hw->clk_div) div_reg = hw->clk_div; typeof(hw->clk_div) div_reg = hw->clk_div;
return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1)); return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1));
} }

View File

@ -79,31 +79,19 @@ FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk)
*source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK; *source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK;
} }
/**
* @brief Get the UART source clock frequency.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Current source clock frequency
*/
FORCE_INLINE_ATTR uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
{
return (hw->conf0.tick_ref_always_on) ? APB_CLK_FREQ : REF_CLK_FREQ;
}
/** /**
* @brief Configure the baud-rate. * @brief Configure the baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX` * @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX`
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* @return None * @return None
*/ */
FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{ {
uint32_t sclk_freq, clk_div; uint32_t clk_div;
sclk_freq = uart_ll_get_sclk_freq(hw);
clk_div = ((sclk_freq) << 4) / baud; clk_div = ((sclk_freq) << 4) / baud;
// The baud rate configuration register is divided into // The baud rate configuration register is divided into
// an integer part and a fractional part. // an integer part and a fractional part.
@ -115,12 +103,12 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
* @brief Get the current baud-rate. * @brief Get the current baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return The current baudrate * @return The current baudrate
*/ */
FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw) FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
{ {
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
typeof(hw->clk_div) div_reg = hw->clk_div; typeof(hw->clk_div) div_reg = hw->clk_div;
return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag);
} }

View File

@ -117,38 +117,18 @@ FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
} }
} }
/**
* @brief Get the UART source clock frequency.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Current source clock frequency
*/
FORCE_INLINE_ATTR uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
{
switch (hw->clk_conf.sclk_sel) {
default:
case 1:
return APB_CLK_FREQ;
case 2:
return RTC_CLK_FREQ;
case 3:
return XTAL_CLK_FREQ;
}
}
/** /**
* @brief Configure the baud-rate. * @brief Configure the baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set. * @param baud The baud rate to be set.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return None * @return None
*/ */
FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{ {
#define DIV_UP(a, b) (((a) + (b) - 1) / (b)) #define DIV_UP(a, b) (((a) + (b) - 1) / (b))
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
int sclk_div = DIV_UP(sclk_freq, max_div * baud); int sclk_div = DIV_UP(sclk_freq, max_div * baud);
@ -165,12 +145,12 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
* @brief Get the current baud-rate. * @brief Get the current baud-rate.
* *
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return The current baudrate * @return The current baudrate
*/ */
FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw) FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
{ {
uint32_t sclk_freq = uart_ll_get_sclk_freq(hw);
uart_clkdiv_reg_t div_reg = hw->clkdiv; uart_clkdiv_reg_t div_reg = hw->clkdiv;
return ((sclk_freq << 4)) / return ((sclk_freq << 4)) /
(((div_reg.clkdiv << 4) | div_reg.clkdiv_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1)); (((div_reg.clkdiv << 4) | div_reg.clkdiv_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1));

View File

@ -203,10 +203,11 @@ void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk);
* *
* @param hal Context of the HAL layer * @param hal Context of the HAL layer
* @param baud_rate The baud-rate to be set * @param baud_rate The baud-rate to be set
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return None * @return None
*/ */
void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate); void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate, uint32_t sclk_freq);
/** /**
* @brief Configure the UART stop bit * @brief Configure the UART stop bit
@ -408,10 +409,11 @@ void uart_hal_get_parity(uart_hal_context_t *hal, uart_parity_t *parity_mode);
* *
* @param hal Context of the HAL layer * @param hal Context of the HAL layer
* @param baud_rate Pointer to accept the current baud-rate * @param baud_rate Pointer to accept the current baud-rate
* @param sclk_freq Frequency of the clock source of UART, in Hz.
* *
* @return None * @return None
*/ */
void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate); void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate, uint32_t sclk_freq);
/** /**
* @brief Get the hw flow control configuration * @brief Get the hw flow control configuration

View File

@ -17,14 +17,14 @@ void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk)
uart_ll_get_sclk(hal->dev, sclk); uart_ll_get_sclk(hal->dev, sclk);
} }
void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate) void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate, uint32_t sclk_freq)
{ {
uart_ll_set_baudrate(hal->dev, baud_rate); uart_ll_set_baudrate(hal->dev, baud_rate, sclk_freq);
} }
void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate) void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate, uint32_t sclk_freq)
{ {
*baud_rate = uart_ll_get_baudrate(hal->dev); *baud_rate = uart_ll_get_baudrate(hal->dev, sclk_freq);
} }
void uart_hal_set_stop_bits(uart_hal_context_t *hal, uart_stop_bits_t stop_bit) void uart_hal_set_stop_bits(uart_hal_context_t *hal, uart_stop_bits_t stop_bit)
@ -131,9 +131,6 @@ void uart_hal_init(uart_hal_context_t *hal, int uart_num)
{ {
// Set default clock source // Set default clock source
uart_ll_set_sclk(hal->dev, UART_SCLK_DEFAULT); uart_ll_set_sclk(hal->dev, UART_SCLK_DEFAULT);
// Set default baud: 115200, use APB clock.
const uint32_t baud_def = 115200;
uart_ll_set_baudrate(hal->dev, baud_def);
// Set UART mode. // Set UART mode.
uart_ll_set_mode(hal->dev, UART_MODE_UART); uart_ll_set_mode(hal->dev, UART_MODE_UART);
// Disable UART parity // Disable UART parity

View File

@ -595,6 +595,10 @@ config SOC_UART_NUM
int int
default 3 default 3
config SOC_UART_SUPPORT_APB_CLK
bool
default y
config SOC_UART_SUPPORT_REF_TICK config SOC_UART_SUPPORT_REF_TICK
bool bool
default y default y

View File

@ -305,6 +305,7 @@
/*-------------------------- UART CAPS ---------------------------------------*/ /*-------------------------- UART CAPS ---------------------------------------*/
// ESP32 have 3 UART. // ESP32 have 3 UART.
#define SOC_UART_NUM (3) #define SOC_UART_NUM (3)
#define SOC_UART_SUPPORT_APB_CLK (1) /*!< Support APB as the clock source */
#define SOC_UART_SUPPORT_REF_TICK (1) /*!< Support REF_TICK as the clock source */ #define SOC_UART_SUPPORT_REF_TICK (1) /*!< Support REF_TICK as the clock source */
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */

View File

@ -495,6 +495,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
bool bool
default y default y
config SOC_UART_SUPPORT_PLL_F40M_CLK
bool
default y
config SOC_UART_SUPPORT_RTC_CLK config SOC_UART_SUPPORT_RTC_CLK
bool bool
default y default y

View File

@ -240,8 +240,9 @@
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_SUPPORT_RTC_CLK (1) #define SOC_UART_SUPPORT_PLL_F40M_CLK (1) /*!< Support APB as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)

View File

@ -723,6 +723,10 @@ config SOC_UART_BITRATE_MAX
int int
default 5000000 default 5000000
config SOC_UART_SUPPORT_APB_CLK
bool
default y
config SOC_UART_SUPPORT_RTC_CLK config SOC_UART_SUPPORT_RTC_CLK
bool bool
default y default y

View File

@ -334,8 +334,9 @@
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */
#define SOC_UART_SUPPORT_RTC_CLK (1) #define SOC_UART_SUPPORT_APB_CLK (1) /*!< Support APB as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_REQUIRE_CORE_RESET (1) #define SOC_UART_REQUIRE_CORE_RESET (1)

View File

@ -691,6 +691,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
bool bool
default y default y
config SOC_UART_SUPPORT_AHB_CLK
bool
default y
config SOC_UART_SUPPORT_RTC_CLK config SOC_UART_SUPPORT_RTC_CLK
bool bool
default y default y

View File

@ -333,8 +333,9 @@
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_SUPPORT_RTC_CLK (1) #define SOC_UART_SUPPORT_AHB_CLK (1) /*!< Support AHB as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)

View File

@ -691,6 +691,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
bool bool
default y default y
config SOC_UART_SUPPORT_APB_CLK
bool
default y
config SOC_UART_SUPPORT_REF_TICK config SOC_UART_SUPPORT_REF_TICK
bool bool
default y default y

View File

@ -306,6 +306,7 @@
// ESP32-S2 has 2 UART. // ESP32-S2 has 2 UART.
#define SOC_UART_NUM (2) #define SOC_UART_NUM (2)
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_SUPPORT_APB_CLK (1) /*!< Support APB as the clock source */
#define SOC_UART_SUPPORT_REF_TICK (1) /*!< Support REF_TICK as the clock source */ #define SOC_UART_SUPPORT_REF_TICK (1) /*!< Support REF_TICK as the clock source */
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */

View File

@ -787,6 +787,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
bool bool
default y default y
config SOC_UART_SUPPORT_APB_CLK
bool
default y
config SOC_UART_SUPPORT_RTC_CLK config SOC_UART_SUPPORT_RTC_CLK
bool bool
default y default y

View File

@ -322,6 +322,7 @@
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_SUPPORT_APB_CLK (1) /*!< Support APB as the clock source */
#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
#define SOC_UART_REQUIRE_CORE_RESET (1) #define SOC_UART_REQUIRE_CORE_RESET (1)

View File

@ -732,7 +732,6 @@ components/hal/esp32/include/hal/rwdt_ll.h
components/hal/esp32/include/hal/spi_flash_encrypted_ll.h components/hal/esp32/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32/include/hal/touch_sensor_hal.h components/hal/esp32/include/hal/touch_sensor_hal.h
components/hal/esp32/include/hal/trace_ll.h components/hal/esp32/include/hal/trace_ll.h
components/hal/esp32/include/hal/uart_ll.h
components/hal/esp32c3/hmac_hal.c components/hal/esp32c3/hmac_hal.c
components/hal/esp32c3/include/hal/aes_ll.h components/hal/esp32c3/include/hal/aes_ll.h
components/hal/esp32c3/include/hal/ds_ll.h components/hal/esp32c3/include/hal/ds_ll.h