mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 10:47:19 +02:00
Merge branch 'feature/add_uart_io_deinit_process_v5.3' into 'release/v5.3'
fix(uart): eliminate garbled data on TX/RX line in sleep (v5.3) See merge request espressif/esp-idf!39281
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -33,6 +33,8 @@
|
|||||||
#include "hal/dedic_gpio_ll.h"
|
#include "hal/dedic_gpio_ll.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEDIC_GPIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||||
|
|
||||||
static const char *TAG = "dedic_gpio";
|
static const char *TAG = "dedic_gpio";
|
||||||
|
|
||||||
typedef struct dedic_gpio_platform_t dedic_gpio_platform_t;
|
typedef struct dedic_gpio_platform_t dedic_gpio_platform_t;
|
||||||
@ -75,7 +77,7 @@ static esp_err_t dedic_gpio_build_platform(int core_id)
|
|||||||
// prevent building platform concurrently
|
// prevent building platform concurrently
|
||||||
_lock_acquire(&s_platform_mutexlock[core_id]);
|
_lock_acquire(&s_platform_mutexlock[core_id]);
|
||||||
if (!s_platform[core_id]) {
|
if (!s_platform[core_id]) {
|
||||||
s_platform[core_id] = calloc(1, sizeof(dedic_gpio_platform_t));
|
s_platform[core_id] = (dedic_gpio_platform_t *)heap_caps_calloc(1, sizeof(dedic_gpio_platform_t), DEDIC_GPIO_MEM_ALLOC_CAPS);
|
||||||
if (s_platform[core_id]) {
|
if (s_platform[core_id]) {
|
||||||
// initialize platform members
|
// initialize platform members
|
||||||
s_platform[core_id]->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
s_platform[core_id]->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||||
@ -213,7 +215,7 @@ esp_err_t dedic_gpio_new_bundle(const dedic_gpio_bundle_config_t *config, dedic_
|
|||||||
ESP_GOTO_ON_ERROR(dedic_gpio_build_platform(core_id), err, TAG, "build platform %d failed", core_id);
|
ESP_GOTO_ON_ERROR(dedic_gpio_build_platform(core_id), err, TAG, "build platform %d failed", core_id);
|
||||||
|
|
||||||
size_t bundle_size = sizeof(dedic_gpio_bundle_t) + config->array_size * sizeof(config->gpio_array[0]);
|
size_t bundle_size = sizeof(dedic_gpio_bundle_t) + config->array_size * sizeof(config->gpio_array[0]);
|
||||||
bundle = calloc(1, bundle_size);
|
bundle = (dedic_gpio_bundle_t *)heap_caps_calloc(1, bundle_size, DEDIC_GPIO_MEM_ALLOC_CAPS);
|
||||||
ESP_GOTO_ON_FALSE(bundle, ESP_ERR_NO_MEM, err, TAG, "no mem for bundle");
|
ESP_GOTO_ON_FALSE(bundle, ESP_ERR_NO_MEM, err, TAG, "no mem for bundle");
|
||||||
|
|
||||||
// for performance reasons, we only search for continuous channels
|
// for performance reasons, we only search for continuous channels
|
||||||
|
@ -76,7 +76,7 @@ static gpio_context_t gpio_context = {
|
|||||||
|
|
||||||
esp_err_t gpio_pullup_en(gpio_num_t gpio_num)
|
esp_err_t gpio_pullup_en(gpio_num_t gpio_num)
|
||||||
{
|
{
|
||||||
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error (input-only pad has no internal PU)", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
|
if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
|
||||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||||
@ -114,7 +114,7 @@ esp_err_t gpio_pullup_dis(gpio_num_t gpio_num)
|
|||||||
|
|
||||||
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num)
|
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num)
|
||||||
{
|
{
|
||||||
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error (input-only pad has no internal PD)", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
|
if (!rtc_gpio_is_valid_gpio(gpio_num) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
|
||||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||||
|
@ -34,7 +34,8 @@ extern "C" {
|
|||||||
* @brief UART configuration parameters for uart_param_config function
|
* @brief UART configuration parameters for uart_param_config function
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int baud_rate; /*!< UART baud rate*/
|
int baud_rate; /*!< UART baud rate
|
||||||
|
Note that the actual baud rate set could have a slight deviation from the user-configured value due to rounding error*/
|
||||||
uart_word_length_t data_bits; /*!< UART byte size*/
|
uart_word_length_t data_bits; /*!< UART byte size*/
|
||||||
uart_parity_t parity; /*!< UART parity mode*/
|
uart_parity_t parity; /*!< UART parity mode*/
|
||||||
uart_stop_bits_t stop_bits; /*!< UART stop bits*/
|
uart_stop_bits_t stop_bits; /*!< UART stop bits*/
|
||||||
@ -225,7 +226,9 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode);
|
|||||||
esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz);
|
esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set UART baud rate.
|
* @brief Set desired UART baud rate.
|
||||||
|
*
|
||||||
|
* Note that the actual baud rate set could have a slight deviation from the user-configured value due to rounding error.
|
||||||
*
|
*
|
||||||
* @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 baudrate UART baud rate.
|
* @param baudrate UART baud rate.
|
||||||
@ -237,7 +240,9 @@ esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz);
|
|||||||
esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);
|
esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the UART baud rate configuration.
|
* @brief Get the actual UART baud rate.
|
||||||
|
*
|
||||||
|
* It returns the real UART rate set in the hardware. It could have a slight deviation from the user-configured baud rate.
|
||||||
*
|
*
|
||||||
* @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 baudrate Pointer to accept value of UART baud rate
|
* @param baudrate Pointer to accept value of UART baud rate
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
#include "hal/rtc_io_ll.h"
|
#include "hal/rtc_io_ll.h"
|
||||||
#include "driver/lp_io.h"
|
#include "driver/lp_io.h"
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
#include "soc/lp_gpio_pins.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#include "clk_ctrl_os.h"
|
#include "clk_ctrl_os.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
@ -105,6 +108,10 @@ static const char *UART_TAG = "uart";
|
|||||||
.hal.dev = UART_LL_GET_HW(uart_num), \
|
.hal.dev = UART_LL_GET_HW(uart_num), \
|
||||||
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
|
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
|
||||||
.hw_enabled = false, \
|
.hw_enabled = false, \
|
||||||
|
.tx_io_num = -1, \
|
||||||
|
.rx_io_num = -1, \
|
||||||
|
.rts_io_num = -1, \
|
||||||
|
.cts_io_num = -1, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -170,6 +177,10 @@ typedef struct {
|
|||||||
bool retention_link_inited; /*!< Mark whether the retention link is inited */
|
bool retention_link_inited; /*!< Mark whether the retention link is inited */
|
||||||
bool retention_link_created; /*!< Mark whether the retention link is created */
|
bool retention_link_created; /*!< Mark whether the retention link is created */
|
||||||
#endif
|
#endif
|
||||||
|
int tx_io_num;
|
||||||
|
int rx_io_num;
|
||||||
|
int rts_io_num;
|
||||||
|
int cts_io_num;
|
||||||
} uart_context_t;
|
} uart_context_t;
|
||||||
|
|
||||||
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
||||||
@ -703,8 +714,69 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//internal signal can be output to multiple GPIO pads
|
static void uart_release_pin(uart_port_t uart_num)
|
||||||
//only one GPIO pad can connect with input signal
|
{
|
||||||
|
if (uart_num >= UART_NUM_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uart_context[uart_num].tx_io_num >= 0) {
|
||||||
|
gpio_ll_output_disable(&GPIO, uart_context[uart_num].tx_io_num);
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
if (!(uart_num < SOC_UART_HP_NUM)) {
|
||||||
|
rtc_gpio_deinit(uart_context[uart_num].tx_io_num);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
|
||||||
|
gpio_sleep_sel_en(uart_context[uart_num].tx_io_num); // re-enable the switch to the sleep configuration to save power consumption
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].rx_io_num >= 0) {
|
||||||
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
|
||||||
|
}
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
else {
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
|
||||||
|
#endif
|
||||||
|
rtc_gpio_deinit(uart_context[uart_num].rx_io_num);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
|
||||||
|
gpio_sleep_sel_en(uart_context[uart_num].rx_io_num); // re-enable the switch to the sleep configuration to save power consumption
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].rts_io_num >= 0) {
|
||||||
|
gpio_ll_output_disable(&GPIO, uart_context[uart_num].rts_io_num);
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
if (!(uart_num < SOC_UART_HP_NUM)) {
|
||||||
|
rtc_gpio_deinit(uart_context[uart_num].rts_io_num);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].cts_io_num >= 0) {
|
||||||
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
|
||||||
|
}
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
else {
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
|
||||||
|
#endif
|
||||||
|
rtc_gpio_deinit(uart_context[uart_num].cts_io_num);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_context[uart_num].tx_io_num = -1;
|
||||||
|
uart_context[uart_num].rx_io_num = -1;
|
||||||
|
uart_context[uart_num].rts_io_num = -1;
|
||||||
|
uart_context[uart_num].cts_io_num = -1;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
|
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
||||||
@ -736,48 +808,68 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// First, release previously configured IOs if there is
|
||||||
|
uart_release_pin(uart_num);
|
||||||
|
|
||||||
// Since an IO cannot route peripheral signals via IOMUX and GPIO matrix at the same time,
|
// Since an IO cannot route peripheral signals via IOMUX and GPIO matrix at the same time,
|
||||||
// if tx and rx share the same IO, both signals need to be route to IOs through GPIO matrix
|
// if tx and rx share the same IO, both signals need to be route to IOs through GPIO matrix
|
||||||
bool tx_rx_same_io = (tx_io_num == rx_io_num);
|
bool tx_rx_same_io = (tx_io_num == rx_io_num);
|
||||||
|
|
||||||
/* In the following statements, if the io_num is negative, no need to configure anything. */
|
/* In the following statements, if the io_num is negative, no need to configure anything. */
|
||||||
if (tx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX))) {
|
if (tx_io_num >= 0) {
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
uart_context[uart_num].tx_io_num = tx_io_num;
|
||||||
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
|
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
|
||||||
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
|
||||||
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
// But TX IO in isolate state could write garbled data to the other end
|
||||||
// (output enabled too early may cause unnecessary level change at the pad)
|
// Therefore, we should disable the switch of the TX pin to sleep configuration
|
||||||
}
|
gpio_sleep_sel_dis(tx_io_num);
|
||||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
|
||||||
else {
|
|
||||||
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
|
|
||||||
|
|
||||||
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
|
||||||
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
|
||||||
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
if (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX))) {
|
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
||||||
gpio_func_sel(rx_io_num, PIN_FUNC_GPIO);
|
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
||||||
gpio_ll_input_enable(&GPIO, rx_io_num);
|
// (output enabled too early may cause unnecessary level change at the pad)
|
||||||
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
}
|
||||||
}
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
else {
|
||||||
else {
|
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
|
||||||
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
|
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
||||||
rtc_gpio_set_direction(rx_io_num, mode);
|
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
|
||||||
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
|
|
||||||
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
|
if (rx_io_num >= 0) {
|
||||||
|
uart_context[uart_num].rx_io_num = rx_io_num;
|
||||||
|
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
|
||||||
|
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
|
||||||
|
// But RX IO in isolate state could receive garbled data into FIFO, which is not desired
|
||||||
|
// Therefore, we should disable the switch of the RX pin to sleep configuration
|
||||||
|
gpio_sleep_sel_dis(rx_io_num);
|
||||||
|
#endif
|
||||||
|
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
|
||||||
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
|
gpio_func_sel(rx_io_num, PIN_FUNC_GPIO);
|
||||||
|
gpio_ll_input_enable(&GPIO, rx_io_num);
|
||||||
|
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
||||||
|
}
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
else {
|
||||||
|
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
|
||||||
|
rtc_gpio_set_direction(rx_io_num, mode);
|
||||||
|
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
|
||||||
|
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
|
||||||
|
}
|
||||||
|
|
||||||
|
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rts_io_num >= 0 && (uart_context[uart_num].rts_io_num = rts_io_num, !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX))) {
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
|
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
|
||||||
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
|
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
|
||||||
@ -792,7 +884,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
|
if (cts_io_num >= 0 && (uart_context[uart_num].cts_io_num = cts_io_num, !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX))) {
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
gpio_func_sel(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_pull_mode(cts_io_num, GPIO_PULLUP_ONLY);
|
||||||
@ -1780,6 +1872,9 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
|||||||
ESP_LOGI(UART_TAG, "ALREADY NULL");
|
ESP_LOGI(UART_TAG, "ALREADY NULL");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uart_release_pin(uart_num);
|
||||||
|
|
||||||
esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
||||||
uart_disable_rx_intr(uart_num);
|
uart_disable_rx_intr(uart_num);
|
||||||
uart_disable_tx_intr(uart_num);
|
uart_disable_tx_intr(uart_num);
|
||||||
|
@ -880,7 +880,7 @@ static int uart_tcgetattr(int fd, struct termios *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uint32_t baudrate;
|
uint32_t baudrate = 0;
|
||||||
if (uart_get_baudrate(fd, &baudrate) != ESP_OK) {
|
if (uart_get_baudrate(fd, &baudrate) != ESP_OK) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -543,13 +543,9 @@ static void IRAM_ATTR resume_timers(uint32_t pd_flags) {
|
|||||||
static void IRAM_ATTR flush_uarts(void)
|
static void IRAM_ATTR flush_uarts(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
|
||||||
esp_rom_output_tx_wait_idle(i);
|
|
||||||
#else
|
|
||||||
if (uart_ll_is_enabled(i)) {
|
if (uart_ll_is_enabled(i)) {
|
||||||
esp_rom_output_tx_wait_idle(i);
|
esp_rom_output_tx_wait_idle(i);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,11 +559,9 @@ FORCE_INLINE_ATTR void suspend_uarts(void)
|
|||||||
{
|
{
|
||||||
s_suspended_uarts_bmap = 0;
|
s_suspended_uarts_bmap = 0;
|
||||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
|
||||||
if (!uart_ll_is_enabled(i)) {
|
if (!uart_ll_is_enabled(i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
uart_ll_force_xoff(i);
|
uart_ll_force_xoff(i);
|
||||||
s_suspended_uarts_bmap |= BIT(i);
|
s_suspended_uarts_bmap |= BIT(i);
|
||||||
#if SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
|
#if SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
|
||||||
|
@ -107,12 +107,14 @@ static inline void uart_ll_reset_register(uart_port_t uart_num)
|
|||||||
// ESP32C3 requires a workaround: enable core reset before enabling uart module clock to prevent uart output garbage value
|
// ESP32C3 requires a workaround: enable core reset before enabling uart module clock to prevent uart output garbage value
|
||||||
switch (uart_num) {
|
switch (uart_num) {
|
||||||
case 0:
|
case 0:
|
||||||
|
SYSTEM.perip_rst_en0.reg_uart_rst = 0;
|
||||||
UART0.clk_conf.rst_core = 1;
|
UART0.clk_conf.rst_core = 1;
|
||||||
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;
|
||||||
UART0.clk_conf.rst_core = 0;
|
UART0.clk_conf.rst_core = 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
SYSTEM.perip_rst_en0.reg_uart1_rst = 0;
|
||||||
UART1.clk_conf.rst_core = 1;
|
UART1.clk_conf.rst_core = 1;
|
||||||
SYSTEM.perip_rst_en0.reg_uart1_rst = 1;
|
SYSTEM.perip_rst_en0.reg_uart1_rst = 1;
|
||||||
SYSTEM.perip_rst_en0.reg_uart1_rst = 0;
|
SYSTEM.perip_rst_en0.reg_uart1_rst = 0;
|
||||||
|
@ -112,18 +112,21 @@ static inline void uart_ll_reset_register(uart_port_t uart_num)
|
|||||||
// ESP32S3 requires a workaround: enable core reset before enabling uart module clock to prevent uart output garbage value
|
// ESP32S3 requires a workaround: enable core reset before enabling uart module clock to prevent uart output garbage value
|
||||||
switch (uart_num) {
|
switch (uart_num) {
|
||||||
case 0:
|
case 0:
|
||||||
|
SYSTEM.perip_rst_en0.uart_rst = 0;
|
||||||
UART0.clk_conf.rst_core = 1;
|
UART0.clk_conf.rst_core = 1;
|
||||||
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;
|
||||||
UART0.clk_conf.rst_core = 0;
|
UART0.clk_conf.rst_core = 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
SYSTEM.perip_rst_en0.uart1_rst = 0;
|
||||||
UART1.clk_conf.rst_core = 1;
|
UART1.clk_conf.rst_core = 1;
|
||||||
SYSTEM.perip_rst_en0.uart1_rst = 1;
|
SYSTEM.perip_rst_en0.uart1_rst = 1;
|
||||||
SYSTEM.perip_rst_en0.uart1_rst = 0;
|
SYSTEM.perip_rst_en0.uart1_rst = 0;
|
||||||
UART1.clk_conf.rst_core = 0;
|
UART1.clk_conf.rst_core = 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
SYSTEM.perip_rst_en1.uart2_rst = 0;
|
||||||
UART2.clk_conf.rst_core = 1;
|
UART2.clk_conf.rst_core = 1;
|
||||||
SYSTEM.perip_rst_en1.uart2_rst = 1;
|
SYSTEM.perip_rst_en1.uart2_rst = 1;
|
||||||
SYSTEM.perip_rst_en1.uart2_rst = 0;
|
SYSTEM.perip_rst_en1.uart2_rst = 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -264,7 +264,7 @@ static void parse_rmc(esp_gps_t *esp_gps)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: /* Process ground speed in unit m/s */
|
case 7: /* Process ground speed in unit m/s */
|
||||||
esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852;
|
esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 0.514444;
|
||||||
break;
|
break;
|
||||||
case 8: /* Process true course over ground */
|
case 8: /* Process true course over ground */
|
||||||
esp_gps->parent.cog = strtof(esp_gps->item_str, NULL);
|
esp_gps->parent.cog = strtof(esp_gps->item_str, NULL);
|
||||||
@ -338,7 +338,7 @@ static void parse_vtg(esp_gps_t *esp_gps)
|
|||||||
esp_gps->parent.variation = strtof(esp_gps->item_str, NULL);
|
esp_gps->parent.variation = strtof(esp_gps->item_str, NULL);
|
||||||
break;
|
break;
|
||||||
case 5:/* Process ground speed in unit m/s */
|
case 5:/* Process ground speed in unit m/s */
|
||||||
esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 1.852;//knots to m/s
|
esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) * 0.514444;//knots to m/s
|
||||||
break;
|
break;
|
||||||
case 7:/* Process ground speed in unit m/s */
|
case 7:/* Process ground speed in unit m/s */
|
||||||
esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) / 3.6;//km/h to m/s
|
esp_gps->parent.speed = strtof(esp_gps->item_str, NULL) / 3.6;//km/h to m/s
|
||||||
@ -702,7 +702,7 @@ nmea_parser_handle_t nmea_parser_init(const nmea_parser_config_t *config)
|
|||||||
.task_name = NULL
|
.task_name = NULL
|
||||||
};
|
};
|
||||||
if (esp_event_loop_create(&loop_args, &esp_gps->event_loop_hdl) != ESP_OK) {
|
if (esp_event_loop_create(&loop_args, &esp_gps->event_loop_hdl) != ESP_OK) {
|
||||||
ESP_LOGE(GPS_TAG, "create event loop faild");
|
ESP_LOGE(GPS_TAG, "create event loop failed");
|
||||||
goto err_eloop;
|
goto err_eloop;
|
||||||
}
|
}
|
||||||
/* Create NMEA Parser task */
|
/* Create NMEA Parser task */
|
||||||
|
@ -64,7 +64,7 @@ build_stage2() {
|
|||||||
--size-file size.json \
|
--size-file size.json \
|
||||||
--keep-going \
|
--keep-going \
|
||||||
--collect-size-info size_info.txt \
|
--collect-size-info size_info.txt \
|
||||||
--default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c5 esp32c6 esp32h2 esp32p4 esp32c61
|
--default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2 esp32p4 esp32c61
|
||||||
}
|
}
|
||||||
|
|
||||||
build_stage1() {
|
build_stage1() {
|
||||||
@ -78,36 +78,7 @@ build_stage1() {
|
|||||||
--build-log ${BUILD_LOG_CMAKE} \
|
--build-log ${BUILD_LOG_CMAKE} \
|
||||||
--size-file size.json \
|
--size-file size.json \
|
||||||
--collect-size-info size_info.txt \
|
--collect-size-info size_info.txt \
|
||||||
--default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c5 esp32c6 esp32h2 esp32p4 esp32c61
|
--default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2 esp32p4 esp32c61
|
||||||
}
|
|
||||||
|
|
||||||
# TODO: IDF-9197 remove the additional test for esp32c5 beta3
|
|
||||||
build_c5beta3() {
|
|
||||||
# Update the config to select C5 beta3
|
|
||||||
C5BETA3_CFG="CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION=y\nCONFIG_IDF_TARGET_ESP32C5_MP_VERSION=n"
|
|
||||||
if [ $1 = 1 ]
|
|
||||||
then
|
|
||||||
echo "${C5BETA3_CFG}" >> ${TEMPLATE_APP_PATH}/sdkconfig.ci2.Og
|
|
||||||
CONFIG_STR=$(get_config_str sdkconfig.ci2.*=)
|
|
||||||
KEEP_GOING=""
|
|
||||||
else
|
|
||||||
echo "${C5BETA3_CFG}" >> ${TEMPLATE_APP_PATH}/sdkconfig.ci.O0
|
|
||||||
echo "${C5BETA3_CFG}" >> ${TEMPLATE_APP_PATH}/sdkconfig.ci.Os
|
|
||||||
echo "${C5BETA3_CFG}" >> ${TEMPLATE_APP_PATH}/sdkconfig.ci.O2
|
|
||||||
CONFIG_STR=$(get_config_str sdkconfig.ci.*=)
|
|
||||||
KEEP_GOING=" --keep-going"
|
|
||||||
fi
|
|
||||||
python -m idf_build_apps build -vv \
|
|
||||||
-p ${TEMPLATE_APP_PATH} \
|
|
||||||
-t esp32c5 \
|
|
||||||
${CONFIG_STR} \
|
|
||||||
--work-dir ${BUILD_PATH}/cmake \
|
|
||||||
--build-dir ${BUILD_DIR} \
|
|
||||||
--build-log ${BUILD_LOG_CMAKE} \
|
|
||||||
--size-file size.json \
|
|
||||||
${KEEP_GOING} \
|
|
||||||
--collect-size-info size_info.txt \
|
|
||||||
--default-build-targets esp32c5
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Default arguments
|
# Default arguments
|
||||||
@ -135,7 +106,3 @@ then
|
|||||||
else
|
else
|
||||||
build_stage2
|
build_stage2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# TODO: IDF-9197 remove the additional test for esp32c5 beta3
|
|
||||||
echo "Build ESP32-C5 beta3 additionally"
|
|
||||||
build_c5beta3 ${STAGE}
|
|
||||||
|
Reference in New Issue
Block a user