feat(lp_core): Added support for LP UART on LP core for esp32p4

This commit enables LP UART support for the LP core on the esp32p4.
This commit is contained in:
Sudeep Mohanty 2024-03-11 09:57:53 +01:00
parent 4f900edb06
commit 26fd843376
5 changed files with 80 additions and 23 deletions

View File

@ -179,6 +179,10 @@ config SOC_LP_TIMER_SUPPORTED
bool bool
default y default y
config SOC_ULP_LP_UART_SUPPORTED
bool
default y
config SOC_LP_GPIO_MATRIX_SUPPORTED config SOC_LP_GPIO_MATRIX_SUPPORTED
bool bool
default y default y

View File

@ -72,7 +72,7 @@
#define SOC_DCDC_SUPPORTED 1 #define SOC_DCDC_SUPPORTED 1
// #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531 // #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531
#define SOC_LP_TIMER_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1
// #define SOC_ULP_LP_UART_SUPPORTED 1 //TODO: IDF-7533 #define SOC_ULP_LP_UART_SUPPORTED 1
#define SOC_LP_GPIO_MATRIX_SUPPORTED 1 #define SOC_LP_GPIO_MATRIX_SUPPORTED 1
#define SOC_LP_PERIPHERALS_SUPPORTED 1 #define SOC_LP_PERIPHERALS_SUPPORTED 1
#define SOC_SPIRAM_SUPPORTED 1 #define SOC_SPIRAM_SUPPORTED 1

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -15,6 +15,23 @@ extern "C" {
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "hal/gpio_types.h" #include "hal/gpio_types.h"
/**
* Default LP_IO Mux pins for LP UART
*/
#if CONFIG_IDF_TARGET_ESP32P4
#define LP_UART_DEFAULT_TX_GPIO_NUM GPIO_NUM_14
#define LP_UART_DEFAULT_RX_GPIO_NUM GPIO_NUM_15
#define LP_UART_DEFAULT_RTS_GPIO_NUM (-1)
#define LP_UART_DEFAULT_CTS_GPIO_NUM (-1)
#elif CONFIG_IDF_TARGET_ESP32C6
#define LP_UART_DEFAULT_TX_GPIO_NUM GPIO_NUM_5
#define LP_UART_DEFAULT_RX_GPIO_NUM GPIO_NUM_4
#define LP_UART_DEFAULT_RTS_GPIO_NUM GPIO_NUM_2
#define LP_UART_DEFAULT_CTS_GPIO_NUM GPIO_NUM_3
#else
#error "LP IO Mux pins undefined for LP UART"
#endif /* CONFIG_IDF_TARGET_ESP32P4 */
/** /**
* @brief LP UART IO pins configuration * @brief LP UART IO pins configuration
*/ */
@ -47,11 +64,11 @@ typedef struct {
} lp_core_uart_cfg_t; } lp_core_uart_cfg_t;
/* Default LP UART GPIO settings */ /* Default LP UART GPIO settings */
#define LP_UART_DEFAULT_GPIO_CONFIG() \ #define LP_UART_DEFAULT_GPIO_CONFIG() \
.uart_pin_cfg.tx_io_num = GPIO_NUM_5, \ .uart_pin_cfg.tx_io_num = LP_UART_DEFAULT_TX_GPIO_NUM, \
.uart_pin_cfg.rx_io_num = GPIO_NUM_4, \ .uart_pin_cfg.rx_io_num = LP_UART_DEFAULT_RX_GPIO_NUM, \
.uart_pin_cfg.rts_io_num = GPIO_NUM_2, \ .uart_pin_cfg.rts_io_num = LP_UART_DEFAULT_RTS_GPIO_NUM, \
.uart_pin_cfg.cts_io_num = GPIO_NUM_3, \ .uart_pin_cfg.cts_io_num = LP_UART_DEFAULT_CTS_GPIO_NUM, \
/* Default LP UART protocol config */ /* Default LP UART protocol config */
#define LP_UART_DEFAULT_PROTO_CONFIG() \ #define LP_UART_DEFAULT_PROTO_CONFIG() \

View File

@ -6,15 +6,21 @@
#include <stdint.h> #include <stdint.h>
#include "esp_err.h" #include "esp_err.h"
#include "esp_check.h"
#include "lp_core_uart.h" #include "lp_core_uart.h"
#include "driver/rtc_io.h" #include "driver/rtc_io.h"
#include "driver/lp_io.h"
#include "soc/uart_periph.h"
#include "soc/lp_uart_struct.h" #include "soc/lp_uart_struct.h"
#include "hal/uart_hal.h" #include "hal/uart_hal.h"
#include "hal/rtc_io_hal.h"
#include "hal/rtc_io_types.h" #include "hal/rtc_io_types.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/uart_share_hw_ctrl.h" #include "esp_private/uart_share_hw_ctrl.h"
static const char *LP_UART_TAG = "lp_uart";
#define LP_UART_PORT_NUM LP_UART_NUM_0 #define LP_UART_PORT_NUM LP_UART_NUM_0
#define LP_UART_TX_IDLE_NUM_DEFAULT (0U) #define LP_UART_TX_IDLE_NUM_DEFAULT (0U)
@ -67,8 +73,13 @@ static esp_err_t lp_core_uart_param_config(const lp_core_uart_cfg_t *cfg)
return ret; return ret;
} }
static esp_err_t lp_uart_config_io(gpio_num_t pin, rtc_gpio_mode_t direction) static esp_err_t lp_uart_config_io(gpio_num_t pin, rtc_gpio_mode_t direction, uint32_t idx)
{ {
/* Skip configuration if the LP_IO is -1 */
if (pin < 0) {
return ESP_OK;
}
/* Initialize LP_IO */ /* Initialize LP_IO */
esp_err_t ret = rtc_gpio_init(pin); esp_err_t ret = rtc_gpio_init(pin);
if (ret != ESP_OK) { if (ret != ESP_OK) {
@ -81,8 +92,26 @@ static esp_err_t lp_uart_config_io(gpio_num_t pin, rtc_gpio_mode_t direction)
return ESP_FAIL; return ESP_FAIL;
} }
/* Set LP_IO function */ /* Connect pins */
ret = rtc_gpio_iomux_func_sel(pin, 1); const uart_periph_sig_t *upin = &uart_periph_signal[LP_UART_PORT_NUM].pins[idx];
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
/* When LP_IO Matrix is not support, LP_IO Mux must be connected to the pins */
ret = rtc_gpio_iomux_func_sel(pin, upin->iomux_func);
#else
/* If the configured pin is the default LP_IO Mux pin for LP UART, then set the LP_IO MUX function */
if (upin->default_gpio == pin) {
ret = rtc_gpio_iomux_func_sel(pin, upin->iomux_func);
} else {
/* Select FUNC1 for LP_IO Matrix */
ret = rtc_gpio_iomux_func_sel(pin, 1);
/* Connect the LP_IO to the LP UART peripheral signal */
if (direction == RTC_GPIO_MODE_OUTPUT_ONLY) {
ret = lp_gpio_connect_out_signal(pin, UART_PERIPH_SIGNAL(LP_UART_PORT_NUM, idx), 0, 0);
} else {
ret = lp_gpio_connect_in_signal(pin, UART_PERIPH_SIGNAL(LP_UART_PORT_NUM, idx), 0);
}
}
#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */
return ret; return ret;
} }
@ -92,22 +121,29 @@ static esp_err_t lp_core_uart_set_pin(const lp_core_uart_cfg_t *cfg)
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
/* Argument sanity check */ /* Argument sanity check */
if ((cfg->uart_pin_cfg.tx_io_num != GPIO_NUM_5) || #if !SOC_LP_GPIO_MATRIX_SUPPORTED
(cfg->uart_pin_cfg.rx_io_num != GPIO_NUM_4) || const uart_periph_sig_t *pins = uart_periph_signal[LP_UART_PORT_NUM].pins;
(cfg->uart_pin_cfg.rts_io_num != GPIO_NUM_2) || // LP_UART has its fixed IOs
(cfg->uart_pin_cfg.cts_io_num != GPIO_NUM_3)) { ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.tx_io_num < 0 || (cfg->uart_pin_cfg.tx_io_num == pins[SOC_UART_TX_PIN_IDX].default_gpio)), ESP_FAIL, LP_UART_TAG, "tx_io_num error");
// Invalid IO config ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.rx_io_num < 0 || (cfg->uart_pin_cfg.rx_io_num == pins[SOC_UART_RX_PIN_IDX].default_gpio)), ESP_FAIL, LP_UART_TAG, "rx_io_num error");
return ESP_ERR_INVALID_ARG; ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.rts_io_num < 0 || (cfg->uart_pin_cfg.rts_io_num == pins[SOC_UART_RTS_PIN_IDX].default_gpio)), ESP_FAIL, LP_UART_TAG, "rts_io_num error");
} ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.cts_io_num < 0 || (cfg->uart_pin_cfg.cts_io_num == pins[SOC_UART_CTS_PIN_IDX].default_gpio)), ESP_FAIL, LP_UART_TAG, "cts_io_num error");
#else
// LP_UART signals can be routed to any LP_IOs
ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.tx_io_num < 0 || rtc_gpio_is_valid_gpio(cfg->uart_pin_cfg.tx_io_num)), ESP_FAIL, LP_UART_TAG, "tx_io_num error");
ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.rx_io_num < 0 || rtc_gpio_is_valid_gpio(cfg->uart_pin_cfg.rx_io_num)), ESP_FAIL, LP_UART_TAG, "rx_io_num error");
ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.rts_io_num < 0 || rtc_gpio_is_valid_gpio(cfg->uart_pin_cfg.rts_io_num)), ESP_FAIL, LP_UART_TAG, "rts_io_num error");
ESP_RETURN_ON_FALSE((cfg->uart_pin_cfg.cts_io_num < 0 || rtc_gpio_is_valid_gpio(cfg->uart_pin_cfg.cts_io_num)), ESP_FAIL, LP_UART_TAG, "cts_io_num error");
#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */
/* Configure Tx Pin */ /* Configure Tx Pin */
ret = lp_uart_config_io(cfg->uart_pin_cfg.tx_io_num, RTC_GPIO_MODE_OUTPUT_ONLY); ret = lp_uart_config_io(cfg->uart_pin_cfg.tx_io_num, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_TX_PIN_IDX);
/* Configure Rx Pin */ /* Configure Rx Pin */
ret = lp_uart_config_io(cfg->uart_pin_cfg.rx_io_num, RTC_GPIO_MODE_INPUT_ONLY); ret = lp_uart_config_io(cfg->uart_pin_cfg.rx_io_num, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_RX_PIN_IDX);
/* Configure RTS Pin */ /* Configure RTS Pin */
ret = lp_uart_config_io(cfg->uart_pin_cfg.rts_io_num, RTC_GPIO_MODE_OUTPUT_ONLY); ret = lp_uart_config_io(cfg->uart_pin_cfg.rts_io_num, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_RTS_PIN_IDX);
/* Configure CTS Pin */ /* Configure CTS Pin */
ret = lp_uart_config_io(cfg->uart_pin_cfg.cts_io_num, RTC_GPIO_MODE_INPUT_ONLY); ret = lp_uart_config_io(cfg->uart_pin_cfg.cts_io_num, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_CTS_PIN_IDX);
return ret; return ret;
} }

View File

@ -285,7 +285,7 @@ examples/system/ulp/lp_core/lp_uart/lp_uart_echo:
- if: SOC_ULP_LP_UART_SUPPORTED != 1 - if: SOC_ULP_LP_UART_SUPPORTED != 1
- if: IDF_TARGET == "esp32p4" - if: IDF_TARGET == "esp32p4"
temporary: true temporary: true
reason: target esp32p4 is not supported yet TODO IDF-7533 reason: target esp32p4 is not supported yet TODO IDF-9407
depends_components: depends_components:
- ulp - ulp
@ -294,7 +294,7 @@ examples/system/ulp/lp_core/lp_uart/lp_uart_print:
- if: SOC_ULP_LP_UART_SUPPORTED != 1 - if: SOC_ULP_LP_UART_SUPPORTED != 1
- if: IDF_TARGET == "esp32p4" - if: IDF_TARGET == "esp32p4"
temporary: true temporary: true
reason: target esp32p4 is not supported yet TODO IDF-7533 reason: target esp32p4 is not supported yet TODO IDF-9407
depends_components: depends_components:
- ulp - ulp