feat(uart): spilt LP and HP uart set_baudrate function

This commit is contained in:
gaoxu
2023-09-26 17:42:03 +08:00
parent 4f24f805cc
commit bc2a6bd730
17 changed files with 155 additions and 119 deletions

View File

@@ -7,27 +7,28 @@
#pragma once #pragma once
#include "sdkconfig.h" #include "soc/soc_caps.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#if (SOC_UART_LP_NUM >= 1)
#define LP_UART_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#endif
#if SOC_PERIPH_CLK_CTRL_SHARED #if SOC_PERIPH_CLK_CTRL_SHARED
#define UART_SCLK_ATOMIC() PERIPH_RCC_ATOMIC() #define HP_UART_SRC_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#else #else
#define UART_SCLK_ATOMIC() #define HP_UART_SRC_CLK_ATOMIC()
#endif #endif
#if SOC_RCC_IS_INDEPENDENT #if SOC_RCC_IS_INDEPENDENT
#define UART_CLK_ATOMIC() #define HP_UART_BUS_CLK_ATOMIC()
#else #else
#define UART_CLK_ATOMIC() PERIPH_RCC_ATOMIC() #define HP_UART_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#endif
#if (SOC_UART_LP_NUM >= 1)
#define LP_UART_SRC_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#define LP_UART_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -179,24 +179,24 @@ static void uart_module_enable(uart_port_t uart_num)
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
if (uart_context[uart_num].hw_enabled != true) { if (uart_context[uart_num].hw_enabled != true) {
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {
UART_CLK_ATOMIC() { HP_UART_BUS_CLK_ATOMIC() {
uart_ll_enable_bus_clock(uart_num, true); uart_ll_enable_bus_clock(uart_num, true);
} }
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) { if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) {
// Workaround for ESP32C3/S3: enable core reset before enabling uart module clock to prevent uart output // Workaround for ESP32C3/S3: enable core reset before enabling uart module clock to prevent uart output
// garbage value. // garbage value.
#if SOC_UART_REQUIRE_CORE_RESET #if SOC_UART_REQUIRE_CORE_RESET
UART_SCLK_ATOMIC(){ HP_UART_SRC_CLK_ATOMIC(){
uart_hal_set_reset_core(&(uart_context[uart_num].hal), true); uart_hal_set_reset_core(&(uart_context[uart_num].hal), true);
} }
UART_CLK_ATOMIC() { HP_UART_BUS_CLK_ATOMIC() {
uart_ll_reset_register(uart_num); uart_ll_reset_register(uart_num);
} }
UART_SCLK_ATOMIC(){ HP_UART_SRC_CLK_ATOMIC(){
uart_hal_set_reset_core(&(uart_context[uart_num].hal), false); uart_hal_set_reset_core(&(uart_context[uart_num].hal), false);
} }
#else #else
UART_CLK_ATOMIC() { HP_UART_BUS_CLK_ATOMIC() {
uart_ll_reset_register(uart_num); uart_ll_reset_register(uart_num);
} }
#endif #endif
@@ -204,7 +204,7 @@ static void uart_module_enable(uart_port_t uart_num)
} }
#if (SOC_UART_LP_NUM >= 1) #if (SOC_UART_LP_NUM >= 1)
else { else {
LP_UART_CLK_ATOMIC() { LP_UART_BUS_CLK_ATOMIC() {
lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, true); lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, true);
lp_uart_ll_reset_register(uart_num - SOC_UART_HP_NUM); lp_uart_ll_reset_register(uart_num - SOC_UART_HP_NUM);
} }
@@ -220,13 +220,13 @@ static void uart_module_disable(uart_port_t uart_num)
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
if (uart_context[uart_num].hw_enabled != false) { if (uart_context[uart_num].hw_enabled != false) {
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) { if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
UART_CLK_ATOMIC() { HP_UART_BUS_CLK_ATOMIC() {
uart_ll_enable_bus_clock(uart_num, false); uart_ll_enable_bus_clock(uart_num, false);
} }
} }
#if (SOC_UART_LP_NUM >= 1) #if (SOC_UART_LP_NUM >= 1)
else if (uart_num >= SOC_UART_HP_NUM) { else if (uart_num >= SOC_UART_HP_NUM) {
LP_UART_CLK_ATOMIC() { LP_UART_BUS_CLK_ATOMIC() {
lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, false); lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, false);
} }
} }
@@ -306,9 +306,18 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "Invalid src_clk"); ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "Invalid src_clk");
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
UART_SCLK_ATOMIC() {
uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate, sclk_freq); if (uart_num < SOC_UART_HP_NUM) {
HP_UART_SRC_CLK_ATOMIC() {
uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate, sclk_freq);
}
} }
#if (SOC_UART_LP_NUM >= 1)
else {
lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, baud_rate, sclk_freq);
}
#endif
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
return ESP_OK; return ESP_OK;
} }
@@ -818,20 +827,19 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
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);
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {
UART_SCLK_ATOMIC() { HP_UART_SRC_CLK_ATOMIC() {
uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel); uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel);
uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
} }
} }
#if (SOC_UART_LP_NUM >= 1) #if (SOC_UART_LP_NUM >= 1)
else { else {
LP_UART_CLK_ATOMIC() { LP_UART_SRC_CLK_ATOMIC() {
lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel); lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel);
} }
lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, uart_config->baud_rate, sclk_freq);
} }
#endif #endif
UART_SCLK_ATOMIC() {
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

@@ -43,7 +43,6 @@
#include "esp_private/sleep_cpu.h" #include "esp_private/sleep_cpu.h"
#include "esp_private/sleep_gpio.h" #include "esp_private/sleep_gpio.h"
#include "esp_private/sleep_modem.h" #include "esp_private/sleep_modem.h"
#include "esp_private/periph_ctrl.h"
#include "esp_sleep.h" #include "esp_sleep.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@@ -742,13 +741,13 @@ void esp_pm_impl_init(void)
; ;
} }
/* 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_SCLK_ATOMIC() { HP_UART_SRC_CLK_ATOMIC() {
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source); uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source);
} }
uint32_t sclk_freq; uint32_t sclk_freq;
esp_err_t err = uart_get_sclk_freq(clk_source, &sclk_freq); esp_err_t err = uart_get_sclk_freq(clk_source, &sclk_freq);
assert(err == ESP_OK); assert(err == ESP_OK);
UART_SCLK_ATOMIC() { HP_UART_SRC_CLK_ATOMIC() {
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq); 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

View File

@@ -34,6 +34,8 @@ void esp_rom_uart_tx_wait_idle(uint8_t uart_no);
* @param uart_no UART port number * @param uart_no UART port number
* @param clock_hz Source clock (in Hz) * @param clock_hz Source clock (in Hz)
* @param baud_rate Baud rate to set * @param baud_rate Baud rate to set
*
* @note Only for HP UART
*/ */
#define esp_rom_uart_set_clock_baudrate(uart_no, clock_hz, baud_rate) uart_ll_set_baudrate(UART_LL_GET_HW(uart_no), baud_rate, clock_hz) #define esp_rom_uart_set_clock_baudrate(uart_no, clock_hz, baud_rate) uart_ll_set_baudrate(UART_LL_GET_HW(uart_no), baud_rate, clock_hz)

View File

@@ -91,7 +91,6 @@
#include "esp_cpu.h" #include "esp_cpu.h"
#include "esp_private/esp_clk.h" #include "esp_private/esp_clk.h"
#include "spi_flash_mmap.h" #include "spi_flash_mmap.h"
#include "esp_private/periph_ctrl.h"
#if CONFIG_ESP32_TRAX || CONFIG_ESP32S2_TRAX || CONFIG_ESP32S3_TRAX #if CONFIG_ESP32_TRAX || CONFIG_ESP32S2_TRAX || CONFIG_ESP32S3_TRAX
#include "esp_private/trax.h" #include "esp_private/trax.h"

View File

@@ -230,12 +230,12 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
#elif SOC_UART_SUPPORT_XTAL_CLK #elif SOC_UART_SUPPORT_XTAL_CLK
clk_source = UART_SCLK_XTAL; clk_source = UART_SCLK_XTAL;
#endif #endif
UART_SCLK_ATOMIC() { HP_UART_SRC_CLK_ATOMIC() {
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source); uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source);
} }
uint32_t sclk_freq; uint32_t sclk_freq;
TEST_ESP_OK(uart_get_sclk_freq(clk_source, &sclk_freq)); TEST_ESP_OK(uart_get_sclk_freq(clk_source, &sclk_freq));
UART_SCLK_ATOMIC() { HP_UART_SRC_CLK_ATOMIC() {
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq); uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq);
} }
#endif #endif

View File

@@ -11,7 +11,6 @@
#pragma once #pragma once
#include <stdlib.h> #include <stdlib.h>
#include "hal/assert.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
@@ -66,7 +65,6 @@ typedef enum {
*/ */
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{ {
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST : uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST :
(uart_num == 1) ? DPORT_UART1_RST : (uart_num == 1) ? DPORT_UART1_RST :
(uart_num == 2) ? DPORT_UART2_RST : 0); (uart_num == 2) ? DPORT_UART2_RST : 0);
@@ -85,8 +83,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
reg_val = reg_val & (~DPORT_UART_CLK_EN); reg_val = reg_val & (~DPORT_UART_CLK_EN);
reg_val = reg_val | (enable << 2); reg_val = reg_val | (enable << 2);
@@ -113,8 +110,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);

View File

@@ -12,7 +12,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/assert.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
#include "soc/uart_struct.h" #include "soc/uart_struct.h"
#include "soc/clk_tree_defs.h" #include "soc/clk_tree_defs.h"
@@ -69,7 +68,6 @@ typedef enum {
*/ */
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{ {
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST : uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST :
(uart_num == 1) ? SYSTEM_UART1_RST : 0); (uart_num == 1) ? SYSTEM_UART1_RST : 0);
uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN : uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN :
@@ -85,8 +83,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
*/ */
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
SYSTEM.perip_clk_en0.uart_clk_en = enable; SYSTEM.perip_clk_en0.uart_clk_en = enable;
break; break;
@@ -107,8 +104,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
SYSTEM.perip_rst_en0.uart_rst = 1; SYSTEM.perip_rst_en0.uart_rst = 1;
SYSTEM.perip_rst_en0.uart_rst = 0; SYSTEM.perip_rst_en0.uart_rst = 0;

View File

@@ -11,7 +11,6 @@
#pragma once #pragma once
#include <stdlib.h> #include <stdlib.h>
#include "hal/assert.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
@@ -69,7 +68,6 @@ typedef enum {
*/ */
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{ {
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST : uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST :
(uart_num == 1) ? SYSTEM_UART1_RST : 0); (uart_num == 1) ? SYSTEM_UART1_RST : 0);
uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN : uint32_t uart_en_bit = ((uart_num == 0) ? SYSTEM_UART_CLK_EN :
@@ -85,8 +83,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
*/ */
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
SYSTEM.perip_clk_en0.reg_uart_clk_en = enable; SYSTEM.perip_clk_en0.reg_uart_clk_en = enable;
break; break;
@@ -107,8 +104,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
SYSTEM.perip_rst_en0.reg_uart_rst = 1; SYSTEM.perip_rst_en0.reg_uart_rst = 1;
SYSTEM.perip_rst_en0.reg_uart_rst = 0; SYSTEM.perip_rst_en0.reg_uart_rst = 0;

View File

@@ -85,6 +85,19 @@ typedef enum {
UART_INTR_WAKEUP = (0x1 << 19), UART_INTR_WAKEUP = (0x1 << 19),
} uart_intr_t; } uart_intr_t;
/**
* @brief Sync the update to UART core clock domain
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
{
hw->reg_update.reg_update = 1;
while (hw->reg_update.reg_update);
}
/****************************************** LP_UART Specific ********************************************/ /****************************************** LP_UART Specific ********************************************/
/** /**
* @brief Get the LP_UART source clock. * @brief Get the LP_UART source clock.
@@ -131,6 +144,32 @@ static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_
/// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way /// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way
#define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__) #define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__)
/**
* @brief Configure the lp uart baud-rate.
*
* @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
*
* @return None
*/
FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{
#define DIV_UP(a, b) (((a) + (b) - 1) / (b))
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud);
if (sclk_div == 0) abort();
uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div);
// The baud rate configuration register is divided into
// an integer part and a fractional part.
hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
uart_ll_update(hw);
}
/** /**
* @brief Enable bus clock for the LP UART module * @brief Enable bus clock for the LP UART module
* *
@@ -190,8 +229,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
*/ */
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
PCR.uart0_conf.uart0_clk_en = enable; PCR.uart0_conf.uart0_clk_en = enable;
break; break;
@@ -211,8 +249,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
PCR.uart0_conf.uart0_rst_en = 1; PCR.uart0_conf.uart0_rst_en = 1;
PCR.uart0_conf.uart0_rst_en = 0; PCR.uart0_conf.uart0_rst_en = 0;
@@ -228,19 +265,6 @@ static inline void uart_ll_reset_register(uart_port_t uart_num)
} }
} }
/**
* @brief Sync the update to UART core clock domain
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
{
hw->reg_update.reg_update = 1;
while (hw->reg_update.reg_update);
}
/** /**
* @brief Configure the UART core reset. * @brief Configure the UART core reset.
* *
@@ -382,7 +406,7 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3
hw->clkdiv_sync.clkdiv_int = clk_div >> 4; hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
if ((hw) == &LP_UART) { if ((hw) == &LP_UART) {
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); abort();
} else { } else {
UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1);
} }

View File

@@ -12,7 +12,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "hal/assert.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
@@ -91,7 +90,6 @@ typedef enum {
*/ */
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{ {
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG : uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG :
(uart_num == 1) ? PCR_UART1_CONF_REG : 0); (uart_num == 1) ? PCR_UART1_CONF_REG : 0);
uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN : uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN :
@@ -109,8 +107,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
*/ */
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
PCR.uart0_conf.uart0_clk_en = enable; PCR.uart0_conf.uart0_clk_en = enable;
break; break;
@@ -129,8 +126,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
PCR.uart0_conf.uart0_rst_en = 1; PCR.uart0_conf.uart0_rst_en = 1;
PCR.uart0_conf.uart0_rst_en = 0; PCR.uart0_conf.uart0_rst_en = 0;

View File

@@ -69,6 +69,19 @@ typedef enum {
UART_INTR_WAKEUP = (0x1 << 19), UART_INTR_WAKEUP = (0x1 << 19),
} uart_intr_t; } uart_intr_t;
/**
* @brief Sync the update to UART core clock domain
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
{
hw->reg_update.reg_update = 1;
while (hw->reg_update.reg_update);
}
/****************************************** LP_UART Specific ********************************************/ /****************************************** LP_UART Specific ********************************************/
/** /**
* @brief Get the LP_UART source clock. * @brief Get the LP_UART source clock.
@@ -99,7 +112,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *sou
* @param hw Address offset of the LP UART peripheral registers * @param hw Address offset of the LP UART peripheral registers
* @param src_clk Source clock for the LP UART peripheral * @param src_clk Source clock for the LP UART peripheral
*/ */
FORCE_INLINE_ATTR void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk) static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk)
{ {
(void)hw; (void)hw;
switch (src_clk) { switch (src_clk) {
@@ -121,13 +134,40 @@ FORCE_INLINE_ATTR void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_u
// LPPERI.core_clk_sel is a shared register, so this function must be used in an atomic way // LPPERI.core_clk_sel is a shared register, so this function must be used in an atomic way
#define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__) #define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__)
/**
* @brief Configure the lp uart baud-rate.
*
* @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set.
* @param sclk_freq Frequency of the clock source of UART, in Hz.
*
* @return None
*/
FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
{
#define DIV_UP(a, b) (((a) + (b) - 1) / (b))
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud);
if (sclk_div == 0) abort();
uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div);
// The baud rate configuration register is divided into
// an integer part and a fractional part.
hw->clkdiv_sync.clkdiv = clk_div >> 4;
hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
//needs force u32 write
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
#undef DIV_UP
uart_ll_update(hw);
}
/** /**
* @brief Enable bus clock for the LP UART module * @brief Enable bus clock for the LP UART module
* *
* @param hw_id LP UART instance ID * @param hw_id LP UART instance ID
* @param enable True to enable, False to disable * @param enable True to enable, False to disable
*/ */
FORCE_INLINE_ATTR void lp_uart_ll_enable_bus_clock(int hw_id, bool enable) static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
{ {
(void)hw_id; (void)hw_id;
LPPERI.clk_en.ck_en_lp_uart = enable; LPPERI.clk_en.ck_en_lp_uart = enable;
@@ -141,7 +181,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
* *
* @param hw_id LP UART instance ID * @param hw_id LP UART instance ID
*/ */
FORCE_INLINE_ATTR void lp_uart_ll_reset_register(int hw_id) static inline void lp_uart_ll_reset_register(int hw_id)
{ {
(void)hw_id; (void)hw_id;
LPPERI.reset_en.rst_en_lp_uart = 1; LPPERI.reset_en.rst_en_lp_uart = 1;
@@ -166,8 +206,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
bool uart_rst_en = false; bool uart_rst_en = false;
bool uart_apb_en = false; bool uart_apb_en = false;
bool uart_sys_en = false; bool uart_sys_en = false;
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
uart_rst_en = HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb; uart_rst_en = HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb;
uart_apb_en = HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en; uart_apb_en = HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en;
@@ -204,10 +243,9 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable * @param enable true to enable, false to disable
*/ */
FORCE_INLINE_ATTR void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en = enable; HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart0_sys_clk_en = enable; HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart0_sys_clk_en = enable;
@@ -243,10 +281,9 @@ FORCE_INLINE_ATTR void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enabl
* @brief Reset UART module * @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/ */
FORCE_INLINE_ATTR void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb = 1; HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb = 0; HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb = 0;
@@ -278,19 +315,6 @@ FORCE_INLINE_ATTR void uart_ll_reset_register(uart_port_t uart_num)
// HP_SYS_CLKRST.hp_rst_en1 is a shared register, so this function must be used in an atomic way // HP_SYS_CLKRST.hp_rst_en1 is a shared register, so this function must be used in an atomic way
#define uart_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_reset_register(__VA_ARGS__) #define uart_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_reset_register(__VA_ARGS__)
/**
* @brief Sync the update to UART core clock domain
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
{
hw->reg_update.reg_update = 1;
while (hw->reg_update.reg_update);
}
/** /**
* @brief Configure the UART core reset. * @brief Configure the UART core reset.
* *
@@ -490,8 +514,8 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl114, reg_uart3_sclk_div_num, sclk_div - 1); HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl114, reg_uart3_sclk_div_num, sclk_div - 1);
} else if ((hw) == &UART4) { } else if ((hw) == &UART4) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl115, reg_uart4_sclk_div_num, sclk_div - 1); HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl115, reg_uart4_sclk_div_num, sclk_div - 1);
} else if ((hw) == &LP_UART) { } else {
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); abort();
} }
#undef DIV_UP #undef DIV_UP
uart_ll_update(hw); uart_ll_update(hw);

View File

@@ -11,7 +11,6 @@
#pragma once #pragma once
#include <stdlib.h> #include <stdlib.h>
#include "hal/assert.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
@@ -65,7 +64,6 @@ typedef enum {
*/ */
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{ {
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST : uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST :
(uart_num == 1) ? DPORT_UART1_RST : 0); (uart_num == 1) ? DPORT_UART1_RST : 0);
uint32_t uart_en_bit = ((uart_num == 0) ? DPORT_UART_CLK_EN : uint32_t uart_en_bit = ((uart_num == 0) ? DPORT_UART_CLK_EN :
@@ -82,8 +80,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG);
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
reg_val = reg_val & (~DPORT_UART_CLK_EN); reg_val = reg_val & (~DPORT_UART_CLK_EN);
reg_val = reg_val | (enable << DPORT_UART_CLK_EN_S); reg_val = reg_val | (enable << DPORT_UART_CLK_EN_S);
@@ -106,8 +103,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);

View File

@@ -11,7 +11,6 @@
#pragma once #pragma once
#include <stdlib.h> #include <stdlib.h>
#include "hal/assert.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
@@ -69,7 +68,6 @@ typedef enum {
*/ */
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{ {
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST : uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST :
(uart_num == 1) ? SYSTEM_UART1_RST : (uart_num == 1) ? SYSTEM_UART1_RST :
(uart_num == 2) ? SYSTEM_UART2_RST : 0); (uart_num == 2) ? SYSTEM_UART2_RST : 0);
@@ -87,8 +85,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
*/ */
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
SYSTEM.perip_clk_en0.uart_clk_en = enable; SYSTEM.perip_clk_en0.uart_clk_en = enable;
break; break;
@@ -112,8 +109,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
*/ */
static inline void uart_ll_reset_register(uart_port_t uart_num) static inline void uart_ll_reset_register(uart_port_t uart_num)
{ {
switch (uart_num) switch (uart_num) {
{
case 0: case 0:
SYSTEM.perip_rst_en0.uart_rst = 1; SYSTEM.perip_rst_en0.uart_rst = 1;
SYSTEM.perip_rst_en0.uart_rst = 0; SYSTEM.perip_rst_en0.uart_rst = 0;

View File

@@ -278,7 +278,12 @@ typedef enum {
LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */ LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */
LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */ LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */
LP_UART_SCLK_LP_PLL = SOC_MOD_CLK_LP_PLL, /*!< LP_UART source clock is LP_PLL (8M PLL) */ LP_UART_SCLK_LP_PLL = SOC_MOD_CLK_LP_PLL, /*!< LP_UART source clock is LP_PLL (8M PLL) */
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock default choice is XTAL_D2 */ #if SOC_CLK_TREE_SUPPORTED
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST,
#else
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock default choice is XTAL_D2 */
#endif
} soc_periph_lp_uart_clk_src_t; } soc_periph_lp_uart_clk_src_t;
//////////////////////////////////////////////////MCPWM///////////////////////////////////////////////////////////////// //////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////

View File

@@ -48,14 +48,12 @@ static esp_err_t lp_core_uart_param_config(const lp_core_uart_cfg_t *cfg)
} }
// LP UART clock source is mixed with other peripherals in the same register // LP UART clock source is mixed with other peripherals in the same register
PERIPH_RCC_ATOMIC() { LP_UART_SRC_CLK_ATOMIC() {
lp_uart_ll_set_source_clk(hal.dev, clk_src); lp_uart_ll_set_source_clk(hal.dev, clk_src);
} }
/* Override protocol parameters from the configuration */ /* Override protocol parameters from the configuration */
UART_SCLK_ATOMIC() { lp_uart_ll_set_baudrate(hal.dev, cfg->uart_proto_cfg.baud_rate, sclk_freq);
uart_hal_set_baudrate(&hal, cfg->uart_proto_cfg.baud_rate, sclk_freq);
}
uart_hal_set_parity(&hal, cfg->uart_proto_cfg.parity); uart_hal_set_parity(&hal, cfg->uart_proto_cfg.parity);
uart_hal_set_data_bit_num(&hal, cfg->uart_proto_cfg.data_bits); uart_hal_set_data_bit_num(&hal, cfg->uart_proto_cfg.data_bits);
uart_hal_set_stop_bits(&hal, cfg->uart_proto_cfg.stop_bits); uart_hal_set_stop_bits(&hal, cfg->uart_proto_cfg.stop_bits);

View File

@@ -204,12 +204,12 @@ examples/system/ulp/lp_core/lp_i2c:
- if: SOC_LP_I2C_SUPPORTED == 1 - if: SOC_LP_I2C_SUPPORTED == 1
examples/system/ulp/lp_core/lp_uart/lp_uart_echo: examples/system/ulp/lp_core/lp_uart/lp_uart_echo:
enable: disable:
- if: SOC_ULP_LP_UART_SUPPORTED == 1 - if: SOC_ULP_LP_UART_SUPPORTED != 1
examples/system/ulp/lp_core/lp_uart/lp_uart_print: examples/system/ulp/lp_core/lp_uart/lp_uart_print:
enable: disable:
- if: SOC_ULP_LP_UART_SUPPORTED == 1 - if: SOC_ULP_LP_UART_SUPPORTED != 1
examples/system/ulp/ulp_fsm/ulp: examples/system/ulp/ulp_fsm/ulp:
disable: disable: