feat(uart): add LP-UART GPIO support

This commit is contained in:
gaoxu 2023-09-25 11:12:09 +08:00
parent 3e3e928209
commit 4f24f805cc
22 changed files with 353 additions and 397 deletions

View File

@ -18,7 +18,7 @@ extern "C" {
#define LP_UART_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#if SOC_PERIPH_CLK_CTRL_SHARED
#define UART_SCLK_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define UART_SCLK_ATOMIC()

View File

@ -26,6 +26,7 @@
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "driver/uart_select.h"
#include "driver/lp_io.h"
#include "esp_private/uart_private.h"
#include "esp_private/periph_ctrl.h"
#include "esp_clk_tree.h"
@ -666,17 +667,21 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
}
#if (SOC_UART_LP_NUM >= 1)
else { // LP_UART IO check
const uart_periph_sig_t *pins = uart_periph_signal[uart_num].pins;
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
const uart_periph_sig_t *pins = uart_periph_signal[uart_num].pins;
// LP_UART has its fixed IOs
ESP_RETURN_ON_FALSE((tx_io_num < 0 || (tx_io_num == pins[SOC_UART_TX_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "tx_io_num error");
ESP_RETURN_ON_FALSE((rx_io_num < 0 || (rx_io_num == pins[SOC_UART_RX_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "rx_io_num error");
ESP_RETURN_ON_FALSE((rts_io_num < 0 || (rts_io_num == pins[SOC_UART_RTS_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "rts_io_num error");
ESP_RETURN_ON_FALSE((cts_io_num < 0 || (cts_io_num == pins[SOC_UART_CTS_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "cts_io_num error");
#else
// LP_UART signals can be routed to any LP_IOs
ESP_RETURN_ON_FALSE((tx_io_num < 0 || rtc_gpio_is_valid_gpio(tx_io_num)), ESP_FAIL, UART_TAG, "tx_io_num error");
ESP_RETURN_ON_FALSE((rx_io_num < 0 || rtc_gpio_is_valid_gpio(rx_io_num)), ESP_FAIL, UART_TAG, "rx_io_num error");
ESP_RETURN_ON_FALSE((rts_io_num < 0 || rtc_gpio_is_valid_gpio(rts_io_num)), ESP_FAIL, UART_TAG, "rts_io_num error");
ESP_RETURN_ON_FALSE((cts_io_num < 0 || rtc_gpio_is_valid_gpio(cts_io_num)), ESP_FAIL, UART_TAG, "cts_io_num error");
#else // SOC_LP_GPIO_MATRIX_SUPPORTED
// LP_UART IOs can be routed any LP_IOs
//TODO: IDF-7815, check for LP_IO 0~15
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
}
#endif
@ -690,11 +695,11 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
//TODO:IDF-7815
rtc_gpio_set_direction(tx_io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_init(tx_io_num);
rtc_gpio_iomux_func_sel(tx_io_num, 1);
LP_GPIO.func10_out_sel_cfg.reg_gpio_func10_out_sel = uart_periph_signal[uart_num].pins[SOC_UART_TX_PIN_IDX].signal;
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
}
#endif
}
@ -708,12 +713,11 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
//TODO:IDF-7815
rtc_gpio_set_direction(rx_io_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_init(rx_io_num);
rtc_gpio_iomux_func_sel(rx_io_num, 1);
LP_GPIO.func2_in_sel_cfg.reg_gpio_sig2_in_sel = 1;
LP_GPIO.func2_in_sel_cfg.reg_gpio_func2_in_sel = 11;
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
}
#endif
}
@ -726,11 +730,10 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
//TODO:IDF-7815
rtc_gpio_set_direction(rts_io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_init(rts_io_num);
rtc_gpio_iomux_func_sel(rts_io_num, 1);
LP_GPIO.func10_out_sel_cfg.reg_gpio_func12_out_sel = uart_periph_signal[uart_num].pins[SOC_UART_RTS_PIN_IDX].signal;
lp_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
}
#endif
}
@ -744,12 +747,11 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
//TODO:IDF-7815
rtc_gpio_set_direction(cts_io_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_init(cts_io_num);
rtc_gpio_iomux_func_sel(cts_io_num, 1);
LP_GPIO.func2_in_sel_cfg.reg_gpio_sig3_in_sel = 1;
LP_GPIO.func2_in_sel_cfg.reg_gpio_func3_in_sel = 13;
lp_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);
}
#endif
}

View File

@ -738,7 +738,7 @@ void esp_pm_impl_init(void)
#else
#error "No UART clock source is aware of DFS"
#endif // SOC_UART_SUPPORT_xxx
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 */

View File

@ -11,6 +11,7 @@ extern "C" {
#endif
#include <stdint.h>
#include "hal/uart_ll.h"
#define ESP_ROM_CDC_ACM_WORK_BUF_MIN 128
@ -34,7 +35,7 @@ void esp_rom_uart_tx_wait_idle(uint8_t uart_no);
* @param clock_hz Source clock (in Hz)
* @param baud_rate Baud rate to set
*/
void esp_rom_uart_set_clock_baudrate(uint8_t uart_no, uint32_t clock_hz, uint32_t baud_rate);
#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)
/**
* @brief Wait until UART TX FIFO is empty (i.e. flush TX FIFO)

View File

@ -23,15 +23,6 @@ IRAM_ATTR void esp_rom_uart_tx_wait_idle(uint8_t uart_no)
}
#endif
IRAM_ATTR void esp_rom_uart_set_clock_baudrate(uint8_t uart_no, uint32_t clock_hz, uint32_t baud_rate)
{
// To avoid build errors about __DECLARE_RCC_ATOMIC_ENV
#if !BOOTLOADER_BUILD
int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused));
#endif
uart_ll_set_baudrate(UART_LL_GET_HW(uart_no), baud_rate, clock_hz);
}
#if CONFIG_IDF_TARGET_ESP32C3
/**
* The ESP32-C3 ROM has released two versions, one is the ECO3 version,

View File

@ -144,13 +144,6 @@ static volatile bool s_cpu_inited[SOC_CPU_CORES_NUM] = { false };
static volatile bool s_resume_cores;
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#define UART_START_SCLK_ATOMIC() PERIPH_RCC_ATOMIC()
#else
// #define UART_START_SCLK_ATOMIC() for(int i = 1, __DECLARE_RCC_ATOMIC_ENV; i < 1; i--)
#define UART_START_SCLK_ATOMIC() int __DECLARE_RCC_ATOMIC_ENV;
#endif
static void core_intr_matrix_clear(void)
{
uint32_t core_id = esp_cpu_get_core_id();
@ -690,10 +683,10 @@ void IRAM_ATTR call_start_cpu0(void)
clock_hz = esp_clk_xtal_freq(); // From esp32-s3 on, UART clock source is selected to XTAL in ROM
#endif
esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
UART_START_SCLK_ATOMIC() {
(void) __DECLARE_RCC_ATOMIC_ENV; // To avoid build warning about __DECLARE_RCC_ATOMIC_ENV defined but not used on P4
esp_rom_uart_set_clock_baudrate(CONFIG_ESP_CONSOLE_UART_NUM, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
}
// In a single thread mode, the freertos is not started yet. So don't have to use a critical section.
int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused)); // To avoid build errors about spinlock's __DECLARE_RCC_ATOMIC_ENV
esp_rom_uart_set_clock_baudrate(CONFIG_ESP_CONSOLE_UART_NUM, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
#endif
#endif

View File

@ -78,47 +78,6 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
DPORT_REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, uart_en_bit) != 0;
}
/**
* @brief Configure the UART core reset.
*
* @param hw Beginning address of the peripheral registers.
* @param core_rst_en True to enable the core reset, otherwise set it false.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en)
{
hw->clk_conf.rst_core = core_rst_en;
}
/**
* @brief Enable the UART clock.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw)
{
hw->clk_conf.sclk_en = 1;
hw->clk_conf.rx_sclk_en = 1;
hw->clk_conf.tx_sclk_en = 1;
}
/**
* @brief Disable the UART clock.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw)
{
hw->clk_conf.sclk_en = 0;
hw->clk_conf.rx_sclk_en = 0;
hw->clk_conf.tx_sclk_en = 0;
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
@ -166,6 +125,48 @@ static inline void uart_ll_reset_register(uart_port_t uart_num)
// SYSTEM.perip_rst_en0 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__)
/**
* @brief Configure the UART core reset.
*
* @param hw Beginning address of the peripheral registers.
* @param core_rst_en True to enable the core reset, otherwise set it false.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en)
{
hw->clk_conf.rst_core = core_rst_en;
}
/**
* @brief Enable the UART clock.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw)
{
hw->clk_conf.sclk_en = 1;
hw->clk_conf.rx_sclk_en = 1;
hw->clk_conf.tx_sclk_en = 1;
}
/**
* @brief Disable the UART clock.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw)
{
hw->clk_conf.sclk_en = 0;
hw->clk_conf.rx_sclk_en = 0;
hw->clk_conf.tx_sclk_en = 0;
}
/**
* @brief Set the UART source clock.
*

View File

@ -78,6 +78,53 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
DPORT_REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, uart_en_bit) != 0;
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
SYSTEM.perip_clk_en0.reg_uart_clk_en = enable;
break;
case 1:
SYSTEM.perip_clk_en0.reg_uart1_clk_en = enable;
break;
default:
abort();
break;
}
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/
static inline void uart_ll_reset_register(uart_port_t uart_num)
{
switch (uart_num)
{
case 0:
SYSTEM.perip_rst_en0.reg_uart_rst = 1;
SYSTEM.perip_rst_en0.reg_uart_rst = 0;
break;
case 1:
SYSTEM.perip_rst_en0.reg_uart1_rst = 1;
SYSTEM.perip_rst_en0.reg_uart1_rst = 0;
break;
default:
abort();
break;
}
}
// SYSTEM.perip_rst_enx are shared registers, 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__)
/**
* @brief Configure the UART core reset.
*
@ -119,60 +166,6 @@ FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw)
hw->clk_conf.tx_sclk_en = 0;
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
SYSTEM.perip_clk_en0.reg_uart_clk_en = enable;
break;
case 1:
SYSTEM.perip_clk_en0.reg_uart1_clk_en = enable;
break;
case 2:
SYSTEM.perip_clk_en1.reg_uart2_clk_en = enable;
break;
default:
abort();
break;
}
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/
static inline void uart_ll_reset_register(uart_port_t uart_num)
{
switch (uart_num)
{
case 0:
SYSTEM.perip_rst_en0.reg_uart_rst = 1;
SYSTEM.perip_rst_en0.reg_uart_rst = 0;
break;
case 1:
SYSTEM.perip_rst_en0.reg_uart1_rst = 1;
SYSTEM.perip_rst_en0.reg_uart1_rst = 0;
break;
case 2:
SYSTEM.perip_rst_en1.reg_uart2_rst = 1;
SYSTEM.perip_rst_en1.reg_uart2_rst = 0;
break;
default:
abort();
break;
}
}
// SYSTEM.perip_rst_enx are shared registers, 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__)
/**
* @brief Set the UART source clock.
*

View File

@ -183,6 +183,51 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0;
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_clk_en = enable;
break;
case 1:
PCR.uart1_conf.uart1_clk_en = enable;
break;
default:
// LP_UART
abort();
break;
}
}
/**
* @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/
static inline void uart_ll_reset_register(uart_port_t uart_num)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_rst_en = 1;
PCR.uart0_conf.uart0_rst_en = 0;
break;
case 1:
PCR.uart1_conf.uart1_rst_en = 1;
PCR.uart1_conf.uart1_rst_en = 0;
break;
default:
// LP_UART
abort();
break;
}
}
/**
* @brief Sync the update to UART core clock domain
*
@ -251,51 +296,6 @@ FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw)
}
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_clk_en = enable;
break;
case 1:
PCR.uart1_conf.uart1_clk_en = enable;
break;
default:
// LP_UART
abort();
break;
}
}
/**
* @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/
static inline void uart_ll_reset_register(uart_port_t uart_num)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_rst_en = 1;
PCR.uart0_conf.uart0_rst_en = 0;
break;
case 1:
PCR.uart1_conf.uart1_rst_en = 1;
PCR.uart1_conf.uart1_rst_en = 0;
break;
default:
// LP_UART
abort();
break;
}
}
/**
* @brief Set the UART source clock.
*

View File

@ -102,6 +102,49 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0;
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_clk_en = enable;
break;
case 1:
PCR.uart1_conf.uart1_clk_en = enable;
break;
default:
abort();
break;
}
}
/**
* @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/
static inline void uart_ll_reset_register(uart_port_t uart_num)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_rst_en = 1;
PCR.uart0_conf.uart0_rst_en = 0;
break;
case 1:
PCR.uart1_conf.uart1_rst_en = 1;
PCR.uart1_conf.uart1_rst_en = 0;
break;
default:
abort();
break;
}
}
/**
* @brief Sync the update to UART core clock domain
*
@ -152,49 +195,6 @@ FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw)
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0);
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_clk_en = enable;
break;
case 1:
PCR.uart1_conf.uart1_clk_en = enable;
break;
default:
abort();
break;
}
}
/**
* @brief Reset UART module
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
*/
static inline void uart_ll_reset_register(uart_port_t uart_num)
{
switch (uart_num)
{
case 0:
PCR.uart0_conf.uart0_rst_en = 1;
PCR.uart0_conf.uart0_rst_en = 0;
break;
case 1:
PCR.uart1_conf.uart1_rst_en = 1;
PCR.uart1_conf.uart1_rst_en = 0;
break;
default:
abort();
break;
}
}
/**
* @brief Set the UART source clock.
*

View File

@ -199,6 +199,85 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
return (!uart_rst_en && uart_apb_en && uart_sys_en);
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
FORCE_INLINE_ATTR void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart0_sys_clk_en = enable;
break;
case 1:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart1_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart1_sys_clk_en = enable;
break;
case 2:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart2_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart2_sys_clk_en = enable;
break;
case 3:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart3_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart3_sys_clk_en = enable;
break;
case 4:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart4_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart4_sys_clk_en = enable;
break;
case 5:
// LP_UART port having its own enable_bus_clock function: lp_uart_ll_enable_bus_clock
break;;
default:
abort();
break;
}
}
// HP_SYS_CLKRST.soc_clk_ctrlx are shared registers, so this function must be used in an atomic way
#define uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset UART module
* @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)
{
switch (uart_num)
{
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 = 0;
break;
case 1:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart1_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart1_apb = 0;
break;
case 2:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart2_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart2_apb = 0;
break;
case 3:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart3_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart3_apb = 0;
break;
case 4:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart4_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart4_apb = 0;
break;
case 5:
// LP_UART port having its own enable_bus_clock function: lp_uart_ll_reset_register
break;;
default:
abort();
break;
}
}
// 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__)
/**
* @brief Sync the update to UART core clock domain
*
@ -295,85 +374,6 @@ FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw)
// HP_SYS_CLKRST.peri_clk_ctrlxxx are shared registers, so this function must be used in an atomic way
#define uart_ll_sclk_disable(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_sclk_disable(__VA_ARGS__)
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
* @param enable true to enable, false to disable
*/
FORCE_INLINE_ATTR void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
{
switch (uart_num)
{
case 0:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart0_sys_clk_en = enable;
break;
case 1:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart1_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart1_sys_clk_en = enable;
break;
case 2:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart2_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart2_sys_clk_en = enable;
break;
case 3:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart3_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart3_sys_clk_en = enable;
break;
case 4:
HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart4_apb_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart4_sys_clk_en = enable;
break;
case 5:
// LP_UART port having its own enable_bus_clock function: lp_uart_ll_enable_bus_clock
break;;
default:
abort();
break;
}
}
// HP_SYS_CLKRST.soc_clk_ctrlx are shared registers, so this function must be used in an atomic way
#define uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset UART module
* @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)
{
switch (uart_num)
{
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 = 0;
break;
case 1:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart1_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart1_apb = 0;
break;
case 2:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart2_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart2_apb = 0;
break;
case 3:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart3_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart3_apb = 0;
break;
case 4:
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart4_apb = 1;
HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart4_apb = 0;
break;
case 5:
// LP_UART port having its own enable_bus_clock function: lp_uart_ll_reset_register
break;;
default:
abort();
break;
}
}
// 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__)
/**
* @brief Set the UART source clock.
*
@ -490,8 +490,7 @@ 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);
} else if ((hw) == &UART4) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl115, reg_uart4_sclk_div_num, sclk_div - 1);
} else {
//LP UART
} else if ((hw) == &LP_UART) {
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
}
#undef DIV_UP
@ -525,7 +524,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_fr
sclk_div = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl114, reg_uart3_sclk_div_num) + 1;
} else if ((hw) == &UART4) {
sclk_div = HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl115, reg_uart4_sclk_div_num) + 1;
} else {
} else if ((hw) == &LP_UART) {
sclk_div = HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1;
}
return ((sclk_freq << 4)) / (((div_reg.clkdiv << 4) | div_reg.clkdiv_frag) * sclk_div);

View File

@ -80,19 +80,6 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
DPORT_REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, uart_en_bit) != 0;
}
/**
* @brief Configure the UART core reset.
*
* @param hw Beginning address of the peripheral registers.
* @param core_rst_en True to enable the core reset, otherwise set it false.
*
* @return None.
*/
static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en)
{
hw->clk_conf.rst_core = core_rst_en;
}
/**
* @brief Enable the bus clock for uart
* @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
@ -147,6 +134,19 @@ static inline void uart_ll_reset_register(uart_port_t uart_num)
// SYSTEM.perip_rst_enx are shared registers, 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__)
/**
* @brief Configure the UART core reset.
*
* @param hw Beginning address of the peripheral registers.
* @param core_rst_en True to enable the core reset, otherwise set it false.
*
* @return None.
*/
static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en)
{
hw->clk_conf.rst_core = core_rst_en;
}
/**
* @brief Set the UART source clock.
*

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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.
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SOC_SYSTEM_REG_H_
#define _SOC_SYSTEM_REG_H_
@ -282,12 +274,6 @@ extern "C" {
#define SYSTEM_TSENS_CLK_EN_M (BIT(10))
#define SYSTEM_TSENS_CLK_EN_V 0x1
#define SYSTEM_TSENS_CLK_EN_S 10
/* SYSTEM_UART2_CLK_EN : R/W ;bitpos:[9] ;default: 1'b1 ; */
/*description: */
#define SYSTEM_UART2_CLK_EN (BIT(9))
#define SYSTEM_UART2_CLK_EN_M (BIT(9))
#define SYSTEM_UART2_CLK_EN_V 0x1
#define SYSTEM_UART2_CLK_EN_S 9
/* SYSTEM_LCD_CAM_CLK_EN : R/W ;bitpos:[8] ;default: 1'b0 ; */
/*description: */
#define SYSTEM_LCD_CAM_CLK_EN (BIT(8))
@ -538,12 +524,6 @@ extern "C" {
#define SYSTEM_TSENS_RST_M (BIT(10))
#define SYSTEM_TSENS_RST_V 0x1
#define SYSTEM_TSENS_RST_S 10
/* SYSTEM_UART2_RST : R/W ;bitpos:[9] ;default: 1'b0 ; */
/*description: */
#define SYSTEM_UART2_RST (BIT(9))
#define SYSTEM_UART2_RST_M (BIT(9))
#define SYSTEM_UART2_RST_V 0x1
#define SYSTEM_UART2_RST_S 9
/* SYSTEM_LCD_CAM_RST : R/W ;bitpos:[8] ;default: 1'b1 ; */
/*description: */
#define SYSTEM_LCD_CAM_RST (BIT(8))

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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.
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SOC_SYSTEM_STRUCT_H_
#define _SOC_SYSTEM_STRUCT_H_
@ -104,7 +96,7 @@ typedef volatile struct system_dev_s {
uint32_t reg_dma_clk_en : 1; /*reg_dma_clk_en*/
uint32_t reg_sdio_host_clk_en : 1; /*reg_sdio_host_clk_en*/
uint32_t reg_lcd_cam_clk_en : 1; /*reg_lcd_cam_clk_en*/
uint32_t reg_uart2_clk_en : 1; /*reg_uart2_clk_en*/
uint32_t reserved9 : 1; /*reserved*/
uint32_t reg_tsens_clk_en : 1; /*reg_tsens_clk_en*/
uint32_t reserved11 : 21; /*reserved*/
};
@ -158,7 +150,7 @@ typedef volatile struct system_dev_s {
uint32_t reg_dma_rst : 1; /*reg_dma_rst*/
uint32_t reg_sdio_host_rst : 1; /*reg_sdio_host_rst*/
uint32_t reg_lcd_cam_rst : 1; /*reg_lcd_cam_rst*/
uint32_t reg_uart2_rst : 1; /*reg_uart2_rst*/
uint32_t reserved9 : 1; /*reserved*/
uint32_t reg_tsens_rst : 1; /*reg_tsens_rst*/
uint32_t reserved11 : 21; /*reserved*/
};

View File

@ -203,6 +203,10 @@ config SOC_LP_I2C_SUPPORTED
bool
default y
config SOC_ULP_LP_UART_SUPPORTED
bool
default y
config SOC_CLK_TREE_SUPPORTED
bool
default y

View File

@ -75,6 +75,7 @@
#define SOC_LP_AON_SUPPORTED 1
#define SOC_LP_PERIPHERALS_SUPPORTED 1
#define SOC_LP_I2C_SUPPORTED 1
#define SOC_ULP_LP_UART_SUPPORTED 1
#define SOC_CLK_TREE_SUPPORTED 1
#define SOC_ASSIST_DEBUG_SUPPORTED 1

View File

@ -1037,12 +1037,16 @@ config SOC_FLASH_ENCRYPTION_XTS_AES_128
config SOC_UART_NUM
int
default 5
default 6
config SOC_UART_HP_NUM
int
default 5
config SOC_UART_LP_NUM
int
default 1
config SOC_UART_FIFO_LEN
int
default 128

View File

@ -153,8 +153,8 @@ typedef enum {
SOC_MOD_CLK_APLL, /*!< Audio PLL is sourced from PLL, and its frequency is configurable through APLL configuration registers */
// For LP peripherals
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */
SOC_MOD_CLK_LP_PLL, /*!< LP_PLL is from 32kHz XTAL oscillator frequency multipliers, it has a fixed frequency of 8MHz */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
SOC_MOD_CLK_LP_PLL,
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER//////////////////////////////////////////////////////////////

View File

@ -72,6 +72,7 @@
// #define SOC_PMU_SUPPORTED 1 //TODO: IDF-7531
// #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531
// #define SOC_LP_TIMER_SUPPORTED 1 //TODO: IDF-7532
// #define SOC_ULP_LP_UART_SUPPORTED 1 //TODO: IDF-7533
#define SOC_LP_GPIO_MATRIX_SUPPORTED 1
#define SOC_LP_PERIPHERALS_SUPPORTED 1
#define SOC_SPIRAM_SUPPORTED 1
@ -208,7 +209,6 @@
// Support to hold a single digital I/O when the digital domain is powered off
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
// #define SOC_LP_GPIO_MATRIX_SUPPORTED (1)
/*-------------------------- RTCIO CAPS --------------------------------------*/
#define SOC_RTCIO_PIN_COUNT 16
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature,
@ -472,11 +472,9 @@
/*-------------------------- UART CAPS ---------------------------------------*/
// ESP32-P4 has 6 UARTs (5 HP UART, and 1 LP UART)
#define SOC_UART_NUM (5)
#define SOC_UART_NUM (6)
#define SOC_UART_HP_NUM (5)
// TODO: 7815
// The RTC GPIO and sigmap is not supported yet, so make SOC_UART_NUM->5 to avoid lp-uart build errors
// #define SOC_UART_LP_NUM (1U)
#define SOC_UART_LP_NUM (1U)
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_LP_UART_FIFO_LEN (16) /*!< The LP UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */

View File

@ -180,38 +180,37 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = {
.irq = ETS_UART4_INTR_SOURCE,
.module = PERIPH_UART4_MODULE,
},
//TODO:IDF-7815
// { // LP UART0
// .pins = {
// [SOC_UART_TX_PIN_IDX] = {
// .default_gpio = LP_U0TXD_GPIO_NUM,
// .iomux_func = LP_U0TXD_MUX_FUNC,
// .input = 0,
// .signal = LP_UART_TXD_PAD_OUT_IDX,
// },
{ // LP UART0
.pins = {
[SOC_UART_TX_PIN_IDX] = {
.default_gpio = LP_U0TXD_GPIO_NUM,
.iomux_func = LP_U0TXD_MUX_FUNC,
.input = 0,
.signal = LP_UART_TXD_PAD_OUT_IDX,
},
// [SOC_UART_RX_PIN_IDX] = {
// .default_gpio = LP_U0RXD_GPIO_NUM,
// .iomux_func = LP_U0RXD_MUX_FUNC,
// .input = 1,
// .signal = LP_UART_RXD_PAD_IN_IDX,
// },
[SOC_UART_RX_PIN_IDX] = {
.default_gpio = LP_U0RXD_GPIO_NUM,
.iomux_func = LP_U0RXD_MUX_FUNC,
.input = 1,
.signal = LP_UART_RXD_PAD_IN_IDX,
},
// [SOC_UART_RTS_PIN_IDX] = {
// .default_gpio = LP_U0RTS_GPIO_NUM,
// .iomux_func = LP_U0RTS_MUX_FUNC,
// .input = 0,
// .signal = LP_UART_RTSN_PAD_OUT_IDX,
// },
[SOC_UART_RTS_PIN_IDX] = {
.default_gpio = LP_U0RTS_GPIO_NUM,
.iomux_func = LP_U0RTS_MUX_FUNC,
.input = 0,
.signal = LP_UART_RTSN_PAD_OUT_IDX,
},
// [SOC_UART_CTS_PIN_IDX] = {
// .default_gpio = LP_U0CTS_GPIO_NUM,
// .iomux_func = LP_U0CTS_MUX_FUNC,
// .input = 1,
// .signal = LP_UART_CTSN_PAD_IN_IDX,
// },
// },
// .irq = ETS_LP_UART_INTR_SOURCE,
// .module = PERIPH_LP_UART0_MODULE,
// },
[SOC_UART_CTS_PIN_IDX] = {
.default_gpio = LP_U0CTS_GPIO_NUM,
.iomux_func = LP_U0CTS_MUX_FUNC,
.input = 1,
.signal = LP_UART_CTSN_PAD_IN_IDX,
},
},
.irq = ETS_LP_UART_INTR_SOURCE,
.module = PERIPH_LP_UART0_MODULE,
},
};

View File

@ -205,11 +205,11 @@ examples/system/ulp/lp_core/lp_i2c:
examples/system/ulp/lp_core/lp_uart/lp_uart_echo:
enable:
- if: SOC_UART_LP_NUM > 0
- if: SOC_ULP_LP_UART_SUPPORTED == 1
examples/system/ulp/lp_core/lp_uart/lp_uart_print:
enable:
- if: SOC_UART_LP_NUM > 0
- if: SOC_ULP_LP_UART_SUPPORTED == 1
examples/system/ulp/ulp_fsm/ulp:
disable:

View File

@ -687,8 +687,6 @@ components/soc/esp32c3/include/soc/soc_pins.h
components/soc/esp32c3/include/soc/spi_mem_reg.h
components/soc/esp32c3/include/soc/spi_pins.h
components/soc/esp32c3/include/soc/spi_reg.h
components/soc/esp32c3/include/soc/system_reg.h
components/soc/esp32c3/include/soc/system_struct.h
components/soc/esp32c3/include/soc/systimer_reg.h
components/soc/esp32c3/include/soc/systimer_struct.h
components/soc/esp32c3/include/soc/uart_pins.h