Merge branch 'bugfix/esp32s3_lightsleep_psram_leakage_current' into 'master'

fix SPIRAM leakage when its CS pin has no hardware pullup

See merge request espressif/esp-idf!14730
This commit is contained in:
Li Shuai 2021-09-16 04:07:58 +00:00
commit b59902f4d1
17 changed files with 147 additions and 3 deletions

View File

@ -119,6 +119,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.
*

View File

@ -23,6 +23,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"
@ -191,8 +192,19 @@ void bootloader_common_vddsdio_configure(void)
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}
RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
{
return (RESET_REASON)esp_rom_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;
}

View File

@ -33,5 +33,22 @@ menu "Hardware Settings"
config ESP_SLEEP_RTC_BUS_ISO_WORKAROUND
bool
default y if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
config ESP_SLEEP_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.
config ESP_SLEEP_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.
endmenu
endmenu

View File

@ -85,6 +85,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);
/**

View File

@ -70,6 +70,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);
/**

View File

@ -79,6 +79,16 @@ void esp_spiram_writeback_cache(void);
*/
bool esp_spiram_is_initialized(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);
/**
* @brief Reserve a pool of internal memory for specific DMA/internal allocations
*

View File

@ -316,4 +316,8 @@ bool esp_spiram_is_initialized(void)
return spiram_inited;
}
uint8_t esp_spiram_get_cs_io(void)
{
return psram_get_cs_io();
}
#endif

View File

@ -195,6 +195,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;
@ -839,6 +846,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) {

View File

@ -63,6 +63,13 @@ 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);
#ifdef __cplusplus
}
#endif

View File

@ -377,6 +377,11 @@ bool esp_spiram_is_initialized(void)
return spiram_inited;
}
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
@ -415,4 +420,5 @@ bool esp_spiram_test(void)
return true;
}
}
#endif

View File

@ -160,6 +160,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) {
@ -367,6 +374,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)

View File

@ -68,5 +68,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

View File

@ -38,7 +38,7 @@
#define OCT_PSRAM_ADDR_BITLEN 32
#define OCT_PSRAM_RD_DUMMY_BITLEN (2*(10-1))
#define OCT_PSRAM_WR_DUMMY_BITLEN (2*(5-1))
#define OCT_PSRAM_CS1_IO 26
#define OCT_PSRAM_CS1_IO CONFIG_DEFAULT_PSRAM_CS_IO
#define OCT_PSRAM_CS_SETUP_TIME 3
#define OCT_PSRAM_CS_HOLD_TIME 3
@ -102,6 +102,11 @@ static const char* TAG = "opi psram";
static DRAM_ATTR psram_size_t s_psram_size;
static void IRAM_ATTR s_config_psram_spi_phases(void);
uint8_t IRAM_ATTR psram_get_cs_io(void)
{
return OCT_PSRAM_CS1_IO;
}
/**
* Initialise mode registers of the PSRAM
*/
@ -224,7 +229,7 @@ static void IRAM_ATTR s_init_psram_pins(void)
//Set cs1 pin function
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], FUNC_SPICS1_SPICS1);
//Set mspi cs1 drive strength
PIN_SET_DRV(IO_MUX_GPIO26_REG, 3);
PIN_SET_DRV(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], 3);
//Set psram clock pin drive strength
REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3);
}

View File

@ -329,4 +329,9 @@ bool esp_spiram_is_initialized(void)
return s_spiram_inited;
}
uint8_t esp_spiram_get_cs_io(void)
{
return psram_get_cs_io();
}
#endif

View File

@ -121,6 +121,13 @@ static uint32_t s_psram_id = 0;
static void IRAM_ATTR config_psram_spi_phases(void);
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) {
@ -301,6 +308,7 @@ static void IRAM_ATTR psram_gpio_config(void)
esp_rom_gpio_connect_out_signal(cs1_io, SPICS1_OUT_IDX, 0, 0);
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cs1_io], PIN_FUNC_GPIO);
}
s_psram_cs_io = cs1_io;
//WP HD
uint8_t wp_io = PSRAM_SPIWP_SD3_IO;

View File

@ -68,5 +68,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

View File

@ -19,6 +19,15 @@
#include "driver/gpio.h"
#include "esp_private/gpio.h"
#include "esp_private/sleep_gpio.h"
#include "bootloader_common.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#include "esp32/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/spiram.h"
#endif
static const char *TAG = "sleep";
@ -53,6 +62,12 @@ void esp_sleep_config_gpio_isolate(void)
gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING);
}
}
#if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM
gpio_sleep_set_pull_mode(esp_spiram_get_cs_io(), GPIO_PULLUP_ONLY);
#endif
#if CONFIG_ESP_SLEEP_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)