uart: seperate sclk and baudrate setting

pull/6275/head
Armando 2020-11-23 19:31:50 +08:00
rodzic fb8b905539
commit 05a4a8d864
9 zmienionych plików z 66 dodań i 35 usunięć

Wyświetl plik

@ -24,6 +24,7 @@
#include "freertos/ringbuf.h"
#include "hal/uart_hal.h"
#include "soc/uart_periph.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "driver/uart_select.h"
@ -84,6 +85,10 @@ static const char* UART_TAG = "uart";
.hw_enabled = false,\
}
#if SOC_UART_SUPPORT_RTC_CLK
#define RTC_ENABLED(uart_num) (BIT(uart_num))
#endif
typedef struct {
uart_event_type_t type; /*!< UART TX data type */
struct {
@ -158,6 +163,34 @@ static uart_context_t uart_context[UART_NUM_MAX] = {
static portMUX_TYPE uart_selectlock = portMUX_INITIALIZER_UNLOCKED;
#if SOC_UART_SUPPORT_RTC_CLK
static uint8_t rtc_enabled = 0;
static portMUX_TYPE rtc_num_spinlock = portMUX_INITIALIZER_UNLOCKED;
static void rtc_clk_enable(uart_port_t uart_num)
{
portENTER_CRITICAL(&rtc_num_spinlock);
if (!(rtc_enabled & RTC_ENABLED(uart_num))) {
rtc_enabled |= RTC_ENABLED(uart_num);
}
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
portEXIT_CRITICAL(&rtc_num_spinlock);
}
static void rtc_clk_disable(uart_port_t uart_num)
{
assert(rtc_enabled & RTC_ENABLED(uart_num));
portENTER_CRITICAL(&rtc_num_spinlock);
rtc_enabled &= ~RTC_ENABLED(uart_num);
if (rtc_enabled == 0) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
}
portEXIT_CRITICAL(&rtc_num_spinlock);
}
#endif
static void uart_module_enable(uart_port_t uart_num)
{
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
@ -236,10 +269,8 @@ 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)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
uart_sclk_t source_clk = 0;
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
uart_hal_get_sclk(&(uart_context[uart_num].hal), &source_clk);
uart_hal_set_baudrate(&(uart_context[uart_num].hal), source_clk, baud_rate);
uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate);
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
return ESP_OK;
}
@ -626,10 +657,15 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
UART_CHECK((uart_config->flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error", ESP_FAIL);
UART_CHECK((uart_config->data_bits < UART_DATA_BITS_MAX), "data bit error", ESP_FAIL);
uart_module_enable(uart_num);
#if SOC_UART_SUPPORT_RTC_CLK
if (uart_config->source_clk == UART_SCLK_RTC) {
rtc_clk_enable(uart_num);
}
#endif
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
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_baudrate(&(uart_context[uart_num].hal), uart_config->source_clk, uart_config->baud_rate);
uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate);
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_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits);
@ -1417,6 +1453,14 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
heap_caps_free(p_uart_obj[uart_num]);
p_uart_obj[uart_num] = NULL;
#if SOC_UART_SUPPORT_RTC_CLK
uart_sclk_t sclk = 0;
uart_hal_get_sclk(&(uart_context[uart_num].hal), &sclk);
if (sclk == UART_SCLK_RTC) {
rtc_clk_disable(uart_num);
}
#endif
uart_module_disable(uart_num);
return ESP_OK;
}

Wyświetl plik

@ -130,7 +130,8 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz)
esp_rom_uart_tx_wait_idle(uart_num);
rtc_clk_cpu_freq_set_config(&new_config);
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), UART_SCLK_APB, uart_baud);
uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_APB);
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud);
/* adjust RTOS ticks */
_xt_tick_divisor = cpu_freq_mhz * 1000000 / XT_TICK_PER_SEC;
vTaskDelay(2);
@ -142,7 +143,8 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz)
// return old freq.
esp_rom_uart_tx_wait_idle(uart_num);
rtc_clk_cpu_freq_set_config(&old_config);
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), UART_SCLK_APB, uart_baud);
uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_APB);
uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud);
_xt_tick_divisor = old_config.freq_mhz * 1000000 / XT_TICK_PER_SEC;
}

Wyświetl plik

@ -689,7 +689,8 @@ void esp_pm_impl_init(void)
#endif
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 */
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
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);
#endif // CONFIG_ESP_CONSOLE_UART
#ifdef CONFIG_PM_TRACE

Wyświetl plik

@ -191,7 +191,8 @@ TEST_CASE("light sleep duration is correct", "[deepsleep][ignore]")
TEST_CASE("light sleep and frequency switching", "[deepsleep]")
{
#ifndef CONFIG_PM_ENABLE
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), UART_SCLK_REF_TICK, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), UART_SCLK_REF_TICK);
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE);
#endif
rtc_cpu_freq_config_t config_xtal, config_default;

Wyświetl plik

@ -102,16 +102,13 @@ static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
*
* @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 source_clk The UART source clock. The source clock can be APB clock or REF_TICK.
* If the source clock is REF_TICK, the UART can still work when the APB changes.
*
* @return None
*/
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
{
uint32_t sclk_freq, clk_div;
uart_ll_set_sclk(hw, source_clk);
sclk_freq = uart_ll_get_sclk_freq(hw);
clk_div = ((sclk_freq) << 4) / baud;
// The baud-rate configuration register is divided into

Wyświetl plik

@ -99,16 +99,13 @@ static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
*
* @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 source_clk The UART source clock. The source clock can be APB clock or REF_TICK.
* If the source clock is REF_TICK, the UART can still work when the APB changes.
*
* @return None
*/
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
{
uint32_t sclk_freq, clk_div;
uart_ll_set_sclk(hw, source_clk);
sclk_freq = uart_ll_get_sclk_freq(hw);
clk_div = ((sclk_freq) << 4) / baud;
// The baud rate configuration register is divided into

Wyświetl plik

@ -129,17 +129,14 @@ static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw)
* @brief Configure the baud-rate.
*
* @param hw Beginning address of the peripheral registers.
* @param source_clk The UART source clock. The source clock can be APB clock, RTC clock or XTAL clock.
* If the source clock is RTC/XTAL, the UART can still work when the APB changes.
* @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX`
*
* @return None
*/
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud)
{
uint32_t sclk_freq, clk_div;
uart_ll_set_sclk(hw, source_clk);
sclk_freq = uart_ll_get_sclk_freq(hw);
clk_div = ((sclk_freq) << 4) / baud;
// The baud rate configuration register is divided into

Wyświetl plik

@ -200,12 +200,11 @@ void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk);
* @brief Configure the UART baud-rate and select the source clock
*
* @param hal Context of the HAL layer
* @param source_clk The UART source clock.
* @param baud_rate The baud-rate to be set
*
* @return None
*/
void uart_hal_set_baudrate(uart_hal_context_t *hal, uart_sclk_t source_clk, uint32_t baud_rate);
void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate);
/**
* @brief Configure the UART stop bit

Wyświetl plik

@ -14,17 +14,10 @@
// The HAL layer for UART (common part)
#include "hal/uart_hal.h"
#include "soc/rtc_cntl_reg.h"
void uart_hal_set_sclk(uart_hal_context_t *hal, uart_sclk_t sclk)
{
uart_ll_set_sclk(hal->dev, sclk);
#if SOC_UART_SUPPORT_RTC_CLK
if (sclk == UART_SCLK_RTC) {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
}
#endif
}
void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk)
@ -32,9 +25,9 @@ void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk)
uart_ll_get_sclk(hal->dev, sclk);
}
void uart_hal_set_baudrate(uart_hal_context_t *hal, uart_sclk_t source_clk, uint32_t baud_rate)
void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate)
{
uart_ll_set_baudrate(hal->dev, source_clk, baud_rate);
uart_ll_set_baudrate(hal->dev, baud_rate);
}
void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate)
@ -144,11 +137,11 @@ void uart_hal_set_loop_back(uart_hal_context_t *hal, bool loop_back_en)
void uart_hal_init(uart_hal_context_t *hal, int uart_num)
{
// Set clock source
// Set default clock source
uart_ll_set_sclk(hal->dev, UART_SCLK_APB);
// Set default baud: 115200, use APB clock.
const uint32_t baud_def = 115200;
uart_ll_set_baudrate(hal->dev, UART_SCLK_APB, baud_def);
uart_ll_set_baudrate(hal->dev, baud_def);
// Set UART mode.
uart_ll_set_mode(hal->dev, UART_MODE_UART);
// Disable UART parity