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/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 e232ffb797..1d188b8f9e 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 @@ -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; @@ -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, @@ -191,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); @@ -224,7 +225,7 @@ static void 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); @@ -234,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(); @@ -244,12 +245,10 @@ 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}; + 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; @@ -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,13 +271,15 @@ 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; } //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/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 } diff --git a/components/esp_hw_support/port/esp32s3/spiram_psram.c b/components/esp_hw_support/port/esp32s3/spiram_psram.c index 1c36d0a74c..6c243bf2ac 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"; @@ -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*/ @@ -298,7 +298,7 @@ static void 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 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 f67361877e..7e3bf89985 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 @@ -2774,9 +2773,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 @@ -2817,7 +2814,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 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