mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 14:44:32 +02:00
Merge branch 'bugfix/fix_deep_sleep_crash_when_psram_high_freq' into 'master'
mspi: turn down freq to fix crash when sleep Closes IDF-6881 See merge request espressif/esp-idf!22491
This commit is contained in:
@@ -696,6 +696,30 @@ component_ut_pytest_esp32s3_flash_multi:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, flash_multi ]
|
||||
|
||||
component_ut_pytest_esp32s3_mspi_f4r4:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s3
|
||||
needs:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, MSPI_F4R4 ]
|
||||
|
||||
component_ut_pytest_esp32s3_mspi_f4r8:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s3
|
||||
needs:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, MSPI_F4R8 ]
|
||||
|
||||
component_ut_pytest_esp32s3_mspi_f8r8:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s3
|
||||
needs:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, MSPI_F8R8 ]
|
||||
|
||||
component_ut_pytest_esp32c2_generic:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
|
@@ -746,7 +746,7 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool bootloader_flash_is_octal_mode_enabled(void)
|
||||
bool IRAM_ATTR bootloader_flash_is_octal_mode_enabled(void)
|
||||
{
|
||||
#if SOC_SPI_MEM_SUPPORT_OPI_MODE
|
||||
return efuse_ll_get_flash_type();
|
||||
|
@@ -14,6 +14,10 @@ components/esp_hw_support/test_apps/etm:
|
||||
disable:
|
||||
- if: SOC_ETM_SUPPORTED != 1
|
||||
|
||||
components/esp_hw_support/test_apps/mspi:
|
||||
disable:
|
||||
- if: IDF_TARGET != "esp32s3"
|
||||
|
||||
components/esp_hw_support/test_apps/rtc_clk:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c6", "esp32h2"]
|
||||
@@ -25,6 +29,7 @@ components/esp_hw_support/test_apps/security_support/esp_hw_support_unity_tests:
|
||||
- if: IDF_TARGET in ["esp32h2"]
|
||||
temporary: true
|
||||
reason: H2 fails IDF-6898
|
||||
|
||||
components/heap/host_test/host_test_linux:
|
||||
enable:
|
||||
- if: IDF_TARGET == "linux"
|
||||
|
@@ -72,6 +72,7 @@
|
||||
#include "esp_private/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/rtc.h"
|
||||
#include "esp_private/mspi_timing_tuning.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
@@ -461,6 +462,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
|
||||
pd_flags &= ~RTC_SLEEP_PD_INT_8M;
|
||||
}
|
||||
|
||||
// Turn down mspi clock speed
|
||||
#if SOC_SPI_MEM_SUPPORT_TIME_TUNING
|
||||
mspi_timing_change_speed_mode_cache_safe(true);
|
||||
#endif
|
||||
|
||||
// Set mspi clock to a low-power one.
|
||||
#if SOC_MEMSPI_CLOCK_IS_INDEPENDENT
|
||||
spi_flash_set_clock_src(MSPI_CLK_SRC_ROM_DEFAULT);
|
||||
@@ -639,6 +645,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
|
||||
spi_flash_set_clock_src(MSPI_CLK_SRC_DEFAULT);
|
||||
#endif
|
||||
|
||||
// Speed up mspi clock freq
|
||||
#if SOC_SPI_MEM_SUPPORT_TIME_TUNING
|
||||
mspi_timing_change_speed_mode_cache_safe(false);
|
||||
#endif
|
||||
|
||||
if (!deep_sleep) {
|
||||
s_config.ccount_ticks_record = esp_cpu_get_cycle_count();
|
||||
misc_modules_wake_prepare();
|
||||
|
5
components/esp_hw_support/test_apps/mspi/CMakeLists.txt
Normal file
5
components/esp_hw_support/test_apps/mspi/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mspi_test_app)
|
10
components/esp_hw_support/test_apps/mspi/main/CMakeLists.txt
Normal file
10
components/esp_hw_support/test_apps/mspi/main/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
set(srcs
|
||||
"test_app_main.c"
|
||||
"test_flash_psram.c"
|
||||
"test_mspi.c"
|
||||
)
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRCS ${srcs}
|
||||
WHOLE_ARCHIVE)
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
// load partition table in tests will use memory
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (450)
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
|
||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("===================TEST MSPI=================\n");
|
||||
unity_run_menu();
|
||||
}
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -31,7 +32,7 @@
|
||||
#define LENGTH_PER_TIME 1024
|
||||
#endif
|
||||
|
||||
static esp_err_t spi0_psram_test(void)
|
||||
TEST_CASE("MSPI: Test_SPI0_PSRAM", "[mspi]")
|
||||
{
|
||||
printf("----------SPI0 PSRAM Test----------\n");
|
||||
|
||||
@@ -55,17 +56,14 @@ static esp_err_t spi0_psram_test(void)
|
||||
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;
|
||||
TEST_FAIL_MESSAGE("SPI0 PSRAM Test Fail");
|
||||
}
|
||||
}
|
||||
|
||||
free(psram_rd_buf);
|
||||
free(psram_wr_buf);
|
||||
printf(DRAM_STR("----------SPI0 PSRAM Test Success----------\n\n"));
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -76,8 +74,6 @@ static esp_err_t spi0_psram_test(void)
|
||||
#define SPI1_FLASH_TEST_NUM (SECTOR_LEN / SPI1_FLASH_TEST_LEN)
|
||||
#define SPI1_FLASH_TEST_ADDR 0x2a0000
|
||||
|
||||
extern void spi_flash_disable_interrupts_caches_and_other_cpu(void);
|
||||
extern void spi_flash_enable_interrupts_caches_and_other_cpu(void);
|
||||
static uint8_t rd_buf[SPI1_FLASH_TEST_LEN];
|
||||
static uint8_t wr_buf[SPI1_FLASH_TEST_LEN];
|
||||
|
||||
@@ -90,7 +86,7 @@ static const esp_partition_t *get_test_flash_partition(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
static NOINLINE_ATTR IRAM_ATTR esp_err_t spi1_flash_test(void)
|
||||
TEST_CASE("MSPI: Test_SPI1_Flash", "[mspi]")
|
||||
{
|
||||
printf(DRAM_STR("----------SPI1 Flash Test----------\n"));
|
||||
|
||||
@@ -114,16 +110,15 @@ static NOINLINE_ATTR IRAM_ATTR esp_err_t spi1_flash_test(void)
|
||||
printf(DRAM_STR("err: wr[%d]: 0x%02x -- rd[%d]: 0x%02x\n"), i, wr_buf[i], i, rd_buf[i]);
|
||||
}
|
||||
}
|
||||
return ESP_FAIL;
|
||||
TEST_FAIL_MESSAGE("SPI1 Flash Test 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, \
|
||||
@@ -133,8 +128,7 @@ static const uint8_t flash_rd_buf[SPI0_FLASH_TEST_LEN] = SPI0_FLASH_TEST_BUF;
|
||||
extern int _flash_rodata_start;
|
||||
extern int _rodata_reserved_end;
|
||||
|
||||
|
||||
static IRAM_ATTR esp_err_t spi0_flash_test(void)
|
||||
TEST_CASE("MSPI: Test_SPI0_Flash", "[mspi]")
|
||||
{
|
||||
printf("----------SPI0 Flash Test----------\n");
|
||||
//Check if the flash_rd_buf is in .rodata
|
||||
@@ -144,22 +138,8 @@ static IRAM_ATTR esp_err_t spi0_flash_test(void)
|
||||
|
||||
for (int i = 0; i < SPI0_FLASH_TEST_LEN; i++) {
|
||||
if (flash_rd_buf[i] != cmp_buf[i]) {
|
||||
return ESP_FAIL;
|
||||
TEST_FAIL_MESSAGE("SPI0 Flash Test 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");
|
||||
}
|
52
components/esp_hw_support/test_apps/mspi/main/test_mspi.c
Normal file
52
components/esp_hw_support/test_apps/mspi/main/test_mspi.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_private/mspi_timing_tuning.h"
|
||||
|
||||
|
||||
static void sorted_array_insert(uint32_t *array, uint32_t *size, uint32_t item)
|
||||
{
|
||||
uint32_t pos;
|
||||
for (pos = *size; pos > 0; pos--) {
|
||||
if (array[pos - 1] <= item) {
|
||||
break;
|
||||
}
|
||||
array[pos] = array[pos - 1];
|
||||
}
|
||||
array[pos] = item;
|
||||
(*size)++;
|
||||
}
|
||||
|
||||
#define TEST_TIME_CNT 10
|
||||
#define TEST_TIME_LIMIT_US 10
|
||||
TEST_CASE("MSPI: Test mspi timing turning time cost", "[mspi]")
|
||||
{
|
||||
uint64_t start, end;
|
||||
uint32_t cost, index_1 = 0, index_2 = 0;
|
||||
uint32_t slow_down_time[TEST_TIME_CNT], speed_up_time[TEST_TIME_CNT];
|
||||
|
||||
printf("\nFunc call `mspi_timing_change_speed_mode_cache_safe` should spend time less than %d us\n", TEST_TIME_LIMIT_US);
|
||||
for (uint8_t i = 0; i < TEST_TIME_CNT; i++) {
|
||||
start = esp_timer_get_time();
|
||||
mspi_timing_change_speed_mode_cache_safe(true);
|
||||
end = esp_timer_get_time();
|
||||
cost = end - start;
|
||||
sorted_array_insert(slow_down_time, &index_1, cost);
|
||||
printf("mspi psram slow down cost %ld\t", cost);
|
||||
|
||||
start = esp_timer_get_time();
|
||||
mspi_timing_change_speed_mode_cache_safe(false);
|
||||
end = esp_timer_get_time();
|
||||
cost = end - start;
|
||||
sorted_array_insert(speed_up_time, &index_2, cost);
|
||||
printf("mspi psram speed up cost %ld\n", cost);
|
||||
}
|
||||
|
||||
TEST_ASSERT_LESS_THAN_UINT32(TEST_TIME_LIMIT_US, slow_down_time[TEST_TIME_CNT / 2]);
|
||||
TEST_ASSERT_LESS_THAN_UINT32(TEST_TIME_LIMIT_US, speed_up_time[TEST_TIME_CNT / 2]);
|
||||
}
|
@@ -1,11 +1,11 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf import IdfDut
|
||||
|
||||
MSPI_F8R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f8r8*')]
|
||||
|
||||
@@ -13,8 +13,8 @@ MSPI_F8R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(o
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.MSPI_F8R8
|
||||
@pytest.mark.parametrize('config', MSPI_F8R8_configs, indirect=True)
|
||||
def test_flash8_psram8(dut: Dut) -> None:
|
||||
dut.expect_exact('flash psram test success')
|
||||
def test_flash8_psram8(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
# For F4R8 board (Quad Flash and Octal PSRAM)
|
||||
@@ -24,8 +24,8 @@ MSPI_F4R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(o
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.MSPI_F4R8
|
||||
@pytest.mark.parametrize('config', MSPI_F4R8_configs, indirect=True)
|
||||
def test_flash4_psram8(dut: Dut) -> None:
|
||||
dut.expect_exact('flash psram test success')
|
||||
def test_flash4_psram8(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
# For F4R4 board (Quad Flash and Quad PSRAM)
|
||||
@@ -35,5 +35,5 @@ MSPI_F4R4_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(o
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.MSPI_F4R4
|
||||
@pytest.mark.parametrize('config', MSPI_F4R4_configs, indirect=True)
|
||||
def test_flash4_psram4(dut: Dut) -> None:
|
||||
dut.expect_exact('flash psram test success', timeout=40)
|
||||
def test_flash4_psram4(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases()
|
@@ -0,0 +1,5 @@
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
|
||||
CONFIG_SPIRAM_RODATA=y
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
@@ -1,6 +0,0 @@
|
||||
# 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.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(test_flash_psram)
|
@@ -1,2 +0,0 @@
|
||||
idf_component_register(SRCS "test_flash_psram.c"
|
||||
INCLUDE_DIRS ".")
|
@@ -1,2 +0,0 @@
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_IDF_TARGET_ESP32S3=y
|
Reference in New Issue
Block a user