From b1dcb52fec4d427cc831240d675e6804d9aebc6f Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Fri, 20 Apr 2018 16:59:25 +0800 Subject: [PATCH] feature(psram): configure flash and psram speed during runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../include_priv/flash_qio_mode.h | 8 ++ .../bootloader_support/src/bootloader_init.c | 89 +++++++++++++------ .../bootloader_support/src/flash_qio_mode.c | 24 +++-- components/esp32/include/rom/spi_flash.h | 2 + components/esp32/spiram_psram.c | 79 ++++++++++++---- 5 files changed, 148 insertions(+), 54 deletions(-) diff --git a/components/bootloader_support/include_priv/flash_qio_mode.h b/components/bootloader_support/include_priv/flash_qio_mode.h index 9efa1313e..98e2fd22a 100644 --- a/components/bootloader_support/include_priv/flash_qio_mode.h +++ b/components/bootloader_support/include_priv/flash_qio_mode.h @@ -24,6 +24,14 @@ extern "C" { */ void bootloader_enable_qio_mode(void); +/** + * @brief Read flash ID by sending 0x9F command + * @return flash raw ID + * mfg_id = (ID >> 16) & 0xFF; + flash_id = ID & 0xffff; + */ +uint32_t bootloader_read_flash_id(); + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index bed022397..5a1ecd6ab 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -63,7 +63,7 @@ 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(); +static void flash_gpio_configure(const esp_image_header_t* pfhdr); static void uart_console_configure(void); static void wdt_reset_check(void); @@ -118,7 +118,14 @@ esp_err_t bootloader_init() static esp_err_t bootloader_main() { vddsdio_configure(); - flash_gpio_configure(); + /* Read and keep flash ID, for further use. */ + g_rom_flashchip.device_id = bootloader_read_flash_id(); + esp_image_header_t fhdr; + if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &fhdr, sizeof(esp_image_header_t), true) != ESP_OK) { + ESP_LOGE(TAG, "failed to load bootloader header!"); + return ESP_FAIL; + } + flash_gpio_configure(&fhdr); #if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240) //Check if ESP32 is rated for a CPU frequency of 160MHz only if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) && @@ -132,8 +139,6 @@ static esp_err_t bootloader_main() wdt_reset_check(); ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER); - esp_image_header_t fhdr; - ESP_LOGI(TAG, "compile time " __TIME__ ); ets_set_appcpu_boot_addr(0); @@ -158,11 +163,6 @@ static esp_err_t bootloader_main() bootloader_enable_qio_mode(); #endif - if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &fhdr, sizeof(esp_image_header_t), true) != ESP_OK) { - ESP_LOGE(TAG, "failed to load bootloader header!"); - return ESP_FAIL; - } - print_flash_info(&fhdr); update_flash_config(&fhdr); @@ -295,31 +295,49 @@ static void vddsdio_configure() #define FLASH_SPIHD_IO 9 #define FLASH_IO_MATRIX_DUMMY_40M 1 #define FLASH_IO_MATRIX_DUMMY_80M 2 -static void IRAM_ATTR flash_gpio_configure() +#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3 + +/* + * Bootloader reads SPI configuration from bin header, so that + * the burning configuration can be different with compiling configuration. + */ +static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr) { int spi_cache_dummy = 0; int drv = 2; -#if CONFIG_FLASHMODE_QIO - spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN; //qio 3 -#elif CONFIG_FLASHMODE_QOUT - spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; //qout 7 -#elif CONFIG_FLASHMODE_DIO - spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //dio 3 -#elif CONFIG_FLASHMODE_DOUT - spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; //dout 7 -#endif + switch (pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; + break; + case ESP_IMAGE_SPI_MODE_DIO: + spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3 + break; + case ESP_IMAGE_SPI_MODE_QOUT: + case ESP_IMAGE_SPI_MODE_DOUT: + default: + spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; + break; + } + /* dummy_len_plus values defined in ROM for SPI flash configuration */ extern uint8_t g_rom_spiflash_dummy_len_plus[]; -#if CONFIG_ESPTOOLPY_FLASHFREQ_40M - g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M; - g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M; - SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY -#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M - g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M; - g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M; - SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY - drv = 3; -#endif + switch (pfhdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_80M: + g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M; + g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M; + SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M, + SPI_USR_DUMMY_CYCLELEN_S); //DUMMY + drv = 3; + break; + case ESP_IMAGE_SPI_SPEED_40M: + g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M; + g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M; + SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M, + SPI_USR_DUMMY_CYCLELEN_S); //DUMMY + break; + default: + break; + } uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); uint32_t pkg_ver = chip_ver & 0x7; @@ -361,6 +379,19 @@ static void IRAM_ATTR flash_gpio_configure() // set drive ability for clock PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S); + + #if CONFIG_SPIRAM_TYPE_ESPPSRAM32 + 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(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); + } + #endif } } } diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c index 001b76f41..e01ad6a1e 100644 --- a/components/bootloader_support/src/flash_qio_mode.c +++ b/components/bootloader_support/src/flash_qio_mode.c @@ -114,6 +114,19 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8 /* dummy_len_plus values defined in ROM for SPI flash configuration */ extern uint8_t g_rom_spiflash_dummy_len_plus[]; +uint32_t bootloader_read_flash_id() +{ + uint32_t old_ctrl_reg = SPIFLASH.ctrl.val; + SPIFLASH.ctrl.val = SPI_WP_REG; // keep WP high while idle, otherwise leave DIO mode + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 0; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + uint32_t id = execute_flash_command(CMD_RDID, 0, 0, 24); + SPIFLASH.ctrl.val = old_ctrl_reg; + id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00); + return id; +} void bootloader_enable_qio_mode(void) { @@ -129,17 +142,12 @@ void bootloader_enable_qio_mode(void) /* Set up some of the SPIFLASH user/ctrl variables which don't change while we're probing using execute_flash_command() */ old_ctrl_reg = SPIFLASH.ctrl.val; - SPIFLASH.ctrl.val = SPI_WP_REG; // keep WP high while idle, otherwise leave DIO mode - SPIFLASH.user.usr_dummy = 0; - SPIFLASH.user.usr_addr = 0; - SPIFLASH.user.usr_command = 1; - SPIFLASH.user2.usr_command_bitlen = 7; - raw_flash_id = execute_flash_command(CMD_RDID, 0, 0, 24); + raw_flash_id = g_rom_flashchip.device_id; ESP_LOGD(TAG, "Raw SPI flash chip id 0x%x", raw_flash_id); - mfg_id = raw_flash_id & 0xFF; - flash_id = (raw_flash_id >> 16) | (raw_flash_id & 0xFF00); + mfg_id = (raw_flash_id >> 16) & 0xFF; + flash_id = raw_flash_id & 0xFFFF; ESP_LOGD(TAG, "Manufacturer ID 0x%02x chip ID 0x%04x", mfg_id, flash_id); for (i = 0; i < NUM_CHIPS-1; i++) { diff --git a/components/esp32/include/rom/spi_flash.h b/components/esp32/include/rom/spi_flash.h index 35d010d79..cc9856f45 100644 --- a/components/esp32/include/rom/spi_flash.h +++ b/components/esp32/include/rom/spi_flash.h @@ -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, diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index 39bb0a388..279de8d2f 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -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) {