kopia lustrzana https://github.com/espressif/esp-idf
uart: seperate sclk and baudrate setting
rodzic
fb8b905539
commit
05a4a8d864
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue