mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-03 00:21:44 +01:00
feature(psram): configure flash and psram speed during runtime
1. Bootloader reads SPI configuration from bin header, so that the burning configuration can be different with compiling configuration. 2. Psram mode init will overwrite original flash speed mode, so that users can change psram and flash speed after OTA. 3. Flash read mode(QIO/DIO…) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode. 4. Add read flash ID function, and save flash ID in g_rom_flashchip 5. Set drive ability for all related GPIOs 6. Check raise VDDSDIO voltage in 80Mhz mode 7. Add check flash ID and update settings in bootloader 8. Read flash ID once and keep in global variable 9. Read flash image header once and reuse the result Tested cases: 1. Test new and old version of bootloader boot Flash 20M —> app Flash 80M + Psram 80M boot Flash 40M —> app Flash 80M + Psram 80M boot Flash 80M —> app Flash 80M + Psram 80M boot Flash 20M —> app Flash 80M + Psram 40M boot Flash 40M —> app Flash 80M + Psram 40M boot Flash 80M —> app Flash 80M + Psram 40M boot Flash 20M —> app Flash 40M + Psram 40M boot Flash 40M —> app Flash 40M + Psram 40M boot Flash 80M —> app Flash 40M + Psram 40M 2. Working after esp_restart reboot.
This commit is contained in:
@@ -117,6 +117,8 @@ extern "C" {
|
||||
#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2)
|
||||
#define ESP_ROM_SPIFLASH_QE BIT9
|
||||
|
||||
#define FLASH_ID_GD25LQ32C 0xC86016
|
||||
|
||||
typedef enum {
|
||||
ESP_ROM_SPIFLASH_QIO_MODE = 0,
|
||||
ESP_ROM_SPIFLASH_QOUT_MODE,
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
#if CONFIG_SPIRAM_SUPPORT
|
||||
#include "soc/rtc.h"
|
||||
|
||||
//Commands for PSRAM chip
|
||||
#define PSRAM_READ 0x03
|
||||
@@ -79,15 +80,10 @@
|
||||
#define PSRAM_IO_MATRIX_DUMMY_40M 1
|
||||
#define PSRAM_IO_MATRIX_DUMMY_80M 2
|
||||
|
||||
#if CONFIG_FLASHMODE_QIO
|
||||
#define SPI_CACHE_DUMMY SPI0_R_QIO_DUMMY_CYCLELEN //qio 3
|
||||
#elif CONFIG_FLASHMODE_QOUT
|
||||
#define SPI_CACHE_DUMMY SPI0_R_FAST_DUMMY_CYCLELEN //qout 7
|
||||
#elif CONFIG_FLASHMODE_DIO
|
||||
#define SPI_CACHE_DUMMY SPI0_R_DIO_DUMMY_CYCLELEN //dio 3
|
||||
#elif CONFIG_FLASHMODE_DOUT
|
||||
#define SPI_CACHE_DUMMY SPI0_R_FAST_DUMMY_CYCLELEN //dout 7
|
||||
#endif
|
||||
#define _SPI_CACHE_PORT 0
|
||||
#define _SPI_FLASH_PORT 1
|
||||
#define _SPI_80M_CLK_DIV 1
|
||||
#define _SPI_40M_CLK_DIV 2
|
||||
|
||||
static const char* TAG = "psram";
|
||||
typedef enum {
|
||||
@@ -101,9 +97,7 @@ static psram_cache_mode_t s_psram_mode = PSRAM_CACHE_MAX;
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
|
||||
static int extra_dummy = 0;
|
||||
|
||||
typedef enum {
|
||||
PSRAM_CMD_QPI,
|
||||
PSRAM_CMD_SPI,
|
||||
@@ -421,8 +415,23 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode)
|
||||
memset((void*)SPI_W0_REG(spi_num), 0, 16 * 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA.
|
||||
* Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode.
|
||||
*/
|
||||
static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
|
||||
{
|
||||
int spi_cache_dummy = 0;
|
||||
uint32_t rd_mode_reg = READ_PERI_REG(SPI_CTRL_REG(0));
|
||||
if (rd_mode_reg & (SPI_FREAD_QIO_M | SPI_FREAD_DIO_M)) {
|
||||
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
|
||||
} else if (rd_mode_reg & (SPI_FREAD_QUAD_M | SPI_FREAD_DUAL_M)) {
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
} else {
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
}
|
||||
// In bootloader, all the signals are already configured,
|
||||
// We keep the following code in case the bootloader is some older version.
|
||||
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(PSRAM_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(PSRAM_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||
@@ -436,24 +445,33 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
|
||||
switch (mode) {
|
||||
case PSRAM_CACHE_F80M_S40M:
|
||||
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M;
|
||||
g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(_SPI_CACHE_PORT), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
|
||||
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
|
||||
//set drive ability for clock
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
|
||||
break;
|
||||
case PSRAM_CACHE_F80M_S80M:
|
||||
extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_80M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M;
|
||||
g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_80M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(_SPI_CACHE_PORT), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
|
||||
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_FLASH_PORT);
|
||||
//set drive ability for clock
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
|
||||
break;
|
||||
case PSRAM_CACHE_F40M_S40M:
|
||||
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(_SPI_CACHE_PORT), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT);
|
||||
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
|
||||
//set drive ability for clock
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 2, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
|
||||
@@ -549,11 +567,38 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
|
||||
gpio_matrix_out(PSRAM_CLK_IO, SIG_IN_FUNC225_IDX, 0, 0);
|
||||
break;
|
||||
}
|
||||
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
// For flash 80Mhz, we must update ldo voltage in case older version of bootloader didn't do this.
|
||||
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||
if (cfg.enable == 1 && cfg.tieh == 0) { // VDDSDIO regulator is enabled @ 1.8V
|
||||
cfg.drefh = 3;
|
||||
cfg.drefm = 3;
|
||||
cfg.drefl = 3;
|
||||
cfg.force = 1;
|
||||
rtc_vddsdio_set_config(cfg);
|
||||
ets_delay_us(10); // wait for regulator to become stable
|
||||
}
|
||||
#endif
|
||||
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_SETUP_M);
|
||||
psram_gpio_config(mode);
|
||||
WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, BIT(PSRAM_CS_IO)| BIT(PSRAM_CLK_IO));
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], PIN_FUNC_GPIO);
|
||||
|
||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32
|
||||
// Set drive ability for 1.8v flash in 80Mhz.
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CS_IO], FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
|
||||
#endif
|
||||
}
|
||||
uint32_t id;
|
||||
psram_read_id(&id);
|
||||
if (((id >> PSRAM_MFG_ID_S) & PSRAM_MFG_ID_M) != PSRAM_MFG_ID_V) {
|
||||
|
||||
Reference in New Issue
Block a user