feat(psram): config SPI psram pins based on efuse value

This commit is contained in:
chenjianqiang 2019-05-07 16:36:37 +08:00
parent e4418f4f92
commit 55f5c2e08d
5 changed files with 233 additions and 150 deletions

View file

@ -136,3 +136,8 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
* - ESP_FAIL: mapping is fail.
*/
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
/**
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
*/
void bootloader_common_vddsdio_configure();

View file

@ -27,6 +27,8 @@
#include "bootloader_flash.h"
#include "bootloader_common.h"
#include "soc/gpio_periph.h"
#include "soc/efuse_reg.h"
#include "soc/rtc.h"
#include "esp_image_format.h"
#include "bootloader_sha.h"
#include "sys/param.h"
@ -257,3 +259,18 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
return ESP_OK;
}
void bootloader_common_vddsdio_configure()
{
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // 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 // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}

View file

@ -48,6 +48,7 @@
#include "bootloader_random.h"
#include "bootloader_config.h"
#include "bootloader_clock.h"
#include "bootloader_common.h"
#include "flash_qio_mode.h"
@ -61,7 +62,6 @@ static const char* TAG = "boot";
static esp_err_t bootloader_main();
static void print_flash_info(const esp_image_header_t* pfhdr);
static void update_flash_config(const esp_image_header_t* pfhdr);
static void vddsdio_configure();
static void flash_gpio_configure(const esp_image_header_t* pfhdr);
static void uart_console_configure(void);
static void wdt_reset_check(void);
@ -117,7 +117,7 @@ esp_err_t bootloader_init()
static esp_err_t bootloader_main()
{
vddsdio_configure();
bootloader_common_vddsdio_configure();
/* Read and keep flash ID, for further use. */
g_rom_flashchip.device_id = bootloader_read_flash_id();
esp_image_header_t fhdr;
@ -285,21 +285,6 @@ static void print_flash_info(const esp_image_header_t* phdr)
#endif
}
static void vddsdio_configure()
{
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // 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 // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}
#define FLASH_CLK_IO 6
#define FLASH_CS_IO 11
#define FLASH_SPIQ_IO 7

View file

@ -239,16 +239,84 @@ menu "ESP32-specific"
bool "VSPI host (SPI3)"
endchoice
config PICO_PSRAM_CS_IO
int "PSRAM CS IO for ESP32-PICO chip"
depends on SPIRAM_SUPPORT
range 0 33
default 10
help
When ESP32-PICO chip connect a external psram, the clock IO and data IO is fixed, but the CS IO can be
any unused GPIO, user can config it based on hardware design.
menu "PSRAM clock and cs IO for ESP32-DOWD"
endmenu
config D0WD_PSRAM_CLK_IO
int "PSRAM CLK IO number"
depends on SPIRAM_SUPPORT
range 0 33
default 17
help
The PSRAM CLOCK IO can be any unused GPIO, user can config it based on hardware design. If user use
1.8V flash and 1.8V psram, this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
config D0WD_PSRAM_CS_IO
int "PSRAM CS IO number"
depends on SPIRAM_SUPPORT
range 0 33
default 16
help
The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design. If user use
1.8V flash and 1.8V psram, this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
endmenu
menu "PSRAM clock and cs IO for ESP32-D2WD"
config D2WD_PSRAM_CLK_IO
int "PSRAM CLK IO number"
depends on SPIRAM_SUPPORT
range 0 33
default 9
help
User can config it based on hardware design. For ESP32-D2WD chip, the psram can only be 1.8V psram,
so this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
config D2WD_PSRAM_CS_IO
int "PSRAM CS IO number"
depends on SPIRAM_SUPPORT
range 0 33
default 10
help
User can config it based on hardware design. For ESP32-D2WD chip, the psram can only be 1.8V psram,
so this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
endmenu
menu "PSRAM clock and cs IO for ESP32-PICO"
config PICO_PSRAM_CS_IO
int "PSRAM CS IO number"
depends on SPIRAM_SUPPORT
range 0 33
default 10
help
The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design.
For ESP32-PICO chip, the psram share clock with flash, so user do not need to configure the clock
IO.
For the reference hardware design, please refer to
https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf
endmenu
config SPIRAM_SPIWP_SD3_PIN
int "SPI PSRAM WP(SD3) Pin when customising pins via eFuse (read help)"
depends on ESPTOOLPY_FLASHMODE_DIO || ESPTOOLPY_FLASHMODE_DOUT
range 0 33
default 7
help
This value is ignored unless flash mode is set to DIO or DOUT and the SPI flash pins have been
overriden by setting the eFuses SPI_PAD_CONFIG_xxx.
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. And the psram only has QPI
mode, the WP pin is necessary, so we need to configure this value here.
When flash mode is set to QIO or QOUT, the PSRAM WP pin will be set as the value configured in
bootloader.
For ESP32-PICO chip, the default value of this config should be 7.
endmenu # "SPI RAM config"
config MEMMAP_TRACEMEM
bool

View file

@ -28,6 +28,7 @@
#include "rom/spi_flash.h"
#include "rom/gpio.h"
#include "rom/cache.h"
#include "rom/efuse.h"
#include "soc/io_mux_reg.h"
#include "soc/dport_reg.h"
#include "soc/gpio_sig_map.h"
@ -35,6 +36,7 @@
#include "driver/gpio.h"
#include "driver/spi_common.h"
#include "driver/periph_ctrl.h"
#include "bootloader_common.h"
#if CONFIG_SPIRAM_SUPPORT
#include "soc/rtc.h"
@ -94,43 +96,36 @@ typedef enum {
// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
// hardcode the flash pins as well, making this code incompatible with either a setup
// that has the flash on non-standard pins or ESP32s with built-in flash.
#define FLASH_CLK_IO 6
#define FLASH_CLK_IO 6
#define FLASH_CS_IO 11
#define FLASH_SPIQ_SD0_IO 7
#define FLASH_SPID_SD1_IO 8
#define FLASH_SPIWP_SD3_IO 10
#define FLASH_SPIHD_SD2_IO 9
#define PSRAM_CLK_IO 17
#define PSRAM_CS_IO 16
#define PSRAM_SPIQ_SD0_IO 7
#define PSRAM_SPID_SD1_IO 8
#define PSRAM_SPIQ_SD0_IO 7
#define PSRAM_SPID_SD1_IO 8
#define PSRAM_SPIWP_SD3_IO 10
#define PSRAM_SPIHD_SD2_IO 9
#define PSRAM_SPIHD_SD2_IO 9
// IO-pins of ESP32-PICO-D4 for PSRAM. PSRAM share clock with flash.
// The CS IO can be overwrite via menuconfig.
#define PICO_FLASH_CLK_IO 6
#define PICO_FLASH_CS_IO 16
#define PICO_FLASH_SPIQ_SD0_IO 17
#define PICO_FLASH_SPID_SD1_IO 8
#define PICO_FLASH_SPIWP_SD3_IO 7
#define PICO_FLASH_SPIHD_SD2_IO 11
#define FLASH_HSPI_CLK_IO 14
#define FLASH_HSPI_CS_IO 15
#define PSRAM_HSPI_SPIQ_SD0_IO 12
#define PSRAM_HSPI_SPID_SD1_IO 13
#define PSRAM_HSPI_SPIWP_SD3_IO 2
#define PSRAM_HSPI_SPIHD_SD2_IO 4
#define PICO_PSRAM_CLK_IO 6
#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO
#define PICO_PSRAM_SPIQ_SD0_IO 17
#define PICO_PSRAM_SPID_SD1_IO 8
#define PICO_PSRAM_SPIWP_SD3_IO 7
#define PICO_PSRAM_SPIHD_SD2_IO 11
// PSRAM clock and cs IO should be configured based on hardware design.
// For ESP32-WROVER or ESP32-WROVER-B module, the clock IO is IO17, the cs IO is IO16,
// they are the default value for these two configs.
#define D0WD_PSRAM_CLK_IO CONFIG_D0WD_PSRAM_CLK_IO // Default value is 17
#define D0WD_PSRAM_CS_IO CONFIG_D0WD_PSRAM_CS_IO // Default value is 16
#define D2WD_PSRAM_CLK_IO CONFIG_D2WD_PSRAM_CLK_IO // Default value is 9
#define D2WD_PSRAM_CS_IO CONFIG_D2WD_PSRAM_CS_IO // Default value is 10
// For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6.
#define PICO_PSRAM_CLK_IO 6
#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10
typedef struct {
uint8_t flash_clk_io;
uint8_t flash_cs_io;
uint8_t flash_spiq_sd0_io;
uint8_t flash_spid_sd1_io;
uint8_t flash_spiwp_sd3_io;
uint8_t flash_spihd_sd2_io;
uint8_t psram_clk_io;
uint8_t psram_cs_io;
uint8_t psram_spiq_sd0_io;
@ -491,7 +486,6 @@ void psram_set_cs_timing(psram_spi_num_t spi_num, psram_clk_mode_t clk_mode)
void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode)
{
CLEAR_PERI_REG_MASK(SPI_SLAVE_REG(spi_num), SPI_TRANS_DONE << 5);
SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CS_SETUP);
// SPI_CPOL & SPI_CPHA
CLEAR_PERI_REG_MASK(SPI_PIN_REG(spi_num), SPI_CK_IDLE_EDGE);
CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CK_OUT_EDGE);
@ -508,11 +502,8 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode)
psram_set_cs_timing(spi_num, s_clk_mode);
}
/*
* 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_io_t psram_io, psram_cache_mode_t mode)
//psram gpio init , different working frequency we have different solutions
static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_mode_t mode)
{
int spi_cache_dummy = 0;
uint32_t rd_mode_reg = READ_PERI_REG(SPI_CTRL_REG(0));
@ -523,17 +514,6 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t
} 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(psram_io.flash_cs_io, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io.psram_spiq_sd0_io, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spiq_sd0_io, SPIQ_IN_IDX, 0);
gpio_matrix_out(psram_io.psram_spid_sd1_io, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spid_sd1_io, SPID_IN_IDX, 0);
gpio_matrix_out(psram_io.psram_spiwp_sd3_io, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spiwp_sd3_io, SPIWP_IN_IDX, 0);
gpio_matrix_out(psram_io.psram_spihd_sd2_io, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spihd_sd2_io, SPIHD_IN_IDX, 0);
switch (mode) {
case PSRAM_CACHE_F80M_S40M:
@ -544,8 +524,8 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t
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(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
break;
case PSRAM_CACHE_F80M_S80M:
extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M;
@ -555,8 +535,8 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t
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(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 3, FUN_DRV_S);
break;
case PSRAM_CACHE_F40M_S40M:
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
@ -566,36 +546,54 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t
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(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
break;
default:
break;
}
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy en
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy enable
// In bootloader, all the signals are already configured,
// We keep the following code in case the bootloader is some older version.
gpio_matrix_out(psram_io->flash_cs_io, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io->psram_cs_io, SPICS1_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io->psram_spiq_sd0_io, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io->psram_spiq_sd0_io, SPIQ_IN_IDX, 0);
gpio_matrix_out(psram_io->psram_spid_sd1_io, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io->psram_spid_sd1_io, SPID_IN_IDX, 0);
gpio_matrix_out(psram_io->psram_spiwp_sd3_io, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io->psram_spiwp_sd3_io, SPIWP_IN_IDX, 0);
gpio_matrix_out(psram_io->psram_spihd_sd2_io, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io->psram_spihd_sd2_io, SPIHD_IN_IDX, 0);
//select pin function gpio
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spiq_sd0_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spid_sd1_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spihd_sd2_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spiwp_sd3_io], PIN_FUNC_GPIO);
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUNC_SD_CLK_SPICLK);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_cs_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_cs_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], PIN_FUNC_GPIO);
if ((psram_io->flash_clk_io == FLASH_CLK_IO) && (psram_io->flash_clk_io != psram_io->psram_clk_io)) {
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUNC_SD_CLK_SPICLK);
} else {
//flash clock signal should come from GPIO matrix.
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], PIN_FUNC_GPIO);
}
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_cs_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_cs_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spiq_sd0_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spid_sd1_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spihd_sd2_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->psram_spiwp_sd3_io], PIN_FUNC_GPIO);
uint32_t flash_id = g_rom_flashchip.device_id;
if (flash_id == FLASH_ID_GD25LQ32C) {
// Set drive ability for 1.8v flash in 80Mhz.
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spiq_sd0_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spid_sd1_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spihd_sd2_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spiwp_sd3_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spiq_sd0_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spid_sd1_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spihd_sd2_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spiwp_sd3_io], FUN_DRV_V, 3, FUN_DRV_S);
}
}
@ -612,15 +610,24 @@ psram_size_t psram_get_size()
}
}
//psram gpio init , different working frequency we have different solutions
/*
* 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.
*/
esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init
{
psram_io_t psram_io;
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_ver = chip_ver & 0x7;
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
ESP_EARLY_LOGE(TAG, "ESP32D2WD do not support psram yet");
return ESP_FAIL;
ESP_EARLY_LOGI(TAG, "This chip is ESP32-D2WD");
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
if (cfg.tieh != RTC_VDDSDIO_TIEH_1_8V) {
ESP_EARLY_LOGE(TAG, "VDDSDIO is not 1.8V");
return ESP_FAIL;
}
psram_io.psram_clk_io = D2WD_PSRAM_CLK_IO;
psram_io.psram_cs_io = D2WD_PSRAM_CS_IO;
} else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) {
ESP_EARLY_LOGI(TAG, "This chip is ESP32-PICO");
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
@ -628,36 +635,46 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V");
return ESP_FAIL;
}
psram_io.flash_clk_io = PICO_FLASH_CLK_IO;
psram_io.flash_cs_io = PICO_FLASH_CS_IO;
psram_io.flash_spiq_sd0_io = PICO_FLASH_SPIQ_SD0_IO;
psram_io.flash_spid_sd1_io = PICO_FLASH_SPID_SD1_IO;
psram_io.flash_spiwp_sd3_io = PICO_FLASH_SPIWP_SD3_IO;
psram_io.flash_spihd_sd2_io = PICO_FLASH_SPIHD_SD2_IO;
psram_io.psram_clk_io = PICO_PSRAM_CLK_IO;
psram_io.psram_cs_io = PICO_PSRAM_CS_IO;
psram_io.psram_spiq_sd0_io = PICO_PSRAM_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PICO_PSRAM_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PICO_PSRAM_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PICO_PSRAM_SPIHD_SD2_IO;
s_clk_mode = PSRAM_CLK_MODE_NORM;
} else {
psram_io.psram_clk_io = PICO_PSRAM_CLK_IO;
psram_io.psram_cs_io = PICO_PSRAM_CS_IO;
} else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5)){
ESP_EARLY_LOGI(TAG, "This chip is ESP32-D0WD");
psram_io.psram_clk_io = D0WD_PSRAM_CLK_IO;
psram_io.psram_cs_io = D0WD_PSRAM_CS_IO;
}
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
psram_io.flash_clk_io = FLASH_CLK_IO;
psram_io.flash_cs_io = FLASH_CS_IO;
psram_io.flash_spiq_sd0_io = FLASH_SPIQ_SD0_IO;
psram_io.flash_spid_sd1_io = FLASH_SPID_SD1_IO;
psram_io.flash_spiwp_sd3_io = FLASH_SPIWP_SD3_IO;
psram_io.flash_spihd_sd2_io = FLASH_SPIHD_SD2_IO;
psram_io.psram_clk_io = PSRAM_CLK_IO;
psram_io.psram_cs_io = PSRAM_CS_IO;
psram_io.psram_spiq_sd0_io = PSRAM_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PSRAM_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PSRAM_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PSRAM_SPIHD_SD2_IO;
} else if (spiconfig == EFUSE_SPICONFIG_HSPI_DEFAULTS) {
psram_io.flash_clk_io = FLASH_HSPI_CLK_IO;
psram_io.flash_cs_io = FLASH_HSPI_CS_IO;
psram_io.psram_spiq_sd0_io = PSRAM_HSPI_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PSRAM_HSPI_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PSRAM_HSPI_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PSRAM_HSPI_SPIHD_SD2_IO;
} else {
psram_io.flash_clk_io = EFUSE_SPICONFIG_RET_SPICLK(spiconfig);
psram_io.flash_cs_io = EFUSE_SPICONFIG_RET_SPICS0(spiconfig);
psram_io.psram_spiq_sd0_io = EFUSE_SPICONFIG_RET_SPIQ(spiconfig);
psram_io.psram_spid_sd1_io = EFUSE_SPICONFIG_RET_SPID(spiconfig);
psram_io.psram_spihd_sd2_io = EFUSE_SPICONFIG_RET_SPIHD(spiconfig);
// If flash mode is set to QIO or QOUT, the WP pin is equal the value configured in bootloader.
// If flash mode is set to DIO or DOUT, the WP pin should config it via menuconfig.
#if CONFIG_FLASHMODE_QIO || CONFIG_FLASHMODE_QOUT
psram_io.psram_spiwp_sd3_io = CONFIG_BOOTLOADER_SPI_WP_PIN;
#else
psram_io.psram_spiwp_sd3_io = CONFIG_SPIRAM_SPIWP_SD3_PIN;
#endif
}
WRITE_PERI_REG(GPIO_ENABLE_W1TC_REG, BIT(psram_io.psram_clk_io) | BIT(psram_io.psram_cs_io)); //DISABLE OUPUT FOR IO16/17
assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
s_psram_mode = mode;
@ -666,7 +683,6 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
psram_spi_init(PSRAM_SPI_1, mode);
gpio_matrix_out(psram_io.psram_cs_io, SPICS1_OUT_IDX, 0, 0);
switch (mode) {
case PSRAM_CACHE_F80M_S80M:
gpio_matrix_out(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
@ -691,25 +707,16 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
}
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 == RTC_VDDSDIO_TIEH_1_8V) { // 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
// Rise VDDSIO for 1.8V psram.
bootloader_common_vddsdio_configure();
// GPIO related settings
psram_gpio_config(psram_io, mode);
psram_gpio_config(&psram_io, mode);
psram_read_id(&s_psram_id);
if (!PSRAM_IS_VALID(s_psram_id)) {
return ESP_FAIL;
}
if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
s_clk_mode = PSRAM_CLK_MODE_DCLK;
if (mode == PSRAM_CACHE_F80M_S80M) {
@ -776,42 +783,43 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra
CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div
break;
}
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_WCMD_M); // cache write command enable
SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_ADDR_BITLEN_V, 23, SPI_SRAM_ADDR_BITLEN_S); //write address for cache command.
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_QIO_M); //enable qio mode for cache command
CLEAR_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_DIO_M); //disable dio mode for cache command
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable user mode for cache read command
CLEAR_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_DIO_M); //disable dio mode for cache command
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_QIO_M); //enable qio mode for cache command
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable cache read command
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_WCMD_M); //enable cache write command
SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_ADDR_BITLEN_V, 23, SPI_SRAM_ADDR_BITLEN_S); //write address for cache command.
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
//config sram cache r/w command
SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S);
SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD,
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB
SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 7,
SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S);
SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, PSRAM_QUAD_WRITE,
SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38
SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S);
SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD,
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b
SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy; 80m--+2dummy
//config sram cache r/w command
switch (psram_cache_mode) {
case PSRAM_CACHE_F80M_S80M: //in this mode , no delay is needed
break;
case PSRAM_CACHE_F80M_S40M: //is sram is @40M, need 2 cycles of delay
case PSRAM_CACHE_F80M_S40M: //if sram is @40M, need 2 cycles of delay
case PSRAM_CACHE_F40M_S40M:
default:
if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 15,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); //read command length, 2 bytes(1byte for delay),sending in qio mode in cache
SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, ((PSRAM_FAST_READ_QUAD) << 8),
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b, read command value,(0x00 for delay,0x0b for cmd)
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB, read command value,(0x00 for delay,0xeb for cmd)
SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 15,
SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S); //write command length,2 bytes(1byte for delay,send in qio mode in cache)
SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, ((PSRAM_QUAD_WRITE) << 8),
SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38, write command value,(0x00 for delay)
SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy; 80m--+2dummy
}
break;
}