feat(uart): add HP/LP uart support on ESP32C5

pull/13309/head
gaoxu 2024-02-28 09:56:18 +08:00
rodzic 6817e9f07c
commit f9109beda2
11 zmienionych plików z 195 dodań i 44 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -25,6 +25,7 @@
#include "driver/rtc_io.h"
#include "driver/uart_select.h"
#include "driver/lp_io.h"
#include "esp_private/gpio.h"
#include "esp_private/uart_share_hw_ctrl.h"
#include "esp_clk_tree.h"
#include "sdkconfig.h"
@ -678,7 +679,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
/* In the following statements, if the io_num is negative, no need to configure anything. */
if (tx_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO);
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
gpio_set_level(tx_io_num, 1);
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
}
@ -695,7 +696,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
if (rx_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO);
gpio_func_sel(rx_io_num, PIN_FUNC_GPIO);
gpio_set_pull_mode(rx_io_num, GPIO_PULLUP_ONLY);
gpio_set_direction(rx_io_num, GPIO_MODE_INPUT);
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
@ -713,7 +714,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
if (rts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rts_io_num], PIN_FUNC_GPIO);
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
gpio_set_direction(rts_io_num, GPIO_MODE_OUTPUT);
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
}
@ -729,7 +730,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cts_io_num], PIN_FUNC_GPIO);
gpio_func_sel(cts_io_num, PIN_FUNC_GPIO);
gpio_set_pull_mode(cts_io_num, GPIO_PULLUP_ONLY);
gpio_set_direction(cts_io_num, GPIO_MODE_INPUT);
esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);

Wyświetl plik

@ -38,6 +38,9 @@ uint32_t *freq_value)
case SOC_MOD_CLK_PLL_F240M:
clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = 20 * MHZ;
break;
case SOC_MOD_CLK_SPLL:
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ;
break;

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -85,8 +85,6 @@ typedef enum {
UART_INTR_WAKEUP = (0x1 << 19),
} uart_intr_t;
// TODO: [ESP32C5] IDF-8722, IDF-8633
/**
* @brief Sync the update to UART core clock domain
*
@ -213,15 +211,18 @@ static inline void lp_uart_ll_reset_register(int hw_id)
*/
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 :
(uart_num == 1) ? PCR_UART1_CONF_REG : 0);
uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN :
(uart_num == 1) ? PCR_UART1_RST_EN : 0);
uint32_t uart_en_bit = ((uart_num == 0) ? PCR_UART0_CLK_EN :
(uart_num == 1) ? PCR_UART1_CLK_EN : 0);
return REG_GET_BIT(uart_clk_config_reg, uart_rst_bit) == 0 &&
REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0;
switch (uart_num) {
case 0:
return PCR.uart0_conf.uart0_clk_en && !PCR.uart0_conf.uart0_rst_en;
case 1:
return PCR.uart1_conf.uart1_clk_en && !PCR.uart1_conf.uart1_rst_en;
case 2: // LP_UART
return LPPERI.clk_en.lp_uart_ck_en && !LPPERI.reset_en.lp_uart_reset_en;
default:
// Unknown uart port number
HAL_ASSERT(false);
return false;
}
}
/**
@ -336,14 +337,14 @@ FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_
if ((hw) != &LP_UART) {
uint32_t sel_value = 0;
switch (source_clk) {
case UART_SCLK_PLL_F80M:
sel_value = 2;
case UART_SCLK_XTAL:
sel_value = 0;
break;
case UART_SCLK_RTC:
sel_value = 1;
break;
case UART_SCLK_XTAL:
sel_value = 0;
case UART_SCLK_PLL_F80M:
sel_value = 2;
break;
default:
// Invalid HP_UART clock source
@ -370,14 +371,14 @@ FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source
if ((hw) != &LP_UART) {
switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) {
default:
case 1:
*source_clk = (soc_module_clk_t)UART_SCLK_PLL_F80M;
case 0:
*source_clk = (soc_module_clk_t)UART_SCLK_XTAL;
break;
case 2:
case 1:
*source_clk = (soc_module_clk_t)UART_SCLK_RTC;
break;
case 3:
*source_clk = (soc_module_clk_t)UART_SCLK_XTAL;
case 2:
*source_clk = (soc_module_clk_t)UART_SCLK_PLL_F80M;
break;
}
} else {

Wyświetl plik

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once

Wyświetl plik

@ -55,6 +55,10 @@ config SOC_FLASH_ENC_SUPPORTED
bool
default y
config SOC_LP_PERIPHERALS_SUPPORTED
bool
default y
config SOC_SPI_FLASH_SUPPORTED
bool
default y
@ -331,10 +335,26 @@ config SOC_LP_UART_FIFO_LEN
int
default 16
config SOC_UART_BITRATE_MAX
int
default 5000000
config SOC_UART_SUPPORT_PLL_F80M_CLK
bool
default y
config SOC_UART_SUPPORT_XTAL_CLK
bool
default y
config SOC_UART_SUPPORT_WAKEUP_INT
bool
default y
config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
bool
default y
config SOC_PM_SUPPORT_CPU_PD
bool
default y

Wyświetl plik

@ -232,20 +232,30 @@ typedef enum { // TODO: [ESP32C5] IDF-8727 (inherit from C6)
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/
typedef enum { // TODO: [ESP32C5] IDF-8722 (inherit from C6)
typedef enum {
UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */
UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */
UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
} soc_periph_uart_clk_src_legacy_t;
/**
* @brief Array initializer for all supported clock sources of LP_UART
*/
#define SOC_LP_UART_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL_D2}
/**
* @brief Type of LP_UART clock source
*/
typedef enum { // TODO: [ESP32C5] IDF-8633 (inherit from C6)
typedef enum {
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_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock default choice is LP(RTC)_FAST */

Wyświetl plik

@ -19,7 +19,7 @@
/*-------------------------- COMMON CAPS ---------------------------------------*/
// #define SOC_ADC_SUPPORTED 1 // TODO: [ESP32C5] IDF-8701
// #define SOC_DEDICATED_GPIO_SUPPORTED 1 // TODO: [ESP32C5] IDF-8725
#define SOC_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8722
#define SOC_UART_SUPPORTED 1
#define SOC_GDMA_SUPPORTED 1
#define SOC_AHB_GDMA_SUPPORTED 1
#define SOC_GPTIMER_SUPPORTED 1
@ -61,7 +61,7 @@
// #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638, IDF-8640
// #define SOC_LP_TIMER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8636
// #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638, IDF-8640
// #define SOC_LP_PERIPHERALS_SUPPORTED 1 // TODO: [ESP32C5] IDF-8695, IDF-8723, IDF-8719
#define SOC_LP_PERIPHERALS_SUPPORTED 1
// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634
// #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8633
// #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32C5] IDF-8642
@ -475,14 +475,14 @@
#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 */
// #define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */
// #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */
#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */
// #define SOC_UART_SUPPORT_RTC_CLK (1) // TODO: [ESP32C5] IDF-8642
#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 */
// 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)
/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
// #define SOC_COEX_HW_PTI (1)

Wyświetl plik

@ -8,8 +8,6 @@
#pragma once
// TODO: [ESP32C5] IDF-8722
//UART channels
#define UART_GPIO10_DIRECT_CHANNEL UART_NUM_0
#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 10

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,14 +8,12 @@
#include "soc/io_mux_reg.h"
// TODO: [ESP32C5] IDF-8722
/* Specify the number of pins for UART */
#define SOC_UART_PINS_COUNT (4)
/* Specify the GPIO pin number for each UART signal in the IOMUX */
#define U0RXD_GPIO_NUM 17
#define U0TXD_GPIO_NUM 16
#define U0RXD_GPIO_NUM 11
#define U0TXD_GPIO_NUM 10
#define U0RTS_GPIO_NUM (-1)
#define U0CTS_GPIO_NUM (-1)

Wyświetl plik

@ -19,8 +19,7 @@ typedef union {
/** rxfifo_rd_byte : RO; bitpos: [7:0]; default: 0;
* UART $n accesses FIFO via this register.
*/
uint32_t rxfifo_rd_byte:8;
uint32_t reserved_8:24;
uint32_t rxfifo_rd_byte:32;
};
uint32_t val;
} uart_fifo_reg_t;

Wyświetl plik

@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/uart_periph.h"
/*
Bunch of constants for every UART peripheral: GPIO signals, irqs, hw addr of registers etc
*/
const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = {
{ // HP UART0
.pins = {
[SOC_UART_TX_PIN_IDX] = {
.default_gpio = U0TXD_GPIO_NUM,
.iomux_func = U0TXD_MUX_FUNC,
.input = 0,
.signal = U0TXD_OUT_IDX,
},
[SOC_UART_RX_PIN_IDX] = {
.default_gpio = U0RXD_GPIO_NUM,
.iomux_func = U0RXD_MUX_FUNC,
.input = 1,
.signal = U0RXD_IN_IDX,
},
[SOC_UART_RTS_PIN_IDX] = {
.default_gpio = U0RTS_GPIO_NUM,
.iomux_func = U0RTS_MUX_FUNC,
.input = 0,
.signal = U0RTS_OUT_IDX,
},
[SOC_UART_CTS_PIN_IDX] = {
.default_gpio = U0CTS_GPIO_NUM,
.iomux_func = U0CTS_MUX_FUNC,
.input = 1,
.signal = U0CTS_IN_IDX,
}
},
.irq = ETS_UART0_INTR_SOURCE,
.module = PERIPH_UART0_MODULE,
},
{ // HP UART1
.pins = {
[SOC_UART_TX_PIN_IDX] = {
.default_gpio = U1TXD_GPIO_NUM,
.iomux_func = U1TXD_MUX_FUNC,
.input = 0,
.signal = U1TXD_OUT_IDX,
},
[SOC_UART_RX_PIN_IDX] = {
.default_gpio = U1RXD_GPIO_NUM,
.iomux_func = U1RXD_MUX_FUNC,
.input = 1,
.signal = U1RXD_IN_IDX,
},
[SOC_UART_RTS_PIN_IDX] = {
.default_gpio = U1RTS_GPIO_NUM,
.iomux_func = U1RTS_MUX_FUNC,
.input = 0,
.signal = U1RTS_OUT_IDX,
},
[SOC_UART_CTS_PIN_IDX] = {
.default_gpio = U1CTS_GPIO_NUM,
.iomux_func = U1CTS_MUX_FUNC,
.input = 1,
.signal = U1CTS_IN_IDX,
},
},
.irq = ETS_UART1_INTR_SOURCE,
.module = PERIPH_UART1_MODULE,
},
{ // LP UART0
.pins = {
[SOC_UART_TX_PIN_IDX] = {
.default_gpio = LP_U0TXD_GPIO_NUM,
.iomux_func = LP_U0TXD_MUX_FUNC,
.input = 0,
.signal = UINT8_MAX, // Signal not available in signal map
},
[SOC_UART_RX_PIN_IDX] = {
.default_gpio = LP_U0RXD_GPIO_NUM,
.iomux_func = LP_U0RXD_MUX_FUNC,
.input = 1,
.signal = UINT8_MAX, // Signal not available in signal map
},
[SOC_UART_RTS_PIN_IDX] = {
.default_gpio = LP_U0RTS_GPIO_NUM,
.iomux_func = LP_U0RTS_MUX_FUNC,
.input = 0,
.signal = UINT8_MAX, // Signal not available in signal map
},
[SOC_UART_CTS_PIN_IDX] = {
.default_gpio = LP_U0CTS_GPIO_NUM,
.iomux_func = LP_U0CTS_MUX_FUNC,
.input = 1,
.signal = UINT8_MAX, // Signal not available in signal map
},
},
.irq = ETS_LP_UART_INTR_SOURCE,
.module = PERIPH_LP_UART0_MODULE,
},
};