From 2655a506c9ca201294af9a5214f1330b3978041b Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 9 Sep 2021 15:34:42 +0800 Subject: [PATCH 1/5] mspi: support auto detect octal flash vendor --- .../port/esp32s3/opiram_psram.c | 16 ++- .../port/esp32s3/spiram_psram.c | 2 +- components/esp_system/port/cpu_start.c | 37 +++--- components/esptool_py/Kconfig.projbuild | 30 ++--- .../esp32s3/opi_flash_cmd_format_mxic.h | 14 +-- .../spi_flash/esp32s3/opi_flash_private.h | 36 ++++++ .../esp32s3/spi_flash_oct_flash_init.c | 116 +++++++++++++++--- .../spi_flash/esp32s3/spi_timing_config.h | 4 +- components/spi_flash/esp_flash_spi_init.c | 24 ++-- components/spi_flash/flash_ops.c | 40 ++++-- .../spi_flash_os.h} | 18 ++- components/spi_flash/sim/Makefile.files | 82 +++++++------ .../spi_flash/spi_flash_timing_tuning.c | 6 +- components/spi_flash/test/test_read_write.c | 22 ++-- tools/ci/check_copyright_ignore.txt | 4 - tools/ci/check_public_headers_exceptions.txt | 1 - 16 files changed, 281 insertions(+), 171 deletions(-) create mode 100644 components/spi_flash/esp32s3/opi_flash_private.h rename components/spi_flash/include/{spi_flash_private.h => esp_private/spi_flash_os.h} (88%) diff --git a/components/esp_hw_support/port/esp32s3/opiram_psram.c b/components/esp_hw_support/port/esp32s3/opiram_psram.c index e232ffb797..f0647cc259 100644 --- a/components/esp_hw_support/port/esp32s3/opiram_psram.c +++ b/components/esp_hw_support/port/esp32s3/opiram_psram.c @@ -27,7 +27,7 @@ #if CONFIG_SPIRAM_MODE_OCT #include "soc/rtc.h" -#include "spi_flash_private.h" +#include "esp_private/spi_flash_os.h" #define OPI_PSRAM_SYNC_READ 0x0000 #define OPI_PSRAM_SYNC_WRITE 0x8080 @@ -153,7 +153,7 @@ static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *ou int dummy = OCT_PSRAM_RD_DUMMY_BITLEN; int data_bit_len = 16; - //Read MR0 register + //Read MR0~1 register esp_rom_opiflash_exec_cmd(spi_num, mode, OPI_PSRAM_REG_READ, cmd_len, 0x0, addr_bit_len, @@ -162,7 +162,7 @@ static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *ou &out_reg->mr0.val, data_bit_len, BIT(1), false); - //Read MR2 register + //Read MR2~3 register esp_rom_opiflash_exec_cmd(spi_num, mode, OPI_PSRAM_REG_READ, cmd_len, 0x2, addr_bit_len, @@ -171,6 +171,7 @@ static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *ou &out_reg->mr2.val, data_bit_len, BIT(1), false); + data_bit_len = 8; //Read MR4 register esp_rom_opiflash_exec_cmd(spi_num, mode, OPI_PSRAM_REG_READ, cmd_len, @@ -244,9 +245,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad //set to variable dummy mode SET_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); -#if CONFIG_ESPTOOLPY_FLASH_VENDOR_MXIC && CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR esp_rom_spi_set_dtr_swap_mode(1, false, false); -#endif //Set PSRAM read latency and drive strength static DRAM_ATTR opi_psram_mode_reg_t mode_reg = {0}; @@ -262,12 +261,9 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad mode_reg.mr2.density == 0x5 ? PSRAM_SIZE_128MBITS : mode_reg.mr2.density == 0x7 ? PSRAM_SIZE_256MBITS : 0; -#if CONFIG_ESPTOOLPY_FLASH_VENDOR_MXIC && CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR - esp_rom_spi_set_dtr_swap_mode(1, true, true); -#endif //Do PSRAM timing tuning, we use SPI1 to do the tuning, and set the SPI0 PSRAM timing related registers accordingly spi_timing_psram_tuning(); - ////Back to the high speed mode. Flash/PSRAM clocks are set to the clock that user selected. SPI0/1 registers are all set correctly + //Back to the high speed mode. Flash/PSRAM clocks are set to the clock that user selected. SPI0/1 registers are all set correctly spi_timing_enter_mspi_high_speed_mode(true); /** @@ -275,6 +271,8 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad * This function is to restore SPI1 init state. */ spi_flash_set_rom_required_regs(); + //Flash chip requires MSPI specifically, call this function to set them + spi_flash_set_vendor_required_regs(); s_config_psram_spi_phases(); return ESP_OK; diff --git a/components/esp_hw_support/port/esp32s3/spiram_psram.c b/components/esp_hw_support/port/esp32s3/spiram_psram.c index 1c36d0a74c..d84ab3f0e0 100644 --- a/components/esp_hw_support/port/esp32s3/spiram_psram.c +++ b/components/esp_hw_support/port/esp32s3/spiram_psram.c @@ -39,7 +39,7 @@ #if CONFIG_SPIRAM_MODE_QUAD #include "soc/rtc.h" -#include "spi_flash_private.h" +#include "esp_private/spi_flash_os.h" static const char* TAG = "psram"; diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index dc2f51a5e0..e936223c08 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -1,16 +1,8 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -64,7 +56,7 @@ #include "esp32h2/memprot.h" #endif -#include "spi_flash_private.h" +#include "esp_private/spi_flash_os.h" #include "bootloader_flash_config.h" #include "bootloader_flash.h" #include "esp_private/crosscore_int.h" @@ -371,18 +363,25 @@ void IRAM_ATTR call_start_cpu0(void) Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); #endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 - esp_mspi_pin_init(); - // For Octal flash, it's hard to implement a read_id function in OPI mode for all vendors. - // So we have to read it here in SPI mode, before entering the OPI mode. - bootloader_flash_update_id(); #if CONFIG_ESPTOOLPY_OCT_FLASH bool efuse_opflash_en = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA3_REG, EFUSE_FLASH_TYPE); if (!efuse_opflash_en) { ESP_EARLY_LOGE(TAG, "Octal Flash option selected, but EFUSE not configured!"); abort(); } - esp_opiflash_init(); #endif + esp_mspi_pin_init(); + // For Octal flash, it's hard to implement a read_id function in OPI mode for all vendors. + // So we have to read it here in SPI mode, before entering the OPI mode. + bootloader_flash_update_id(); + /** + * This function initialise the Flash chip to the user-defined settings. + * + * In bootloader, we only init Flash (and MSPI) to a preliminary state, for being flexible to + * different chips. + * In this stage, we re-configure the Flash (and MSPI) to required configuration + */ + spi_flash_init_chip_state(); #if CONFIG_IDF_TARGET_ESP32S3 //On other chips, this feature is not provided by HW, or hasn't been tested yet. spi_timing_flash_tuning(); diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 1e0b35beb8..a6cf30e11c 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -66,15 +66,6 @@ menu "Serial flasher config" bool "Enable Octal Flash" default n - choice ESPTOOLPY_FLASH_VENDOR - depends on ESPTOOLPY_OCT_FLASH - prompt "Select OPI Flash Vendor" - default ESPTOOLPY_FLASH_VENDOR_MXIC - - config ESPTOOLPY_FLASH_VENDOR_MXIC - bool "MXIC OPI FLASH(MX25UM25645G)" - endchoice - choice ESPTOOLPY_FLASHMODE prompt "Flash SPI mode" default ESPTOOLPY_FLASHMODE_DIO @@ -100,17 +91,16 @@ menu "Serial flasher config" bool "OPI" endchoice - choice ESPTOOLPY_FLASHMODE_OCT - depends on ESPTOOLPY_FLASHMODE_OPI - prompt "Flash OPI mode" - default ESPTOOLPY_FLASHMODE_OPI_DTR + choice ESPTOOLPY_FLASH_SAMPLE_MODE + prompt "Flash Sampling Mode" + default ESPTOOLPY_FLASH_SAMPLE_MODE_DTR if ESPTOOLPY_OCT_FLASH + default ESPTOOLPY_FLASH_SAMPLE_MODE_STR if !ESPTOOLPY_OCT_FLASH - config ESPTOOLPY_FLASHMODE_OPI_STR - depends on ESPTOOLPY_FLASH_VENDOR_MXIC - bool "OPI_STR" - config ESPTOOLPY_FLASHMODE_OPI_DTR - depends on ESPTOOLPY_FLASH_VENDOR_MXIC - bool "OPI_DTR" + config ESPTOOLPY_FLASH_SAMPLE_MODE_STR + bool "STR Mode" + config ESPTOOLPY_FLASH_SAMPLE_MODE_DTR + depends on ESPTOOLPY_OCT_FLASH + bool "DTR Mode" endchoice # Note: we use esptool.py to flash bootloader in @@ -136,7 +126,7 @@ menu "Serial flasher config" The SPI flash frequency to be used. config ESPTOOLPY_FLASHFREQ_120M - depends on ESPTOOLPY_FLASHMODE_OPI_STR || !ESPTOOLPY_OCT_FLASH + depends on ESPTOOLPY_FLASH_SAMPLE_MODE_STR bool "120 MHz" config ESPTOOLPY_FLASHFREQ_80M bool "80 MHz" diff --git a/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h b/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h index 06cd8a76fa..661b44ad3f 100644 --- a/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h +++ b/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if CONFIG_ESPTOOLPY_FLASH_VENDOR_MXIC -#if CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR -#define OPI_CMD_FORMAT() { \ +#if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP +#if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR +#define OPI_CMD_FORMAT_MXIC() { \ .rdid = { \ .mode = ESP_ROM_SPIFLASH_OPI_STR_MODE, \ .cmd_bit_len = 16, \ @@ -93,8 +93,8 @@ } \ } -#elif CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR -#define OPI_CMD_FORMAT() { \ +#elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR +#define OPI_CMD_FORMAT_MXIC() { \ .rdid = { \ .mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE, \ .cmd_bit_len = 16, \ @@ -180,5 +180,5 @@ .var_dummy_en = 1, \ } \ } -#endif -#endif +#endif // DTR / STR +#endif // #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP diff --git a/components/spi_flash/esp32s3/opi_flash_private.h b/components/spi_flash/esp32s3/opi_flash_private.h new file mode 100644 index 0000000000..eb98d04c0b --- /dev/null +++ b/components/spi_flash/esp32s3/opi_flash_private.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * System level OPI Flash APIs (private) + */ + +#pragma once + +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Register ROM functions and init flash device registers to make use of octal flash + * + * @param chip_id Full device ID read via RDID command + */ +esp_err_t esp_opiflash_init(uint32_t chip_id); + +/** + * @brief Set Octal Flash chip specifically required MSPI register settings here + */ +void esp_opiflash_set_required_regs(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c b/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c index f689b8bbe0..83acffb5d1 100644 --- a/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c +++ b/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c @@ -5,27 +5,33 @@ */ #include "sdkconfig.h" +#include "esp_log.h" #include "esp_err.h" #include "esp_rom_gpio.h" #include "esp32s3/rom/gpio.h" #include "esp32s3/rom/spi_flash.h" #include "esp32s3/rom/opi_flash.h" -#include "spi_flash_private.h" +#include "esp_private/spi_flash_os.h" +#include "opi_flash_private.h" #include "soc/spi_mem_reg.h" #include "soc/io_mux_reg.h" -#if CONFIG_ESPTOOLPY_FLASH_VENDOR_MXIC #include "opi_flash_cmd_format_mxic.h" -#endif #define SPI_FLASH_SPI_CMD_WRCR2 0x72 #define SPI_FLASH_SPI_CMD_RDSR 0x05 #define SPI_FLASH_SPI_CMD_RDCR 0x15 #define SPI_FLASH_SPI_CMD_WRSRCR 0x01 +/** + * Supported Flash chip vendor id + */ +#define ESP_FLASH_CHIP_MXIC_OCT 0xC2 + +const static char *TAG = "Octal Flash"; // default value is rom_default_spiflash_legacy_flash_func extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs; extern int SPI_write_enable(void *spi); -DRAM_ATTR const esp_rom_opiflash_def_t opiflash_cmd_def = OPI_CMD_FORMAT(); +static uint32_t s_vendor_id; static void s_register_rom_function(void) @@ -46,7 +52,24 @@ static void s_register_rom_function(void) rom_spiflash_legacy_funcs = &rom_func; } -#if CONFIG_ESPTOOLPY_FLASH_VENDOR_MXIC +#if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP +/*---------------------------------------------------------------------------------------------------- + MXIC Specific Functions +-----------------------------------------------------------------------------------------------------*/ +static esp_err_t s_probe_mxic_chip(uint32_t chip_id, uint8_t *out_vendor_id) +{ + if (chip_id >> 16 != ESP_FLASH_CHIP_MXIC_OCT) { + return ESP_ERR_NOT_FOUND; + } + if (((chip_id >> 8) & 0xff) != 0x80) { + ESP_EARLY_LOGE(TAG, "Detected MXIC Flash, but memory type is not Octal"); + return ESP_ERR_NOT_FOUND; + } + *out_vendor_id = ESP_FLASH_CHIP_MXIC_OCT; + + return ESP_OK; +} + // 0x00: SPI; 0x01: STR OPI; 0x02: DTR OPI static void s_set_flash_dtr_str_opi_mode(int spi_num, uint8_t val) { @@ -127,7 +150,8 @@ static void s_set_pin_drive_capability(uint8_t drv) static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode) { - esp_rom_opiflash_legacy_driver_init(&opiflash_cmd_def); + static const esp_rom_opiflash_def_t opiflash_cmd_def_mxic = OPI_CMD_FORMAT_MXIC(); + esp_rom_opiflash_legacy_driver_init(&opiflash_cmd_def_mxic); esp_rom_spiflash_wait_idle(&g_rom_flashchip); // increase flash output driver strength @@ -135,13 +159,13 @@ static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode) // STR/DTR specific setting esp_rom_spiflash_wait_idle(&g_rom_flashchip); -#if CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR +#if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR s_set_pin_drive_capability(3); s_set_flash_dtr_str_opi_mode(1, 0x1); esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd); esp_rom_spi_set_dtr_swap_mode(0, false, false); esp_rom_spi_set_dtr_swap_mode(1, false, false); -#else //CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR +#else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR s_set_pin_drive_capability(3); s_set_flash_dtr_str_opi_mode(1, 0x2); esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd); @@ -149,26 +173,82 @@ static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode) esp_rom_spi_set_dtr_swap_mode(1, true, true); #endif - s_register_rom_function(); esp_rom_opiflash_wait_idle(); } -#endif // #if CONFIG_FLASH_VENDOR_XXX +#endif // #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP -esp_err_t esp_opiflash_init(void) + +/*---------------------------------------------------------------------------------------------------- + General Functions +-----------------------------------------------------------------------------------------------------*/ +typedef struct opi_flash_func_t { + esp_err_t (*probe)(uint32_t flash_id, uint8_t *out_vendor_id); //Function pointer for detecting Flash chip vendor + void (*init)(esp_rom_spiflash_read_mode_t mode); //Function pointer for initialising certain Flash chips +} opi_flash_func_t; + +#if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP +static const opi_flash_func_t opi_flash_func_mxic = { + .probe = &s_probe_mxic_chip, + .init = &s_flash_init_mxic +}; +#endif + +static const opi_flash_func_t *registered_chip_funcs[] = { +#if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP + &opi_flash_func_mxic, +#endif + NULL, +}; + +esp_err_t esp_opiflash_init(uint32_t chip_id) { + esp_err_t ret = ESP_FAIL; esp_rom_spiflash_read_mode_t mode; -#if CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR +#if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR mode = ESP_ROM_SPIFLASH_OPI_STR_MODE; -#elif CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR +#elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; #else mode = ESP_ROM_SPIFLASH_FASTRD_MODE; #endif -#if CONFIG_ESPTOOLPY_FLASH_VENDOR_MXIC - s_flash_init_mxic(mode); -#else - abort(); -#endif + //To check which Flash chip is used + const opi_flash_func_t **chip_func = ®istered_chip_funcs[0]; + + uint8_t vendor_id = 0; + while (*chip_func) { + ret = (*chip_func)->probe(chip_id, &vendor_id); + if (ret == ESP_OK) { + // Detect this is the supported chip type + (*chip_func)->init(mode); + s_vendor_id = vendor_id; + s_register_rom_function(); + break; + } + chip_func++; + } + + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "No detected Flash chip, please check the menuconfig to see if the chip is supported"); + abort(); + } + return ESP_OK; } + +/** + * Add Flash chip specifically required MSPI register settings here + */ +void esp_opiflash_set_required_regs(void) +{ + bool is_swap = false; +#if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR + if (s_vendor_id == ESP_FLASH_CHIP_MXIC_OCT) { + is_swap = true; + } +#else + //STR mode does not need to enable ddr_swap registers +#endif + esp_rom_spi_set_dtr_swap_mode(0, is_swap, is_swap); + esp_rom_spi_set_dtr_swap_mode(1, is_swap, is_swap); +} diff --git a/components/spi_flash/esp32s3/spi_timing_config.h b/components/spi_flash/esp32s3/spi_timing_config.h index cd7d06c683..167232e43c 100644 --- a/components/spi_flash/esp32s3/spi_timing_config.h +++ b/components/spi_flash/esp32s3/spi_timing_config.h @@ -44,8 +44,8 @@ extern "C" { * 2. DDR mode requires the core clock divider (core_clk / div = module_clk) to be power of 2. */ //--------------------------------------FLASH Sampling Mode --------------------------------------// -#define SPI_TIMING_FLASH_DTR_MODE (CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR || CONFIG_ESPTOOLPY_FLASHMODE_OIO_DTR) -#define SPI_TIMING_FLASH_STR_MODE (CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR || !CONFIG_ESPTOOLPY_OCT_FLASH) +#define SPI_TIMING_FLASH_DTR_MODE CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR +#define SPI_TIMING_FLASH_STR_MODE CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR //--------------------------------------FLASH Module Clock --------------------------------------// #if CONFIG_ESPTOOLPY_FLASHFREQ_20M #define SPI_TIMING_FLASH_MODULE_CLOCK 20 diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 79605e56c8..4ac935f6c0 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "sdkconfig.h" #include "esp_flash.h" @@ -27,7 +19,7 @@ #include "hal/gpio_hal.h" #include "esp_flash_internal.h" #include "esp_rom_gpio.h" -#include "spi_flash_private.h" +#include "esp_private/spi_flash_os.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S2 @@ -71,9 +63,9 @@ esp_flash_t *esp_flash_default_chip = NULL; #define DEFAULT_FLASH_MODE SPI_FLASH_DIO #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DOUT) #define DEFAULT_FLASH_MODE SPI_FLASH_DOUT -#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR) +#elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR) #define DEFAULT_FLASH_MODE SPI_FLASH_OPI_STR -#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR) +#elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR) #define DEFAULT_FLASH_MODE SPI_FLASH_OPI_DTR #else #define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 116f07ec31..0ecb6866d3 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -28,6 +20,7 @@ #include "esp_spi_flash.h" #include "esp_log.h" #include "esp_private/system_internal.h" +#include "esp_private/spi_flash_os.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/cache.h" #include "esp32/rom/spi_flash.h" @@ -43,6 +36,7 @@ #include "esp32s3/rom/cache.h" #include "esp32s3/clk.h" #include "esp32s3/clk.h" +#include "esp32s3/opi_flash_private.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/cache.h" #include "esp32c3/rom/spi_flash.h" @@ -175,6 +169,16 @@ void IRAM_ATTR esp_mspi_pin_init(void) #endif } +esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) +{ +#if CONFIG_ESPTOOLPY_OCT_FLASH + return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id); +#else + //currently we don't need other setup for initialising Quad Flash + return ESP_OK; +#endif +} + void spi_flash_init(void) { spi_flash_init_lock(); @@ -906,3 +910,13 @@ void IRAM_ATTR spi_flash_set_rom_required_regs(void) */ #endif } + +void IRAM_ATTR spi_flash_set_vendor_required_regs(void) +{ +#if CONFIG_ESPTOOLPY_OCT_FLASH + //Flash chip requires MSPI specifically, call this function to set them + esp_opiflash_set_required_regs(); +#else + //currently we don't need to set other MSPI registers for Quad Flash +#endif +} diff --git a/components/spi_flash/include/spi_flash_private.h b/components/spi_flash/include/esp_private/spi_flash_os.h similarity index 88% rename from components/spi_flash/include/spi_flash_private.h rename to components/spi_flash/include/esp_private/spi_flash_os.h index 9d822fb947..e302df86ea 100644 --- a/components/spi_flash/include/spi_flash_private.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ - +/** + * System level MSPI APIs (private) + */ /** * Currently the MSPI timing tuning related APIs are designed to be private. * Because: @@ -17,6 +19,10 @@ */ #pragma once +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S2 @@ -34,9 +40,9 @@ extern "C" { #endif /** - * @brief Register ROM functions and init flash device registers to make use of octal flash + * @brief To setup Flash chip */ -esp_err_t esp_opiflash_init(void); +esp_err_t spi_flash_init_chip_state(void); /** * @brief Make MSPI work under 20Mhz @@ -88,6 +94,12 @@ void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing */ bool spi_timine_config_flash_is_tuned(void); +/** + * @brief Set Flash chip specifically required MSPI register settings here + */ +void spi_flash_set_vendor_required_regs(void); + + #ifdef __cplusplus } #endif diff --git a/components/spi_flash/sim/Makefile.files b/components/spi_flash/sim/Makefile.files index 037dd6eefd..336e63895e 100644 --- a/components/spi_flash/sim/Makefile.files +++ b/components/spi_flash/sim/Makefile.files @@ -1,43 +1,45 @@ SOURCE_FILES := \ - SpiFlash.cpp \ - flash_mock.cpp \ - flash_mock_util.c \ - $(addprefix ../, \ - partition.c \ - flash_ops.c \ - esp32/flash_ops_esp32.c \ - ) \ + SpiFlash.cpp \ + flash_mock.cpp \ + flash_mock_util.c \ + $(addprefix ../, \ + partition.c \ + flash_ops.c \ + esp32/flash_ops_esp32.c \ + ) \ INCLUDE_DIRS := \ - . \ - ../ \ - ../include \ - ../private_include \ - $(addprefix stubs/, \ - app_update/include \ - driver/include \ - esp_timer/include \ - freertos/include \ - log/include \ - newlib/include \ - sdmmc/include \ - vfs/include \ - ) \ - $(addprefix ../../../components/, \ - esp_rom/include \ - esp_common/include \ - esp_hw_support/include \ - esp_hw_support/include/soc \ - esp_system/include \ - xtensa/include \ - xtensa/esp32/include \ - soc/esp32/include \ - heap/include \ - soc/include \ - esp32/include \ - esp_timer/include \ - bootloader_support/include \ - app_update/include \ - hal/include \ - spi_flash/include \ - ) + . \ + ../ \ + ../include \ + ../private_include \ + $(addprefix stubs/, \ + app_update/include \ + driver/include \ + esp_timer/include \ + freertos/include \ + log/include \ + newlib/include \ + sdmmc/include \ + vfs/include \ + ) \ + $(addprefix ../../../components/, \ + esp_rom/include \ + esp_common/include \ + esp_hw_support/include \ + esp_hw_support/include/soc \ + esp_system/include \ + xtensa/include \ + xtensa/esp32/include \ + soc/esp32/include \ + heap/include \ + soc/include \ + esp32/include \ + esp_timer/include \ + bootloader_support/include \ + app_update/include \ + hal/include \ + hal/esp32/include \ + hal/platform_port/include \ + spi_flash/include \ + ) diff --git a/components/spi_flash/spi_flash_timing_tuning.c b/components/spi_flash/spi_flash_timing_tuning.c index 5fd5fa5c54..42748f0100 100644 --- a/components/spi_flash/spi_flash_timing_tuning.c +++ b/components/spi_flash/spi_flash_timing_tuning.c @@ -13,7 +13,7 @@ #include "esp_log.h" #include "soc/spi_mem_reg.h" #include "soc/io_mux_reg.h" -#include "spi_flash_private.h" +#include "esp_private/spi_flash_os.h" #include "soc/soc.h" #if CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/spi_timing_config.h" @@ -235,14 +235,14 @@ static void select_best_tuning_config(spi_timing_config_t *config, uint32_t cons if (is_flash) { #if SPI_TIMING_FLASH_DTR_MODE best_point = select_best_tuning_config_dtr(config, consecutive_length, end); -#else //#if SPI_TIMING_FLASH_STR_MODE +#elif SPI_TIMING_FLASH_STR_MODE best_point = select_best_tuning_config_str(config, consecutive_length, end); #endif s_flash_best_timing_tuning_config = config->tuning_config_table[best_point]; } else { #if SPI_TIMING_PSRAM_DTR_MODE best_point = select_best_tuning_config_dtr(config, consecutive_length, end); -#else //#if SPI_TIMING_PSRAM_STR_MODE +#elif SPI_TIMING_PSRAM_STR_MODE best_point = select_best_tuning_config_str(config, consecutive_length, end); #endif s_psram_best_timing_tuning_config = config->tuning_config_table[best_point]; diff --git a/components/spi_flash/test/test_read_write.c b/components/spi_flash/test/test_read_write.c index 9510fb7e8d..fff4495b63 100644 --- a/components/spi_flash/test/test_read_write.c +++ b/components/spi_flash/test/test_read_write.c @@ -1,16 +1,8 @@ -// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // Test for spi_flash_{read,write}. @@ -197,9 +189,9 @@ static void IRAM_ATTR fix_rom_func(void) read_mode = ESP_ROM_SPIFLASH_DIO_MODE; #elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT read_mode = ESP_ROM_SPIFLASH_DOUT_MODE; -#elif CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR +#elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR read_mode = ESP_ROM_SPIFLASH_OPI_STR_MODE; -#elif CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR +#elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR read_mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; #endif diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 51b7be4a10..69f6c98e41 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1142,7 +1142,6 @@ components/esp_system/port/arch/xtensa/expression_with_stack.c components/esp_system/port/arch/xtensa/panic_arch.c components/esp_system/port/arch/xtensa/trax.c components/esp_system/port/brownout.c -components/esp_system/port/cpu_start.c components/esp_system/port/include/esp_clk_internal.h components/esp_system/port/include/port/panic_funcs.h components/esp_system/port/include/riscv/eh_frame_parser_impl.h @@ -2785,9 +2784,7 @@ components/spi_flash/esp32s2/flash_ops_esp32s2.c components/spi_flash/esp32s2/spi_flash_rom_patch.c components/spi_flash/esp32s3/flash_ops_esp32s3.c components/spi_flash/esp_flash_api.c -components/spi_flash/esp_flash_spi_init.c components/spi_flash/flash_mmap.c -components/spi_flash/flash_ops.c components/spi_flash/include/esp_flash.h components/spi_flash/include/esp_flash_internal.h components/spi_flash/include/esp_flash_spi_init.h @@ -2828,7 +2825,6 @@ components/spi_flash/test/test_mmap.c components/spi_flash/test/test_out_of_bounds_write.c components/spi_flash/test/test_partition_ext.c components/spi_flash/test/test_partitions.c -components/spi_flash/test/test_read_write.c components/spi_flash/test/test_spi_flash.c components/spiffs/esp_spiffs.c components/spiffs/include/esp_spiffs.h diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 574b6d86db..39e5111067 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -148,4 +148,3 @@ components/ulp/include/esp32s2/ulp_riscv.h components/lwip/include/apps/sntp/sntp.h components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h -components/spi_flash/include/spi_flash_private.h From 4cafdbd83be4d33ff3fd8d25cb766610ac269c80 Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 14 Sep 2021 15:19:17 +0800 Subject: [PATCH 2/5] mspi: fix psram cs timing register setting not in iram bug --- components/esp_hw_support/port/esp32s3/opiram_psram.c | 2 +- components/esp_hw_support/port/esp32s3/spiram_psram.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp_hw_support/port/esp32s3/opiram_psram.c b/components/esp_hw_support/port/esp32s3/opiram_psram.c index f0647cc259..e7a8396623 100644 --- a/components/esp_hw_support/port/esp32s3/opiram_psram.c +++ b/components/esp_hw_support/port/esp32s3/opiram_psram.c @@ -215,7 +215,7 @@ static void IRAM_ATTR s_print_psram_info(opi_psram_mode_reg_t *reg_val) reg_val->mr0.drive_str == 0x02 ? 4 : 8); } -static void psram_set_cs_timing(void) +static void IRAM_ATTR psram_set_cs_timing(void) { //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for PSRAM, so we only need to set SPI0 related registers here SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M); diff --git a/components/esp_hw_support/port/esp32s3/spiram_psram.c b/components/esp_hw_support/port/esp32s3/spiram_psram.c index d84ab3f0e0..ecd10f08d9 100644 --- a/components/esp_hw_support/port/esp32s3/spiram_psram.c +++ b/components/esp_hw_support/port/esp32s3/spiram_psram.c @@ -290,7 +290,7 @@ static void IRAM_ATTR psram_enable_qio_mode(int spi_num) false); /* whether is program/erase operation */ } -static void psram_set_cs_timing(void) +static void IRAM_ATTR psram_set_cs_timing(void) { //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time registers for PSRAM, so we only need to set SPI0 related registers here SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, 0, SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S); From d6caf142d3b1168742ea92d7925c6c7f2e2581be Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 9 Sep 2021 15:50:42 +0800 Subject: [PATCH 3/5] ci: add flash psram test under different configs on esp32s3 --- .gitlab/ci/target-test.yml | 23 +++ .../system/flash_psram/CMakeLists.txt | 6 + tools/test_apps/system/flash_psram/README.md | 7 + .../test_apps/system/flash_psram/app_test.py | 54 ++++++ .../system/flash_psram/main/CMakeLists.txt | 2 + .../flash_psram/main/test_flash_psram.c | 160 ++++++++++++++++++ .../system/flash_psram/sdkconfig.ci.default | 2 + .../flash_psram/sdkconfig.ci.f4r4_120sdr | 5 + .../sdkconfig.ci.f4r4_120sdr_120sdr | 7 + .../sdkconfig.ci.f4r4_120sdr_40sdr | 7 + .../sdkconfig.ci.f4r4_40sdr_120sdr | 7 + .../flash_psram/sdkconfig.ci.f4r4_80sdr_80sdr | 7 + .../flash_psram/sdkconfig.ci.f4r8_120sdr | 5 + .../flash_psram/sdkconfig.ci.f4r8_80sdr_40ddr | 8 + .../flash_psram/sdkconfig.ci.f4r8_80sdr_80ddr | 8 + .../flash_psram/sdkconfig.ci.f8r8_120sdr | 8 + .../flash_psram/sdkconfig.ci.f8r8_40ddr_40ddr | 10 ++ .../flash_psram/sdkconfig.ci.f8r8_40ddr_80ddr | 10 ++ .../flash_psram/sdkconfig.ci.f8r8_80ddr_40ddr | 10 ++ .../flash_psram/sdkconfig.ci.f8r8_80ddr_80ddr | 10 ++ .../flash_psram/sdkconfig.ci.f8r8_80sdr_80ddr | 10 ++ 21 files changed, 366 insertions(+) create mode 100644 tools/test_apps/system/flash_psram/CMakeLists.txt create mode 100644 tools/test_apps/system/flash_psram/README.md create mode 100644 tools/test_apps/system/flash_psram/app_test.py create mode 100644 tools/test_apps/system/flash_psram/main/CMakeLists.txt create mode 100644 tools/test_apps/system/flash_psram/main/test_flash_psram.c create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.default create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_120sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_40sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_40sdr_120sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_80sdr_80sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_120sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_40ddr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_80ddr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_120sdr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_40ddr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_80ddr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_40ddr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_80ddr create mode 100644 tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80sdr_80ddr diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index f9f3c10c90..25fc2eb3d9 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -303,6 +303,11 @@ example_test_ESP32C3_SDSPI: - .test_app_template - .rules:test:custom_test-esp32c3 +.test_app_esp32s3_template: + extends: + - .test_app_template + - .rules:test:custom_test-esp32s3 + test_app_test_001: extends: .test_app_esp32_template tags: @@ -345,6 +350,24 @@ test_app_test_esp32_generic: variables: SETUP_TOOLS: "1" +test_app_test_flash_psram_f4r4: + extends: .test_app_esp32s3_template + tags: + - ESP32S3 + - MSPI_F4R4 + +test_app_test_flash_psram_f4r8: + extends: .test_app_esp32s3_template + tags: + - ESP32S3 + - MSPI_F4R8 + +test_app_test_flash_psram_f8r8: + extends: .test_app_esp32s3_template + tags: + - ESP32S3 + - MSPI_F8R8 + .component_ut_template: extends: .target_test_job_template variables: diff --git a/tools/test_apps/system/flash_psram/CMakeLists.txt b/tools/test_apps/system/flash_psram/CMakeLists.txt new file mode 100644 index 0000000000..7b9d93cda8 --- /dev/null +++ b/tools/test_apps/system/flash_psram/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_flash_psram) diff --git a/tools/test_apps/system/flash_psram/README.md b/tools/test_apps/system/flash_psram/README.md new file mode 100644 index 0000000000..3677101481 --- /dev/null +++ b/tools/test_apps/system/flash_psram/README.md @@ -0,0 +1,7 @@ +| Supported Targets | ESP32-S3 | +| ----------------- | -------- | + +This project tests if Flash and PSRAM can work under different configurations. +To add new configuration, create one more sdkconfig.ci.NAME file in this directory. + +If you need to test for anything other than flash and psram, create another test project. diff --git a/tools/test_apps/system/flash_psram/app_test.py b/tools/test_apps/system/flash_psram/app_test.py new file mode 100644 index 0000000000..3b7dd83b86 --- /dev/null +++ b/tools/test_apps/system/flash_psram/app_test.py @@ -0,0 +1,54 @@ +# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + + +import glob +import os +from typing import Any + +import ttfw_idf +from tiny_test_fw import Utility + + +def test_loop(env, config_names): # type: (Any, Any) -> None + + for name in config_names: + Utility.console_log("Checking config \"{}\"... ".format(name), end='') + dut = env.get_dut('flash_psram', 'tools/test_apps/system/flash_psram', app_config_name=name) + dut.start_app() + dut.expect('flash psram test success') + env.close_dut(dut.name) + Utility.console_log('done') + + +# For F8R8 board (Octal Flash and Octal PSRAM) +@ttfw_idf.idf_custom_test(env_tag='MSPI_F8R8', target=['esp32s3']) +def test_flash8_psram8(env, _): # type: (Any, Any) -> None + + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.f8r8*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + test_loop(env, config_names) + + +# For F4R8 board (Quad Flash and Octal PSRAM) +@ttfw_idf.idf_custom_test(env_tag='MSPI_F4R8', target=['esp32s3']) +def test_flash4_psram8(env, _): # type: (Any, Any) -> None + + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.f4r8*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + test_loop(env, config_names) + + +# For F4R4 board (Quad Flash and Quad PSRAM) +@ttfw_idf.idf_custom_test(env_tag='MSPI_F4R4', target=['esp32s3']) +def test_flash4_psram4(env, _): # type: (Any, Any) -> None + + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.f4r4*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + test_loop(env, config_names) + + +if __name__ == '__main__': + test_flash8_psram8() + test_flash4_psram8() + test_flash4_psram4() diff --git a/tools/test_apps/system/flash_psram/main/CMakeLists.txt b/tools/test_apps/system/flash_psram/main/CMakeLists.txt new file mode 100644 index 0000000000..437bd3fe3b --- /dev/null +++ b/tools/test_apps/system/flash_psram/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "test_flash_psram.c" + INCLUDE_DIRS ".") diff --git a/tools/test_apps/system/flash_psram/main/test_flash_psram.c b/tools/test_apps/system/flash_psram/main/test_flash_psram.c new file mode 100644 index 0000000000..a44dce24de --- /dev/null +++ b/tools/test_apps/system/flash_psram/main/test_flash_psram.c @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_check.h" +#include "esp_attr.h" +#if CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/opi_flash.h" +#endif + +const static char *TAG = "SPI0"; + +//-----------------------------------------SPI0 PSRAM TEST-----------------------------------------------// +#if CONFIG_SPIRAM + +#if CONFIG_SPIRAM_MODE_OCT +#define SPI0_PSRAM_TEST_LEN (512 * 1024) +#define LENGTH_PER_TIME 1024 +#else +#define SPI0_PSRAM_TEST_LEN (128 * 1024) +#define LENGTH_PER_TIME 1024 +#endif + +static esp_err_t spi0_psram_test(void) +{ + printf("----------SPI0 PSRAM Test----------\n"); + + uint8_t *psram_wr_buf = (uint8_t *)heap_caps_malloc(LENGTH_PER_TIME, MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM); + if (!psram_wr_buf) { + printf("no memory\n"); + abort(); + } + + uint32_t *psram_rd_buf = (uint32_t *)heap_caps_malloc(SPI0_PSRAM_TEST_LEN, MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM); + if (!psram_rd_buf) { + printf("no memory\n"); + abort(); + } + + srand(399); + for (int i = 0; i < SPI0_PSRAM_TEST_LEN / LENGTH_PER_TIME; i++) { + for (int j = 0; j < sizeof(psram_wr_buf); j++) { + psram_wr_buf[j] = rand(); + } + memcpy(psram_rd_buf + i * LENGTH_PER_TIME, psram_wr_buf, LENGTH_PER_TIME); + + if (memcmp(psram_rd_buf + i * LENGTH_PER_TIME, psram_wr_buf, LENGTH_PER_TIME) != 0) { + printf("Fail\n"); + free(psram_rd_buf); + free(psram_wr_buf); + return ESP_FAIL; + } + } + + free(psram_rd_buf); + free(psram_wr_buf); + printf(DRAM_STR("----------SPI0 PSRAM Test Success----------\n\n")); + return ESP_OK; +} +#endif + + +//-----------------------------------------SPI1 FLASH TEST-----------------------------------------------// +#define SPI1_FLASH_TEST_LEN 512 +#define SECTOR_LEN 4096 +#define SPI1_FLASH_TEST_NUM (SECTOR_LEN / SPI1_FLASH_TEST_LEN) +#define SPI1_FLASH_TEST_ADDR 0x200000 + +extern void spi_flash_disable_interrupts_caches_and_other_cpu(void); +extern void spi_flash_enable_interrupts_caches_and_other_cpu(void); +static DRAM_ATTR uint8_t rd_buf[SPI1_FLASH_TEST_LEN]; +static DRAM_ATTR uint8_t wr_buf[SPI1_FLASH_TEST_LEN]; + + +static IRAM_ATTR esp_err_t spi1_flash_test(void) +{ + printf(DRAM_STR("----------SPI1 Flash Test----------\n")); + + //We need to use SPI1 + spi_flash_disable_interrupts_caches_and_other_cpu(); + uint32_t sector_num = SPI1_FLASH_TEST_ADDR / SECTOR_LEN; + esp_rom_spiflash_erase_sector(sector_num); + spi_flash_enable_interrupts_caches_and_other_cpu(); + + for (int i = 0; i < SPI1_FLASH_TEST_NUM; i++) { + for (int j = i + 10; j < SPI1_FLASH_TEST_LEN; j++) { + wr_buf[j] = j; + } + + spi_flash_disable_interrupts_caches_and_other_cpu(); + uint32_t test_flash_addr = SPI1_FLASH_TEST_ADDR + i * SPI1_FLASH_TEST_LEN; + esp_rom_spiflash_write(test_flash_addr, (uint32_t*)wr_buf, SPI1_FLASH_TEST_LEN); + esp_rom_spiflash_read(test_flash_addr, (uint32_t*)rd_buf, SPI1_FLASH_TEST_LEN); + spi_flash_enable_interrupts_caches_and_other_cpu(); + + if (memcmp(wr_buf, rd_buf, SPI1_FLASH_TEST_LEN) != 0) { + printf(DRAM_STR("error happened between 0x%x and 0x%x!!!!\n"), test_flash_addr, test_flash_addr + SPI1_FLASH_TEST_LEN); + for (int i = 0; i < SPI1_FLASH_TEST_LEN; i++) { + if (wr_buf[i] != rd_buf[i]) { + printf(DRAM_STR("err: wr[%d]: 0x%02x -- rd[%d]: 0x%02x\n"), i, wr_buf[i], i, rd_buf[i]); + } + } + return ESP_FAIL; + } + memset(rd_buf, 0x0, SPI1_FLASH_TEST_LEN); + } + + printf(DRAM_STR("----------SPI1 Flash Test Success----------\n\n")); + + return ESP_OK; +} + +//-----------------------------------------SPI0 FLASH TEST-----------------------------------------------// +#define SPI0_FLASH_TEST_LEN 32 +#define SPI0_FLASH_TEST_BUF {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F} + +uint8_t flash_rd_buf[SPI0_FLASH_TEST_LEN] __attribute__((section (".flash.rodata"))) = SPI0_FLASH_TEST_BUF; +extern int _flash_rodata_start; +extern int _rodata_reserved_end; + + +static IRAM_ATTR esp_err_t spi0_flash_test(void) +{ + printf("----------SPI0 Flash Test----------\n"); + //Check if the flash_rd_buf is in .rodata + ESP_RETURN_ON_ERROR(((intptr_t)flash_rd_buf >= (intptr_t)_flash_rodata_start) && ((intptr_t)flash_rd_buf < (intptr_t)_rodata_reserved_end), TAG, "psram_rd_buf not in rodata"); + + uint8_t cmp_buf[SPI0_FLASH_TEST_LEN] = SPI0_FLASH_TEST_BUF; + + for (int i = 0; i < SPI0_FLASH_TEST_LEN; i++) { + if (flash_rd_buf[i] != cmp_buf[i]) { + return ESP_FAIL; + } + } + printf(DRAM_STR("----------SPI0 Flash Test Success----------\n\n")); + + return ESP_OK; +} + +void app_main(void) +{ + ESP_ERROR_CHECK(spi0_flash_test()); + +#if CONFIG_SPIRAM + ESP_ERROR_CHECK(spi0_psram_test()); +#endif + ESP_ERROR_CHECK(spi1_flash_test()); + + printf("flash psram test success\n"); +} diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.default b/tools/test_apps/system/flash_psram/sdkconfig.ci.default new file mode 100644 index 0000000000..5c8d4b156b --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.default @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32s3" +CONFIG_IDF_TARGET_ESP32S3=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr new file mode 100644 index 0000000000..537b02e9fd --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr @@ -0,0 +1,5 @@ +# Legacy, F4R4, Flash 120M SDR, PSRAM disable + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_120sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_120sdr new file mode 100644 index 0000000000..9e2cf2e9f7 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_120sdr @@ -0,0 +1,7 @@ +# Legacy, F4R4, Flash 120M SDR, PSRAM 120M SDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_SPEED_120M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_40sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_40sdr new file mode 100644 index 0000000000..05d6318a64 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_120sdr_40sdr @@ -0,0 +1,7 @@ +# Legacy, F4R4, Flash 120M SDR, PSRAM 40M SDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_SPEED_40M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_40sdr_120sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_40sdr_120sdr new file mode 100644 index 0000000000..e26e7cfba1 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_40sdr_120sdr @@ -0,0 +1,7 @@ +# Legacy, F4R4, Flash 40M SDR, PSRAM 120M SDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_SPEED_120M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_80sdr_80sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_80sdr_80sdr new file mode 100644 index 0000000000..b20bf13fbd --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r4_80sdr_80sdr @@ -0,0 +1,7 @@ +# Legacy, F4R4, Flash 80M SDR, PSRAM 80M SDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_SPEED_80M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_120sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_120sdr new file mode 100644 index 0000000000..2caeb8de79 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_120sdr @@ -0,0 +1,5 @@ +# Legacy, F4R8, Flash 120M SDR, PSRAM disable + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_40ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_40ddr new file mode 100644 index 0000000000..ee44bec1bc --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_40ddr @@ -0,0 +1,8 @@ +# Legacy, F4R8, Flash 80M SDR, PSRAM 40M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_40M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_80ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_80ddr new file mode 100644 index 0000000000..b0f08a79ac --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f4r8_80sdr_80ddr @@ -0,0 +1,8 @@ +# Legacy, F4R8, Flash 80M SDR, PSRAM 80M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_120sdr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_120sdr new file mode 100644 index 0000000000..e85e30a97f --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_120sdr @@ -0,0 +1,8 @@ +# Legacy, F8R8, Flash 120M SDR, PSRAM disable + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=n diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_40ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_40ddr new file mode 100644 index 0000000000..a9bd3815da --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_40ddr @@ -0,0 +1,10 @@ +# Legacy, F8R8, Flash 40M DDR, PSRAM 40M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_40M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_80ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_80ddr new file mode 100644 index 0000000000..a35cf80a87 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_40ddr_80ddr @@ -0,0 +1,10 @@ +# Legacy, F8R8, Flash 40M DDR, PSRAM 80M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_40ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_40ddr new file mode 100644 index 0000000000..5a128bf171 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_40ddr @@ -0,0 +1,10 @@ +# Legacy, F8R8, Flash 80M DDR, PSRAM 40M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_40M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_80ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_80ddr new file mode 100644 index 0000000000..4b37baaa3d --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80ddr_80ddr @@ -0,0 +1,10 @@ +# Legacy, F8R8, Flash 80M DDR, PSRAM 80M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y diff --git a/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80sdr_80ddr b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80sdr_80ddr new file mode 100644 index 0000000000..0451be8686 --- /dev/null +++ b/tools/test_apps/system/flash_psram/sdkconfig.ci.f8r8_80sdr_80ddr @@ -0,0 +1,10 @@ +# Legacy, F8R8, Flash 80M SDR, PSRAM 80M DDR + +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y From 7ff9332243299422acbfd57c8321894e86a00633 Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 24 Sep 2021 10:37:12 +0800 Subject: [PATCH 4/5] rtc: fix mspi timing issue when self-calibrate ocode When doing OCode self-calibration in rtc_init.c, it will change the system clock from PLL to XTAL, which is in a lower frequency, and MSPI timing tuning is not needed. Therefore we should modify the timing configurations accordingly, and set it back after the calibration. This is a temporary fix --- .../esp_hw_support/port/esp32s3/rtc_init.c | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/port/esp32s3/rtc_init.c b/components/esp_hw_support/port/esp32s3/rtc_init.c index 575e07a60b..2a80ca3e3d 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_init.c +++ b/components/esp_hw_support/port/esp32s3/rtc_init.c @@ -18,9 +18,23 @@ #include "regi2c_ulp.h" #include "soc_log.h" #include "esp_err.h" +#include "esp_attr.h" #include "esp_efuse.h" #include "esp_efuse_table.h" +#ifndef BOOTLOADER_BUILD +/** + * TODO: IDF-3204 + * Temporarily solution. Depends on MSPI + * Final solution: the rtc should not depend on MSPI. We should do rtc related before Flash init + */ +#include "esp_private/spi_flash_os.h" +#include "esp32s3/rom/cache.h" +#include "freertos/portmacro.h" +portMUX_TYPE rtc_init_spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; +#endif + + #define RTC_CNTL_MEM_FORCE_NOISO (RTC_CNTL_SLOWMEM_FORCE_NOISO | RTC_CNTL_FASTMEM_FORCE_NOISO) static const char *TAG = "rtcinit"; @@ -231,8 +245,40 @@ static void set_ocode_by_efuse(int calib_version) REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1); } -static void calibrate_ocode(void) +#ifndef BOOTLOADER_BUILD +//TODO: IDF-3204 +//Temporary solution, these 2 functions should be defined elsewhere, because similar operations are also needed elsewhere +//Final solution: the rtc should not depend on MSPI. We should do rtc related before Flash init +static void IRAM_ATTR enter_mspi_low_speed_mode_safe(void) { + portENTER_CRITICAL(&rtc_init_spinlock); + Cache_Freeze_ICache_Enable(1); + Cache_Freeze_DCache_Enable(1); + spi_timing_enter_mspi_low_speed_mode(false); + Cache_Freeze_DCache_Disable(); + Cache_Freeze_ICache_Disable(); + portEXIT_CRITICAL(&rtc_init_spinlock); +} + +static void IRAM_ATTR enter_mspi_high_speed_mode_safe(void) +{ + portENTER_CRITICAL(&rtc_init_spinlock); + Cache_Freeze_ICache_Enable(1); + Cache_Freeze_DCache_Enable(1); + spi_timing_enter_mspi_high_speed_mode(false); + Cache_Freeze_DCache_Disable(); + Cache_Freeze_ICache_Disable(); + portEXIT_CRITICAL(&rtc_init_spinlock); +} +#endif + +//TODO: IDF-3204 +//This function will change the system clock source to XTAL. Under lower frequency (e.g. XTAL), MSPI timing tuning configures should be modified accordingly. +static void IRAM_ATTR calibrate_ocode(void) +{ +#ifndef BOOTLOADER_BUILD + enter_mspi_low_speed_mode_safe(); +#endif /* Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL). Method: @@ -280,4 +326,7 @@ static void calibrate_ocode(void) } } rtc_clk_cpu_freq_set_config(&old_config); +#ifndef BOOTLOADER_BUILD + enter_mspi_high_speed_mode_safe(); +#endif } From 16a91399f1367b7a0e9ecded5c10ece172bbaeed Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 27 Sep 2021 10:41:07 +0800 Subject: [PATCH 5/5] psram: put opiram_psram and spiram_psram in internal ram External memory is accessed via SPI0. When modifying the SPI0 registers, should put the code in internal RAM. Otherwise when there is an ongoing SPI0 transaction, CPU changes the SPI0 registers. This is dangerous. Besides, modifying SPI0 registers may lead external memory to an unstable state. Therefore putting these code in internal RAM is necessary. --- components/esp_hw_support/linker.lf | 5 +++++ .../port/esp32s3/opiram_psram.c | 22 +++++++++---------- .../port/esp32s3/spiram_psram.c | 12 +++++----- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 9d3b3354b0..e8adfc884d 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -11,3 +11,8 @@ entries: rtc_time (noflash_text) if IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n: rtc_wdt (noflash_text) + if IDF_TARGET_ESP32S3 = y: + if SPIRAM_MODE_QUAD = y: + spiram_psram (noflash) + if SPIRAM_MODE_OCT = y: + opiram_psram (noflash) diff --git a/components/esp_hw_support/port/esp32s3/opiram_psram.c b/components/esp_hw_support/port/esp32s3/opiram_psram.c index e7a8396623..1d188b8f9e 100644 --- a/components/esp_hw_support/port/esp32s3/opiram_psram.c +++ b/components/esp_hw_support/port/esp32s3/opiram_psram.c @@ -99,10 +99,10 @@ typedef struct { } opi_psram_mode_reg_t; 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); +static psram_size_t s_psram_size; +static void s_config_psram_spi_phases(void); -uint8_t IRAM_ATTR psram_get_cs_io(void) +uint8_t psram_get_cs_io(void) { return OCT_PSRAM_CS1_IO; } @@ -110,7 +110,7 @@ uint8_t IRAM_ATTR psram_get_cs_io(void) /** * Initialise mode registers of the PSRAM */ -static void IRAM_ATTR s_init_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *mode_reg_config) +static void s_init_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *mode_reg_config) { esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; int cmd_len = 16; @@ -145,7 +145,7 @@ static void IRAM_ATTR s_init_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *m false); } -static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *out_reg) +static void s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *out_reg) { esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; int cmd_len = 16; @@ -192,7 +192,7 @@ static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *ou false); } -static void IRAM_ATTR s_print_psram_info(opi_psram_mode_reg_t *reg_val) +static void s_print_psram_info(opi_psram_mode_reg_t *reg_val) { ESP_EARLY_LOGI(TAG, "vendor id : 0x%02x (%s)", reg_val->mr1.vendor_id, reg_val->mr1.vendor_id == 0x0d ? "AP" : "UNKNOWN"); ESP_EARLY_LOGI(TAG, "dev id : 0x%02x (generation %d)", reg_val->mr2.dev_id, reg_val->mr2.dev_id + 1); @@ -215,7 +215,7 @@ static void IRAM_ATTR s_print_psram_info(opi_psram_mode_reg_t *reg_val) reg_val->mr0.drive_str == 0x02 ? 4 : 8); } -static void IRAM_ATTR psram_set_cs_timing(void) +static void psram_set_cs_timing(void) { //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for PSRAM, so we only need to set SPI0 related registers here SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M); @@ -225,7 +225,7 @@ static void IRAM_ATTR psram_set_cs_timing(void) SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V, OCT_PSRAM_CS_HOLD_DELAY, SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S); } -static void IRAM_ATTR s_init_psram_pins(void) +static void s_init_psram_pins(void) { //Set cs1 pin function PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], FUNC_SPICS1_SPICS1); @@ -235,7 +235,7 @@ static void IRAM_ATTR s_init_psram_pins(void) REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3); } -esp_err_t IRAM_ATTR 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) { s_init_psram_pins(); psram_set_cs_timing(); @@ -248,7 +248,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad esp_rom_spi_set_dtr_swap_mode(1, false, false); //Set PSRAM read latency and drive strength - static DRAM_ATTR opi_psram_mode_reg_t mode_reg = {0}; + static opi_psram_mode_reg_t mode_reg = {0}; mode_reg.mr0.lt = 1; mode_reg.mr0.read_latency = 2; mode_reg.mr0.drive_str = 0; @@ -279,7 +279,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad } //Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement -static void IRAM_ATTR s_config_psram_spi_phases(void) +static void s_config_psram_spi_phases(void) { //Config Write CMD phase for SPI0 to access PSRAM SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_CACHE_SRAM_USR_WCMD_M); diff --git a/components/esp_hw_support/port/esp32s3/spiram_psram.c b/components/esp_hw_support/port/esp32s3/spiram_psram.c index ecd10f08d9..6c243bf2ac 100644 --- a/components/esp_hw_support/port/esp32s3/spiram_psram.c +++ b/components/esp_hw_support/port/esp32s3/spiram_psram.c @@ -118,7 +118,7 @@ typedef enum { typedef esp_rom_spi_cmd_t psram_cmd_t; static uint32_t s_psram_id = 0; -static void IRAM_ATTR config_psram_spi_phases(void); +static void 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; @@ -278,7 +278,7 @@ static void psram_read_id(int spi_num, uint32_t* dev_id) } //enter QPI mode -static void IRAM_ATTR psram_enable_qio_mode(int spi_num) +static void psram_enable_qio_mode(int spi_num) { psram_exec_cmd(spi_num, PSRAM_CMD_SPI, PSRAM_ENTER_QMODE, 8, /* command and command bit len*/ @@ -290,7 +290,7 @@ static void IRAM_ATTR psram_enable_qio_mode(int spi_num) false); /* whether is program/erase operation */ } -static void IRAM_ATTR psram_set_cs_timing(void) +static void psram_set_cs_timing(void) { //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time registers for PSRAM, so we only need to set SPI0 related registers here SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, 0, SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S); @@ -298,7 +298,7 @@ static void IRAM_ATTR psram_set_cs_timing(void) SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M); } -static void IRAM_ATTR psram_gpio_config(void) +static void psram_gpio_config(void) { //CS1 uint8_t cs1_io = PSRAM_CS_IO; @@ -341,7 +341,7 @@ psram_size_t psram_get_size(void) * 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 +esp_err_t psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init { assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now."); @@ -383,7 +383,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad } //Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement -static void IRAM_ATTR config_psram_spi_phases(void) +static void config_psram_spi_phases(void) { //Config CMD phase CLEAR_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_USR_SRAM_DIO_M); //disable dio mode for cache command