feat(gpio): reserve gpio output atomically

This commit is contained in:
morris 2024-02-20 15:20:33 +08:00
parent c460e1cd7e
commit c952cfb673
10 changed files with 86 additions and 68 deletions

View File

@ -46,7 +46,7 @@ typedef struct {
typedef struct { typedef struct {
int source; /*!< ISR source */ int source; /*!< ISR source */
int intr_alloc_flags; /*!< ISR alloc flag */ int intr_alloc_flags; /*!< ISR alloc flag */
void (*fn)(void*); /*!< ISR function */ void (*fn)(void *); /*!< ISR function */
void *arg; /*!< ISR function args*/ void *arg; /*!< ISR function args*/
void *handle; /*!< ISR handle */ void *handle; /*!< ISR handle */
esp_err_t ret; esp_err_t ret;
@ -1016,7 +1016,7 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask)
uint32_t drv, fun_sel, sig_out; uint32_t drv, fun_sel, sig_out;
gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, &pu, &pd, &ie, &oe, &od, &drv, &fun_sel, &sig_out, &slp_sel); gpio_hal_get_io_config(gpio_context.gpio_hal, gpio_num, &pu, &pd, &ie, &oe, &od, &drv, &fun_sel, &sig_out, &slp_sel);
fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_pin_reserved(gpio_num) ? " **RESERVED**" : ""); fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_reserved(BIT64(gpio_num)) ? " **RESERVED**" : "");
fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", pu, pd, drv); fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", pu, pd, drv);
fprintf(out_stream, " InputEn: %d, OutputEn: %d, OpenDrain: %d\n", ie, oe, od); fprintf(out_stream, " InputEn: %d, OutputEn: %d, OpenDrain: %d\n", ie, oe, od);
fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", fun_sel, (fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX"); fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", fun_sel, (fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX");

View File

@ -1,29 +1,30 @@
/* /*
* 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
*/ */
#include <stdatomic.h>
#include "soc/soc_caps.h"
#include "esp_types.h" #include "esp_types.h"
#include "esp_bit_defs.h" #include "esp_bit_defs.h"
#include "soc/soc_caps.h" #include "esp_private/esp_gpio_reserve.h"
static uint64_t s_reserve_status = 0; static _Atomic uint64_t s_reserved_pin_mask = ATOMIC_VAR_INIT(~(SOC_GPIO_VALID_OUTPUT_GPIO_MASK));
void esp_gpio_reserve_pins(uint64_t mask) uint64_t esp_gpio_reserve(uint64_t gpio_mask)
{ {
#if SOC_GPIO_PIN_COUNT < 64 return atomic_fetch_or(&s_reserved_pin_mask, gpio_mask);
mask &= BIT64(SOC_GPIO_PIN_COUNT) - 1;
#endif
s_reserve_status |= mask;
} }
bool esp_gpio_is_pin_reserved(uint32_t gpio_num) uint64_t esp_gpio_revoke(uint64_t gpio_mask)
{ {
if (gpio_num >= SOC_GPIO_PIN_COUNT) { return atomic_fetch_and(&s_reserved_pin_mask, ~gpio_mask);
return false; }
}
return !!(s_reserve_status & BIT64(gpio_num)); bool esp_gpio_is_reserved(uint64_t gpio_mask)
{
return atomic_load(&s_reserved_pin_mask) & gpio_mask;
} }
// TODO: IDF-6968 reserve the pins that not fanned out regarding the SiP version // TODO: IDF-6968 reserve the pins that not fanned out regarding the SiP version

View File

@ -1,18 +1,25 @@
/* /*
* 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
*/ */
/** /**
* File Introduction: * Background:
* This file is used to reserve the GPIOs runtime, which has been occupied by FLASH/PSRAM or
* the GPIOs that not fan out.
* *
* The FLASH pins can be tuned according to eFuse, pins will be reserved in the `esp_mspi_pin_init` * - On some **modules**, specific GPIOs are connected to the PSRAM or Flash, and they shouldn't be used as general purpose IOs in the user's projects.
* while starting the CPU. * - Some GPIO may be not fan-out in the SiP variant.
* - GPIO A is driven by peripheral M, we don't want peripheral N to use the same GPIO.
* - User may deliver a board where a GPIO is used for a special purpose or even not fan-out on the PCB, they want to reserve it in the BSP package.
* ...
*/
/**
* Usage Attention:
* *
* As for the PSRAM pins, they are initialized after CPU started. They will be reserved in * - If a GPIO is used by IO MUX, no matter it's used as Input or Output, we should reserve it, because IO MUX's different "FUNC" has its dedicated peripheral.
* the `psram_gpio_config` when enabling the PSRAM. * - If a GPIO is used by Matrix, and only use its output path, we should reserve it, because we can't bind multiple peripheral output signals to the same GPIO.
* - When doing GPIO reserve, we must check its return value, to ensure the same GPIO is not reserved already.
*/ */
#pragma once #pragma once
@ -24,22 +31,30 @@ extern "C" {
#endif #endif
/** /**
* @brief Set the reserved pin * @brief Reserve the given GPIOs by mask, so they can't be used by others
* @note A same gpio can be reserve repetitively, but can't be clear once it is reserved
* *
* @param[in] mask Mask of GPIO reserved pins * @param gpio_mask Mask of the GPIOs to be reserved
* @return The mask of the GPIOs that were already reserved before this call
*/ */
void esp_gpio_reserve_pins(uint64_t mask); uint64_t esp_gpio_reserve(uint64_t gpio_mask);
/** /**
* @brief Check whether the pin has been reserved * @brief Revoke the given GPIOs by mask, so they can be reused again by others
* *
* @param[in] gpio_num GPIO pin number, please input a gpio number within `SOC_GPIO_PIN_COUNT` * @param gpio_mask Mask of the GPIOs to be revoked
* @return * @return The mask of the GPIOs that were already reserved before this call
* - true This gpio is reserved for FLASH or PSRAM
* - false This gpio is available for other purposes
*/ */
bool esp_gpio_is_pin_reserved(uint32_t gpio_num); uint64_t esp_gpio_revoke(uint64_t gpio_mask);
/**
* @brief Check whether the given GPIOs are reserved
*
* @param gpio_mask Mask of the GPIOs to be checked
* @return
* - true Aay of the given GPIO(s) is reserved
* - false Aay of the given GPIO(s) is not reserved
*/
bool esp_gpio_is_reserved(uint64_t gpio_mask);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -13,8 +13,6 @@ entries:
cpu: esp_cpu_compare_and_set (noflash) cpu: esp_cpu_compare_and_set (noflash)
esp_memory_utils (noflash) esp_memory_utils (noflash)
rtc_clk (noflash) rtc_clk (noflash)
esp_gpio_reserve: esp_gpio_reserve_pins (noflash)
esp_gpio_reserve: esp_gpio_is_pin_reserved (noflash)
if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y: if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y:
rtc_init:rtc_vddsdio_get_config (noflash) rtc_init:rtc_vddsdio_get_config (noflash)
rtc_init:rtc_vddsdio_set_config (noflash) rtc_init:rtc_vddsdio_set_config (noflash)

View File

@ -1,13 +1,13 @@
/* /*
Driver bits for PSRAM chips (at the moment only the ESP-PSRAM32 chip). * SPDX-FileCopyrightText: 2013-2024 Espressif Systems (Shanghai) CO LTD
*/
/*
* SPDX-FileCopyrightText: 2013-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
/*
Driver bits for PSRAM chips (at the moment only the ESP-PSRAM32 chip).
*/
#include "sdkconfig.h" #include "sdkconfig.h"
#include "string.h" #include "string.h"
#include "esp_attr.h" #include "esp_attr.h"
@ -829,14 +829,14 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_speed_
} }
// Reserve psram pins // Reserve psram pins
esp_gpio_reserve_pins(BIT64(psram_io->flash_clk_io) | esp_gpio_reserve(BIT64(psram_io->flash_clk_io) |
BIT64(psram_io->flash_cs_io) | BIT64(psram_io->flash_cs_io) |
BIT64(psram_io->psram_clk_io) | BIT64(psram_io->psram_clk_io) |
BIT64(psram_io->psram_cs_io) | BIT64(psram_io->psram_cs_io) |
BIT64(psram_io->psram_spiq_sd0_io) | BIT64(psram_io->psram_spiq_sd0_io) |
BIT64(psram_io->psram_spid_sd1_io) | BIT64(psram_io->psram_spid_sd1_io) |
BIT64(psram_io->psram_spihd_sd2_io) | BIT64(psram_io->psram_spihd_sd2_io) |
BIT64(psram_io->psram_spiwp_sd3_io)); BIT64(psram_io->psram_spiwp_sd3_io));
} }
//used in UT only //used in UT only

View File

@ -1,13 +1,13 @@
/* /*
Driver bits for PSRAM chips (at the moment only the ESP-PSRAM32 chip). * SPDX-FileCopyrightText: 2013-2024 Espressif Systems (Shanghai) CO LTD
*/
/*
* SPDX-FileCopyrightText: 2013-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
/*
Driver bits for PSRAM chips (at the moment only the ESP-PSRAM32 chip).
*/
#include "sdkconfig.h" #include "sdkconfig.h"
#include "string.h" #include "string.h"
#include "esp_attr.h" #include "esp_attr.h"
@ -383,14 +383,14 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_speed_t mode)
s_psram_cs_io = psram_io.psram_cs_io; s_psram_cs_io = psram_io.psram_cs_io;
// Preserve psram pins // Preserve psram pins
esp_gpio_reserve_pins(BIT64(psram_io.flash_clk_io) | esp_gpio_reserve(BIT64(psram_io.flash_clk_io) |
BIT64(psram_io.flash_cs_io) | BIT64(psram_io.flash_cs_io) |
BIT64(psram_io.psram_clk_io) | BIT64(psram_io.psram_clk_io) |
BIT64(psram_io.psram_cs_io) | BIT64(psram_io.psram_cs_io) |
BIT64(psram_io.psram_spiq_sd0_io) | BIT64(psram_io.psram_spiq_sd0_io) |
BIT64(psram_io.psram_spid_sd1_io) | BIT64(psram_io.psram_spid_sd1_io) |
BIT64(psram_io.psram_spihd_sd2_io) | BIT64(psram_io.psram_spihd_sd2_io) |
BIT64(psram_io.psram_spiwp_sd3_io)); BIT64(psram_io.psram_spiwp_sd3_io));
} }
//used in UT only //used in UT only

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -266,7 +266,7 @@ static void s_init_psram_pins(void)
REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3); REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3);
// Preserve psram pins // Preserve psram pins
esp_gpio_reserve_pins(BIT64(OCT_PSRAM_CS1_IO)); esp_gpio_reserve(BIT64(OCT_PSRAM_CS1_IO));
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2013-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2013-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -299,7 +299,7 @@ static void psram_gpio_config(void)
esp_rom_spiflash_select_qio_pins(wp_io, spiconfig); esp_rom_spiflash_select_qio_pins(wp_io, spiconfig);
// Reserve psram pins // Reserve psram pins
esp_gpio_reserve_pins(BIT64(cs1_io) | BIT64(wp_io)); esp_gpio_reserve(BIT64(cs1_io) | BIT64(wp_io));
} }
esp_err_t esp_psram_impl_enable(void) //psram init esp_err_t esp_psram_impl_enable(void) //psram init

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -50,3 +50,7 @@ esp_err_t esp_psram_impl_enable(void);
* @return psram CS IO * @return psram CS IO
*/ */
uint8_t esp_psram_impl_get_cs_io(void); uint8_t esp_psram_impl_get_cs_io(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -153,7 +153,7 @@ void IRAM_ATTR esp_mspi_pin_init(void)
for (esp_mspi_io_t i = 0; i < ESP_MSPI_IO_MAX; i++) { for (esp_mspi_io_t i = 0; i < ESP_MSPI_IO_MAX; i++) {
reserve_pin_mask |= BIT64(esp_mspi_get_io(i)); reserve_pin_mask |= BIT64(esp_mspi_get_io(i));
} }
esp_gpio_reserve_pins(reserve_pin_mask); esp_gpio_reserve(reserve_pin_mask);
} }
esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) esp_err_t IRAM_ATTR spi_flash_init_chip_state(void)