ci(phy): add test_phy case for esp32h2

This commit is contained in:
Tan Yan Quan
2025-07-01 19:18:06 +08:00
parent 62e09ad60f
commit 91827686ac
18 changed files with 254 additions and 140 deletions
+6 -2
View File
@@ -22,6 +22,9 @@ if(CONFIG_ESP_PHY_ENABLED)
else()
set(link_binary_libs 1)
set(ldfragments "linker.lf")
if(CONFIG_ESP_PHY_INIT_IRAM)
list(APPEND ldfragments "linker_esp32hxx.lf")
endif()
endif()
if(CONFIG_SOC_IEEE802154_BLE_ONLY)
@@ -140,8 +143,9 @@ if(CONFIG_ESP_PHY_ENABLED)
list(APPEND libs_to_link esp_phy_libphy)
endif()
# Finally, link the libraries to the component
target_link_libraries(${COMPONENT_LIB} INTERFACE ${libs_to_link})
# Finally, link the libraries to the component.
# PUBLIC is required for linker.lf fragment mappings (e.g. IRAM placement) to work.
target_link_libraries(${COMPONENT_LIB} PUBLIC ${libs_to_link})
endif()
if(CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION)
+14
View File
@@ -207,5 +207,19 @@ menu "PHY"
PLL track helps the PHY module adapt to temperature changes, ensuring stable performance.
When pll enabled, the ESP PHY module will periodically track and adjust PLL parameters.
config ESP_PHY_INIT_IRAM
bool "Place PHY (de)init in IRAM"
depends on SOC_IEEE802154_BLE_ONLY
default n
help
Select this option to place esp_phy and PHY library functions related to phy_init in IRAM.
This config applies to ESP32-H2, ESP32-H21, and ESP32-H4.
config ESP_PHY_ENABLE_VERSION_PRINT
bool "Print PHY version"
default y
help
Select to print PHY version in esp_phy_enable. This config only applies to esp32hxx for now.
endif
endmenu # PHY
+91
View File
@@ -0,0 +1,91 @@
# Linker fragment for ESP32-Hxx (H2/H21/H4) specific PHY IRAM placement
# These entries are used when CONFIG_ESP_PHY_INIT_IRAM is enabled
[mapping:phy_hxx]
archive: libphy.a
entries:
if ESP_PHY_INIT_IRAM = y:
# esp_phy_disable (basically phy_close_rf)
phy_init:phy_close_rf (noflash)
phy_tsens:tsens_temp_read (noflash)
phy_hw_freq:get_freq_mem_param (noflash)
phy_hw_freq:get_freq_mem_addr (noflash)
phy_basic:enter_critical_phy (noflash)
phy_hw_freq:phy_dis_hw_set_freq (noflash)
phy_hw_freq:wait_freq_set_busy (noflash)
phy_hw_freq:read_rf_freq_mem_new (noflash)
phy_init:phy_xpd_rf (noflash)
phy_pbus:pbus_debugmode (noflash)
phy_pbus:pbus_force_mode (noflash)
phy_basic:exit_critical_phy (noflash)
phy_api:phy_xpd_tsens (noflash)
phy_pbus:pbus_xpd_tx_off (noflash)
phy_reg:phy_bbpll_cal (noflash)
phy_reg:phy_modem_lo_clk (noflash)
phy_pbus:pbus_force_test (noflash)
phy_pbus:pbus_workmode (noflash)
# esp_phy_enable (basically phy_wakeup_init)
phy_init:phy_wakeup_init (noflash)
phy_tsens:tsens_read_init (noflash)
phy_hw_freq:phy_chan_hw_init (noflash)
phy_hw_freq:freq_reg_init (noflash)
phy_rfpll:chan_to_freq (noflash)
phy_hw_freq:freq_i2c_data_write (noflash)
phy_hw_freq:freq_get_i2c_data (noflash)
phy_hw_freq:freq_i2c_write_set_new (noflash)
phy_hw_freq:freq_i2c_num_addr (noflash)
phy_hw_freq:freq_num_get_data (noflash)
phy_reg:open_i2c_xpd (noflash)
phy_i2c:i2c_clk_sel (noflash)
phy_basic:i2c_master_reset (noflash)
phy_reg:set_pbus_reg (noflash)
phy_i2c:phy_i2c_init1 (noflash)
phy_i2c:i2c_paral_write_num (noflash)
phy_i2c:i2c_paral_write (noflash)
phy_i2c:chip_i2c_readReg (noflash)
phy_i2c:get_i2c_read_mask (noflash)
phy_i2c:get_i2c_hostid (noflash)
phy_i2c:chip_i2c_readReg_org (noflash)
phy_i2c:i2c_sar2_init_code (noflash)
phy_i2c:i2c_writeReg_Mask (noflash)
phy_i2c:chip_i2c_writeReg (noflash)
phy_hw_freq:write_chan_freq (noflash)
phy_hw_freq:freq_chan_en_sw (noflash)
phy_reg:fe_reg_init (noflash)
phy_reg:adc_cal_set (noflash)
phy_reg:logain_reg_init (noflash)
phy_init:phy_reg_init (noflash)
phy_reg:iq_corr_enable (noflash)
phy_reg:agc_reg_init (noflash)
phy_reg:phy_ant_init (noflash)
phy_reg:bt_filter_reg (noflash)
phy_hw_freq:phy_en_hw_set_freq (noflash)
[mapping:esp_phy_hxx]
archive: libesp_phy.a
entries:
if ESP_PHY_INIT_IRAM = y:
phy_init_esp32hxx:esp_phy_enable (noflash)
phy_init_esp32hxx:esp_phy_disable (noflash)
phy_common:phy_clr_modem_flag (noflash)
phy_common:phy_get_modem_flag (noflash)
phy_common:phy_set_modem_flag (noflash)
phy_common:phy_track_pll_deinit (noflash)
phy_common:phy_track_pll_init (noflash)
phy_common:phy_track_pll (noflash)
phy_common:phy_enabled_modem_contains (noflash)
[mapping:phy_hal_hxx]
archive: libesp_hal_ana_conv.a
entries:
if ESP_PHY_INIT_IRAM = y:
temperature_sensor_hal:temperature_sensor_hal_get_degree (noflash)
temperature_sensor_hal:temperature_sensor_hal_init (noflash)
temperature_sensor_hal:temperature_sensor_ll_set_range (noflash)
[mapping:esp_timer_hxx]
archive: libesp_timer.a
entries:
if ESP_PHY_INIT_IRAM = y:
esp_timer:esp_timer_create (noflash)
esp_timer:esp_timer_delete (noflash)
+2 -2
View File
@@ -21,8 +21,6 @@
#define PHY_INIT_MODEM_CLOCK_REQUIRED_BITS 0
#endif
#define PHY_ENABLE_VERSION_PRINT 1
static DRAM_ATTR portMUX_TYPE s_phy_int_mux = portMUX_INITIALIZER_UNLOCKED;
extern void phy_version_print(void);
@@ -117,7 +115,9 @@ void esp_phy_enable(esp_phy_modem_t modem)
assert(phy_module_has_clock_bits(PHY_INIT_MODEM_CLOCK_REQUIRED_BITS));
if (!s_phy_is_enabled) {
register_chipv7_phy(NULL, NULL, PHY_RF_CAL_FULL);
#if CONFIG_ESP_PHY_ENABLE_VERSION_PRINT
phy_version_print();
#endif
s_phy_is_enabled = true;
} else {
phy_wakeup_init();
-4
View File
@@ -1,4 +0,0 @@
idf_component_register(SRC_DIRS .
PRIV_INCLUDE_DIRS . ${CMAKE_CURRENT_BINARY_DIR}
PRIV_REQUIRES cmock test_utils nvs_flash ulp esp_common esp_phy esp_wifi
)
-131
View File
@@ -1,131 +0,0 @@
/*
Tests for the Wi-Fi
*/
#include "string.h"
#include "esp_system.h"
#include "unity.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "test_utils.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
#include "soc/soc_caps.h"
#include "esp_private/esp_modem_clock.h"
#include "esp_private/wifi.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
//IDF-5046
#include "esp_phy_init.h"
//Function just extern, need not test
#if SOC_BT_SUPPORTED
extern void bt_bb_init_cmplx(void);
#endif
extern void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void);
extern void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void);
//Functions in librtc.a called by WIFI or Blutooth directly in ISR
#if SOC_BT_SUPPORTED
extern void bt_track_pll_cap(void);
#endif
static const char* TAG = "test_phy_rtc";
static SemaphoreHandle_t semphr_done;
//Functions in libphy.a called by WIFI or Blutooth directly in ISR
static void test_phy_rtc_init(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGI(TAG, "no free pages or nvs version mismatch, erase..");
TEST_ESP_OK(nvs_flash_erase());
ret = nvs_flash_init();
}
TEST_ESP_OK(ret);
#if CONFIG_ESP_WIFI_ENABLED
esp_phy_enable(PHY_MODEM_WIFI);
#endif
#if CONFIG_BT_ENABLED
esp_phy_enable(PHY_MODEM_BT);
#endif
#if CONFIG_IEEE802154_ENABLED
esp_phy_enable(PHY_MODEM_IEEE802154);
#endif
//must run here, not blocking in above code
TEST_ASSERT(1);
nvs_flash_deinit();
}
static IRAM_ATTR void test_phy_rtc_cache_task(void *arg)
{
//power up wifi and bt mac bb power domain
esp_wifi_power_domain_on();
#if CONFIG_IDF_TARGET_ESP32C6
modem_clock_module_enable(PERIPH_PHY_MODULE);
#endif // CONFIG_IDF_TARGET_ESP32C6
test_phy_rtc_init();
#if CONFIG_IDF_TARGET_ESP32
extern void force_wifi_mode(int);
extern void unforce_wifi_mode(void);
for (int i = 0; i < 2; i++) {
ESP_LOGI(TAG, "Test force_wifi_mode(%d)...", i);
spi_flash_disable_interrupts_caches_and_other_cpu();
force_wifi_mode(i);
spi_flash_enable_interrupts_caches_and_other_cpu();
ESP_LOGI(TAG, "Test unforce_wifi_mode()...");
spi_flash_disable_interrupts_caches_and_other_cpu();
unforce_wifi_mode();
spi_flash_enable_interrupts_caches_and_other_cpu();
}
#endif //CONFIG_IDF_TARGET_ESP32
#if SOC_BT_SUPPORTED
#if CONFIG_IDF_TARGET_ESP32
/* Only esp32 will call bt_track_pll_cap() in the interrupt
handler, other chips will call this function in the task
*/
ESP_LOGI(TAG, "Test bt_track_pll_cap()...");
spi_flash_disable_interrupts_caches_and_other_cpu();
bt_track_pll_cap();
spi_flash_enable_interrupts_caches_and_other_cpu();
extern void bt_bb_init_cmplx_reg(void);
ESP_LOGI(TAG, "Test bt_bb_init_cmplx_reg()...");
spi_flash_disable_interrupts_caches_and_other_cpu();
bt_bb_init_cmplx_reg();
spi_flash_enable_interrupts_caches_and_other_cpu();
#endif //CONFIG_IDF_TARGET_ESP32
#endif //SOC_BT_SUPPORTED
#if CONFIG_IDF_TARGET_ESP32C6
modem_clock_module_disable(PERIPH_PHY_MODULE);
#endif // CONFIG_IDF_TARGET_ESP32C6
//power down wifi and bt mac bb power domain
esp_wifi_power_domain_off();
TEST_ASSERT( xSemaphoreGive(semphr_done) );
vTaskDelete(NULL);
}
TEST_CASE("Test PHY/RTC functions called when cache is disabled", "[phy_rtc][cache_disabled]")
{
semphr_done = xSemaphoreCreateCounting(1, 0);
xTaskCreatePinnedToCore(test_phy_rtc_cache_task, "phy_rtc_test_task", 3072,
NULL, configMAX_PRIORITIES-1, NULL, 0);
TEST_ASSERT( xSemaphoreTake(semphr_done, portMAX_DELAY) );
vSemaphoreDelete(semphr_done);
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6)
@@ -1,5 +1,18 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/esp_phy/test_apps/phy_iram:
enable:
- if: SOC_IEEE802154_BLE_ONLY == 1
disable:
- if: IDF_TARGET not in ["esp32h2"]
temporary: true
reason: not supported for esp32h21 and esp32h4 yet
depends_components:
- esp_phy
- esp_pm
- esp_timer
- spi_flash
- nvs_flash
components/esp_phy/test_apps/phy_multiple_init_data:
disable:
- if: IDF_TARGET == "esp32p4" # Update with caps here when IDF-7460 is resolved
@@ -0,0 +1,7 @@
#This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.22)
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_phy_iram)
@@ -0,0 +1,4 @@
| Supported Targets | ESP32-H2 |
| ----------------- | -------- |
This project tests whether esp_phy_enable and esp_phy_disable can be fully placed in IRAM for the ESP32-H2.
@@ -0,0 +1,7 @@
set(srcs "test_app_main.c"
"test_phy.c")
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "."
PRIV_REQUIRES unity nvs_flash esp_phy ieee802154
WHOLE_ARCHIVE)
@@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "unity.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void app_main(void)
{
vTaskPrioritySet(NULL, 5);
unity_run_menu();
}
@@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_system.h"
#include "unity.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
#include "esp_phy_init.h"
extern void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os(void);
extern void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void);
static const char* TAG = "test_phy_iram";
static SemaphoreHandle_t semphr_done;
//Functions in libphy.a called by WIFI or Bluetooth directly in ISR
static void test_phy_rtc_init(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGI(TAG, "no free pages or nvs version mismatch, erase..");
TEST_ESP_OK(nvs_flash_erase());
ret = nvs_flash_init();
}
TEST_ESP_OK(ret);
#if CONFIG_IEEE802154_ENABLED
esp_phy_enable(PHY_MODEM_IEEE802154);
#endif
//must run here, not blocking in above code
TEST_ASSERT(1);
nvs_flash_deinit();
}
static IRAM_ATTR void test_phy_rtc_cache_task(void *arg)
{
test_phy_rtc_init();
#if CONFIG_IDF_TARGET_ESP32H2
/* Check if esp_phy_enable is fully placed in IRAM,
requires CONFIG_ESP_PHY_ENABLE_VERSION_PRINT to be disabled.
Do not suspend OS scheduler because of _lock_acquire.
*/
spi_flash_disable_interrupts_caches_and_other_cpu_no_os();
esp_phy_disable(PHY_MODEM_IEEE802154);
esp_phy_enable(PHY_MODEM_IEEE802154);
spi_flash_enable_interrupts_caches_no_os();
#endif
TEST_ASSERT( xSemaphoreGive(semphr_done) );
vTaskDelete(NULL);
}
TEST_CASE("Test PHY enable/disable functions with cache disabled", "[phy_iram][cache_disabled]")
{
semphr_done = xSemaphoreCreateCounting(1, 0);
xTaskCreatePinnedToCore(test_phy_rtc_cache_task, "phy_rtc_test_task", 3072,
NULL, configMAX_PRIORITIES-1, NULL, 0);
TEST_ASSERT( xSemaphoreTake(semphr_done, portMAX_DELAY) );
vSemaphoreDelete(semphr_done);
}
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.generic
@pytest.mark.eco5
@idf_parametrize('target', ['esp32h2'], indirect=['target'])
def test_phy(dut: Dut) -> None:
dut.run_all_single_board_cases()
@@ -0,0 +1,7 @@
CONFIG_ESP_PHY_ENABLE_VERSION_PRINT=n
CONFIG_ESP_PHY_INIT_IRAM=y
CONFIG_ESP_TIMER_IN_IRAM=y
CONFIG_FREERTOS_IN_IRAM=y
CONFIG_PM_SLP_IRAM_OPT=y
CONFIG_ESP_TASK_WDT_INIT=n
+3
View File
@@ -42,6 +42,9 @@ entries:
systimer (noflash)
if IDF_TARGET_ESP32H21 != y && IDF_TARGET_ESP32H4 != y:
sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash)
sar_periph_ctrl:adc_reset_lock_acquire (noflash)
sar_periph_ctrl:adc_reset_lock_release (noflash)
sar_periph_ctrl:sar_periph_ctrl_adc_reset (noflash)
if SOC_TEMP_SENSOR_SUPPORTED = y:
sar_tsens_ctrl:temperature_sensor_power_acquire (noflash)
sar_tsens_ctrl:temperature_sensor_power_release (noflash)
+1
View File
@@ -135,3 +135,4 @@ env_markers =
rev_default: Runner with default revision connected
flash_32m: Runner with 32MB flash
eco4: Runner with SOC chip that is exactly with the ECO4 version
eco5: Runner with esp32h2 eco5 connected
-1
View File
@@ -379,7 +379,6 @@ components/esp_hid/private/bt_hidd.h
components/esp_hid/private/bt_hidh.h
components/esp_local_ctrl/src/esp_local_ctrl_priv.h
components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c
components/esp_phy/test/test_phy_rtc.c
components/esp_rom/esp32/include/esp32/rom/tjpgd.h
components/esp_rom/esp32/ld/esp32.rom.api.ld
components/esp_rom/esp32/ld/esp32.rom.eco3.ld
+1
View File
@@ -32,4 +32,5 @@ ECO_MARKERS = [
'esp32p4_eco4',
'esp32c5_eco3',
'eco4',
'eco5',
]