forked from espressif/esp-idf
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:
@@ -119,6 +119,15 @@ bool bootloader_common_label_search(const char *list, char *label);
|
|||||||
*/
|
*/
|
||||||
void bootloader_configure_spi_pins(int drv);
|
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.
|
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
|
||||||
*
|
*
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "esp_rom_crc.h"
|
#include "esp_rom_crc.h"
|
||||||
#include "esp_rom_gpio.h"
|
#include "esp_rom_gpio.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
#include "esp_rom_efuse.h"
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
#include "bootloader_flash_priv.h"
|
#include "bootloader_flash_priv.h"
|
||||||
#include "bootloader_common.h"
|
#include "bootloader_common.h"
|
||||||
@@ -191,8 +192,19 @@ void bootloader_common_vddsdio_configure(void)
|
|||||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
|
RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
|
||||||
{
|
{
|
||||||
return (RESET_REASON)esp_rom_get_reset_reason(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;
|
||||||
|
}
|
||||||
|
@@ -33,5 +33,22 @@ menu "Hardware Settings"
|
|||||||
config ESP_SLEEP_RTC_BUS_ISO_WORKAROUND
|
config ESP_SLEEP_RTC_BUS_ISO_WORKAROUND
|
||||||
bool
|
bool
|
||||||
default y if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
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
|
||||||
endmenu
|
endmenu
|
||||||
|
@@ -85,6 +85,15 @@ size_t esp_spiram_get_size(void);
|
|||||||
*/
|
*/
|
||||||
void esp_spiram_writeback_cache(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);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -70,6 +70,15 @@ size_t esp_spiram_get_size(void);
|
|||||||
*/
|
*/
|
||||||
void esp_spiram_writeback_cache(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);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -79,6 +79,16 @@ void esp_spiram_writeback_cache(void);
|
|||||||
*/
|
*/
|
||||||
bool esp_spiram_is_initialized(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
|
* @brief Reserve a pool of internal memory for specific DMA/internal allocations
|
||||||
*
|
*
|
||||||
|
@@ -316,4 +316,8 @@ bool esp_spiram_is_initialized(void)
|
|||||||
return spiram_inited;
|
return spiram_inited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t esp_spiram_get_cs_io(void)
|
||||||
|
{
|
||||||
|
return psram_get_cs_io();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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 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)
|
static void psram_clear_spi_fifo(psram_spi_num_t spi_num)
|
||||||
{
|
{
|
||||||
int i;
|
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);
|
ESP_EARLY_LOGE(TAG, "Not a valid or known package id: %d", pkg_ver);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
s_psram_cs_io = psram_io.psram_cs_io;
|
||||||
|
|
||||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||||
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
|
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -377,6 +377,11 @@ bool esp_spiram_is_initialized(void)
|
|||||||
return spiram_inited;
|
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
|
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
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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);
|
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)
|
static void psram_set_op_mode(int spi_num, psram_cmd_mode_t mode)
|
||||||
{
|
{
|
||||||
if (mode == PSRAM_CMD_QPI) {
|
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();
|
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);
|
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)
|
psram_size_t psram_get_size(void)
|
||||||
|
@@ -68,5 +68,11 @@ typedef enum {
|
|||||||
|
|
||||||
esp_err_t esp_spiram_wrap_set(spiram_wrap_mode_t mode);
|
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
|
#endif
|
||||||
|
@@ -38,7 +38,7 @@
|
|||||||
#define OCT_PSRAM_ADDR_BITLEN 32
|
#define OCT_PSRAM_ADDR_BITLEN 32
|
||||||
#define OCT_PSRAM_RD_DUMMY_BITLEN (2*(10-1))
|
#define OCT_PSRAM_RD_DUMMY_BITLEN (2*(10-1))
|
||||||
#define OCT_PSRAM_WR_DUMMY_BITLEN (2*(5-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_SETUP_TIME 3
|
||||||
#define OCT_PSRAM_CS_HOLD_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 DRAM_ATTR psram_size_t s_psram_size;
|
||||||
static void IRAM_ATTR s_config_psram_spi_phases(void);
|
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
|
* Initialise mode registers of the PSRAM
|
||||||
*/
|
*/
|
||||||
@@ -224,7 +229,7 @@ static void IRAM_ATTR s_init_psram_pins(void)
|
|||||||
//Set cs1 pin function
|
//Set cs1 pin function
|
||||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], FUNC_SPICS1_SPICS1);
|
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], FUNC_SPICS1_SPICS1);
|
||||||
//Set mspi cs1 drive strength
|
//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
|
//Set psram clock pin drive strength
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@@ -329,4 +329,9 @@ bool esp_spiram_is_initialized(void)
|
|||||||
return s_spiram_inited;
|
return s_spiram_inited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t esp_spiram_get_cs_io(void)
|
||||||
|
{
|
||||||
|
return psram_get_cs_io();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -121,6 +121,13 @@ static uint32_t s_psram_id = 0;
|
|||||||
static void IRAM_ATTR config_psram_spi_phases(void);
|
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);
|
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)
|
static void psram_set_op_mode(int spi_num, psram_cmd_mode_t mode)
|
||||||
{
|
{
|
||||||
if (mode == PSRAM_CMD_QPI) {
|
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);
|
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);
|
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cs1_io], PIN_FUNC_GPIO);
|
||||||
}
|
}
|
||||||
|
s_psram_cs_io = cs1_io;
|
||||||
|
|
||||||
//WP HD
|
//WP HD
|
||||||
uint8_t wp_io = PSRAM_SPIWP_SD3_IO;
|
uint8_t wp_io = PSRAM_SPIWP_SD3_IO;
|
||||||
|
@@ -68,5 +68,11 @@ typedef enum {
|
|||||||
|
|
||||||
esp_err_t esp_spiram_wrap_set(spiram_wrap_mode_t mode);
|
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
|
#endif
|
||||||
|
@@ -19,6 +19,15 @@
|
|||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_private/gpio.h"
|
#include "esp_private/gpio.h"
|
||||||
#include "esp_private/sleep_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";
|
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);
|
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)
|
void esp_sleep_enable_gpio_switch(bool enable)
|
||||||
|
Reference in New Issue
Block a user