From 42039cde0aef26d93d222f61d757a0ff8df040f3 Mon Sep 17 00:00:00 2001 From: chenjianqiang Date: Fri, 2 Jul 2021 21:46:49 +0800 Subject: [PATCH 1/3] add flash and PSRAM CS IO acquire function --- .../bootloader_support/include/bootloader_common.h | 9 +++++++++ .../bootloader_support/src/bootloader_common.c | 14 +++++++++++++- components/esp32/include/esp32/spiram.h | 9 +++++++++ components/esp32/spiram.c | 4 ++++ components/esp32/spiram_psram.c | 8 ++++++++ components/esp32/spiram_psram.h | 7 +++++++ components/esp32s2/include/esp32s2/spiram.h | 9 +++++++++ components/esp32s2/spiram.c | 6 ++++++ components/esp32s2/spiram_psram.c | 8 ++++++++ components/esp32s2/spiram_psram.h | 6 ++++++ 10 files changed, 79 insertions(+), 1 deletion(-) diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index 0723d19512..6b04f59533 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -105,6 +105,15 @@ bool bootloader_common_label_search(const char *list, char *label); */ void bootloader_configure_spi_pins(int drv); +/** + * @brief Get flash CS IO + * + * Can be determined by eFuse values, or the default value + * + * @return Flash CS IO + */ +uint8_t bootloader_flash_get_cs_io(void); + /** * @brief Calculates a sha-256 for a given partition or returns a appended digest. * diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 0a081679b9..0fb2a48bb2 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -29,6 +29,7 @@ #include "esp_rom_crc.h" #include "esp_rom_gpio.h" #include "esp_rom_sys.h" +#include "esp_rom_efuse.h" #include "esp_flash_partitions.h" #include "bootloader_flash_priv.h" #include "bootloader_common.h" @@ -192,8 +193,19 @@ void bootloader_common_vddsdio_configure(void) #endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST } - RESET_REASON bootloader_common_get_reset_reason(int cpu_no) { return rtc_get_reset_reason(cpu_no); } + +uint8_t bootloader_flash_get_cs_io(void) +{ + uint8_t cs_io; + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { + cs_io = SPI_CS0_GPIO_NUM; + } else { + cs_io = (spiconfig >> 18) & 0x3f; + } + return cs_io; +} diff --git a/components/esp32/include/esp32/spiram.h b/components/esp32/include/esp32/spiram.h index ccbca2c0b8..0e9aeeaed8 100644 --- a/components/esp32/include/esp32/spiram.h +++ b/components/esp32/include/esp32/spiram.h @@ -89,6 +89,15 @@ size_t esp_spiram_get_size(void); */ void esp_spiram_writeback_cache(void); +/** + * @brief get psram CS IO + * + * This interface should be called after PSRAM is enabled, otherwise it will + * return an invalid value -1/0xff. + * + * @return psram CS IO or -1/0xff if psram not enabled + */ +uint8_t esp_spiram_get_cs_io(void); /** diff --git a/components/esp32/spiram.c b/components/esp32/spiram.c index e43acad59d..e7ee354cfd 100644 --- a/components/esp32/spiram.c +++ b/components/esp32/spiram.c @@ -296,4 +296,8 @@ bool esp_spiram_is_initialized(void) return spiram_inited; } +uint8_t esp_spiram_get_cs_io(void) +{ + return psram_get_cs_io(); +} #endif diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index 0e329fc6d9..8a289c174b 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -203,6 +203,13 @@ typedef struct { static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psram_vaddr_mode_t vaddrmode); +static uint8_t s_psram_cs_io = (uint8_t)-1; + +uint8_t psram_get_cs_io(void) +{ + return s_psram_cs_io; +} + static void psram_clear_spi_fifo(psram_spi_num_t spi_num) { int i; @@ -844,6 +851,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad ESP_EARLY_LOGE(TAG, "Not a valid or known package id: %d", pkg_ver); abort(); } + s_psram_cs_io = psram_io.psram_cs_io; const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { diff --git a/components/esp32/spiram_psram.h b/components/esp32/spiram_psram.h index 14f06cb41d..cd15d1115d 100644 --- a/components/esp32/spiram_psram.h +++ b/components/esp32/spiram_psram.h @@ -67,4 +67,11 @@ psram_size_t psram_get_size(void); */ esp_err_t psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode); +/** + * @brief get psram CS IO + * + * @return psram CS IO + */ +uint8_t psram_get_cs_io(void); + #endif diff --git a/components/esp32s2/include/esp32s2/spiram.h b/components/esp32s2/include/esp32s2/spiram.h index cc2b4c8549..7799182ba2 100644 --- a/components/esp32s2/include/esp32s2/spiram.h +++ b/components/esp32s2/include/esp32s2/spiram.h @@ -78,6 +78,15 @@ size_t esp_spiram_get_size(void); */ void esp_spiram_writeback_cache(void); +/** + * @brief get psram CS IO + * + * This interface should be called after PSRAM is enabled, otherwise it will + * return an invalid value -1/0xff. + * + * @return psram CS IO or -1/0xff if psram not enabled + */ +uint8_t esp_spiram_get_cs_io(void); /** diff --git a/components/esp32s2/spiram.c b/components/esp32s2/spiram.c index 3c0eaa4f8f..6b0c7f2a61 100644 --- a/components/esp32s2/spiram.c +++ b/components/esp32s2/spiram.c @@ -376,6 +376,11 @@ void IRAM_ATTR esp_spiram_writeback_cache(void) +uint8_t esp_spiram_get_cs_io(void) +{ + return psram_get_cs_io(); +} + /* Simple RAM test. Writes a word every 32 bytes. Takes about a second to complete for 4MiB. Returns true when RAM seems OK, false when test fails. WARNING: Do not run this before the 2nd cpu has been @@ -414,4 +419,5 @@ bool esp_spiram_test(void) return true; } } + #endif diff --git a/components/esp32s2/spiram_psram.c b/components/esp32s2/spiram_psram.c index b6bd73c70a..cf971f7e3b 100644 --- a/components/esp32s2/spiram_psram.c +++ b/components/esp32s2/spiram_psram.c @@ -168,6 +168,13 @@ static uint32_t s_psram_id = 0; static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psram_vaddr_mode_t vaddrmode); extern void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode); +static uint8_t s_psram_cs_io = (uint8_t)-1; + +uint8_t psram_get_cs_io(void) +{ + return s_psram_cs_io; +} + static void psram_set_op_mode(int spi_num, psram_cmd_mode_t mode) { if (mode == PSRAM_CMD_QPI) { @@ -375,6 +382,7 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode) psram_io.psram_spiwp_sd3_io = esp_rom_efuse_get_flash_wp_gpio(); } esp_rom_spiflash_select_qio_pins(psram_io.psram_spiwp_sd3_io, spiconfig); + s_psram_cs_io = psram_io.psram_cs_io; } psram_size_t psram_get_size(void) diff --git a/components/esp32s2/spiram_psram.h b/components/esp32s2/spiram_psram.h index ea7908f030..6ad464a0cb 100644 --- a/components/esp32s2/spiram_psram.h +++ b/components/esp32s2/spiram_psram.h @@ -76,5 +76,11 @@ typedef enum { esp_err_t esp_spiram_wrap_set(spiram_wrap_mode_t mode); +/** + * @brief get psram CS IO + * + * @return psram CS IO + */ +uint8_t psram_get_cs_io(void); #endif From acdf49a5acec6f61c220b8461aa535f98deac511 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 16 Sep 2021 16:30:28 +0800 Subject: [PATCH 2/3] light sleep: fix SPIRAM leakage when its CS pin has no hardware pullup --- components/esp_system/Kconfig | 9 +++++++++ components/esp_system/sleep_modes.c | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index e82335d2d3..cf26ebf951 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -100,6 +100,15 @@ menu "ESP System Settings" If enabled, the CPU will be powered down in light sleep. Enabling this option will consume 1.68 KB of internal RAM and will reduce sleep current consumption by about 100 uA. + config ESP_SYSTEM_PSRAM_LEAKAGE_WORKAROUND + bool "PSRAM leakage current workaround in light sleep" + depends on SPIRAM + help + When the CS pin of SPIRAM is not pulled up, the sleep current will + increase during light sleep. If the CS pin of SPIRAM has an external + pull-up, you do not need to select this option, otherwise, you + should enable this option. + menu "Memory protection" config ESP_SYSTEM_MEMPROT_FEATURE diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 8aaa1b18a5..e0fc4df91a 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -53,6 +53,7 @@ #include "esp32/clk.h" #include "esp32/rom/rtc.h" #include "esp_private/gpio.h" +#include "esp32/spiram.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/rom/cache.h" @@ -60,11 +61,13 @@ #include "esp32s2/brownout.h" #include "soc/extmem_reg.h" #include "esp_private/gpio.h" +#include "esp32s2/spiram.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/clk.h" #include "esp32s3/rom/cache.h" #include "esp32s3/rom/rtc.h" #include "soc/extmem_reg.h" +#include "esp32s3/spiram.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/clk.h" #include "esp32c3/rom/cache.h" @@ -418,6 +421,9 @@ void esp_sleep_config_gpio_isolate(void) gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING); } } +#if CONFIG_ESP_SYSTEM_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM + gpio_sleep_set_pull_mode(esp_spiram_get_cs_io(), GPIO_PULLUP_ONLY); +#endif } void esp_sleep_enable_gpio_switch(bool enable) From 3f17cc2ab80a408799ca793a83b16ff4dabea8f7 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 16 Sep 2021 16:35:03 +0800 Subject: [PATCH 3/3] light sleep: fix Flash leakage when its CS pin has no hardware pullup --- components/esp_system/Kconfig | 8 ++++++++ components/esp_system/sleep_modes.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index cf26ebf951..b7f681e45c 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -109,6 +109,14 @@ menu "ESP System Settings" pull-up, you do not need to select this option, otherwise, you should enable this option. + config ESP_SYSTEM_FLASH_LEAKAGE_WORKAROUND + bool "Flash leakage current workaround in light sleep" + help + When the CS pin of Flash is not pulled up, the sleep current will + increase during light sleep. If the CS pin of Flash has an external + pull-up, you do not need to select this option, otherwise, you + should enable this option. + menu "Memory protection" config ESP_SYSTEM_MEMPROT_FEATURE diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index e0fc4df91a..7c185a7363 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -29,6 +29,7 @@ #include "soc/soc_caps.h" #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" +#include "bootloader_common.h" #include "driver/uart.h" @@ -424,6 +425,9 @@ void esp_sleep_config_gpio_isolate(void) #if CONFIG_ESP_SYSTEM_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM gpio_sleep_set_pull_mode(esp_spiram_get_cs_io(), GPIO_PULLUP_ONLY); #endif +#if CONFIG_ESP_SYSTEM_FLASH_LEAKAGE_WORKAROUND + gpio_sleep_set_pull_mode(bootloader_flash_get_cs_io(), GPIO_PULLUP_ONLY); +#endif } void esp_sleep_enable_gpio_switch(bool enable)