From 2fb26b0083d5e61d91e05ea41dde7ac5501b4e6a Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Wed, 9 Sep 2026 10:41:53 +0800 Subject: [PATCH 1/3] feat(test_app): add test app for multiple phy init data --- components/esp_phy/include/esp_private/phy.h | 10 + components/esp_phy/src/phy_init.c | 5 + tools/test_apps/phy/.build-test-rules.yml | 3 - .../phy/phy_multi_init_data_test/README.md | 27 ++ .../main/CMakeLists.txt | 9 +- .../main/phy_init_data_main.c | 56 +--- .../main/test_phy_multiple_init_data.c | 253 ++++++++++++++++++ .../pytest_phy_multi_init_data.py | 19 +- .../sdkconfig.defaults | 2 + 9 files changed, 328 insertions(+), 56 deletions(-) create mode 100644 tools/test_apps/phy/phy_multi_init_data_test/main/test_phy_multiple_init_data.c create mode 100644 tools/test_apps/phy/phy_multi_init_data_test/sdkconfig.defaults diff --git a/components/esp_phy/include/esp_private/phy.h b/components/esp_phy/include/esp_private/phy.h index de9a9820227..ed9a51f737d 100644 --- a/components/esp_phy/include/esp_private/phy.h +++ b/components/esp_phy/include/esp_private/phy.h @@ -283,6 +283,16 @@ void phy_wait_freq_hw_hop_done(void); void phy_track_temp_debug(uint8_t debug_flag, uint8_t track_temp); #endif +#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN +/** + * @brief Get the PHY init data type that is currently applied to the PHY + * + * @return the applied init data type, ESP_PHY_INIT_DATA_TYPE_DEFAULT as long as no + * certified init data has been selected by a country code + */ +phy_init_data_type_t esp_phy_get_init_data_type(void); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index dc2dbf0dccf..0c8ef30e6e3 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -1208,6 +1208,11 @@ esp_err_t esp_phy_update_init_data(phy_init_data_type_t init_data_type) free(init_data_store); return ESP_OK; } + +phy_init_data_type_t esp_phy_get_init_data_type(void) +{ + return s_current_apply_phy_init_data; +} #endif esp_err_t esp_phy_update_country_info(const char *country) diff --git a/tools/test_apps/phy/.build-test-rules.yml b/tools/test_apps/phy/.build-test-rules.yml index 2cd352547c5..02dc9884fef 100644 --- a/tools/test_apps/phy/.build-test-rules.yml +++ b/tools/test_apps/phy/.build-test-rules.yml @@ -3,9 +3,6 @@ tools/test_apps/phy/phy_multi_init_data_test: disable: - if: SOC_WIFI_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET in ["esp32c5", "esp32c61"] - reason: lack of runner tools/test_apps/phy/phy_tsens: disable: diff --git a/tools/test_apps/phy/phy_multi_init_data_test/README.md b/tools/test_apps/phy/phy_multi_init_data_test/README.md index 1c350929488..b389aa10e6f 100644 --- a/tools/test_apps/phy/phy_multi_init_data_test/README.md +++ b/tools/test_apps/phy/phy_multi_init_data_test/README.md @@ -1,2 +1,29 @@ | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | + +This project tests the multiple PHY init data bin support, i.e. `CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN`. + +The tests cover: + +- the layout, the checksums and the certified init data types of `phy_multiple_init_data.bin` +- loading the bin through `esp_phy_get_init_data()` +- switching the PHY init data type from a country code, both through `esp_phy_update_country_info()` + and through `esp_wifi_set_country_code()` +- the fallback to the default init data for countries without a certified init data + +Two configurations are tested: + +| Config | Where the bin lives | +| ---------------------------------- | ------------------------------------------------------------------------ | +| `phy_multiple_init_data` | flashed into the `phy` data partition | +| `phy_multiple_init_data_embed` | embedded into the application binary (`..._MULTIPLE_INIT_DATA_BIN_EMBED`) | + +Which of the two paths was taken is only observable in the log, so `app_main` loads the bin +once before starting the unity runner. + +Run the tests with: + +```bash +idf.py set-target +idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.ci.phy_multiple_init_data" build flash monitor +``` diff --git a/tools/test_apps/phy/phy_multi_init_data_test/main/CMakeLists.txt b/tools/test_apps/phy/phy_multi_init_data_test/main/CMakeLists.txt index ebe797b1c5e..59d35d9aca7 100644 --- a/tools/test_apps/phy/phy_multi_init_data_test/main/CMakeLists.txt +++ b/tools/test_apps/phy/phy_multi_init_data_test/main/CMakeLists.txt @@ -1,2 +1,7 @@ -idf_component_register(SRCS "phy_init_data_main.c" - INCLUDE_DIRS ".") +set(srcs "phy_init_data_main.c" + "test_phy_multiple_init_data.c") + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "." + PRIV_REQUIRES unity esp_phy esp_wifi esp_event nvs_flash esp_partition + WHOLE_ARCHIVE) diff --git a/tools/test_apps/phy/phy_multi_init_data_test/main/phy_init_data_main.c b/tools/test_apps/phy/phy_multi_init_data_test/main/phy_init_data_main.c index 8c9953b1d31..2c99a0b74ee 100644 --- a/tools/test_apps/phy/phy_multi_init_data_test/main/phy_init_data_main.c +++ b/tools/test_apps/phy/phy_multi_init_data_test/main/phy_init_data_main.c @@ -1,55 +1,21 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -/* test phy init data bin options - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event.h" -#include "esp_log.h" -#include "nvs_flash.h" - -static const char *TAG = "phy init"; -static EventGroupHandle_t s_wifi_event_group; - -void wifi_init(void) -{ - s_wifi_event_group = xEventGroupCreate(); - - ESP_ERROR_CHECK(esp_netif_init()); - - ESP_ERROR_CHECK(esp_event_loop_create_default()); - esp_netif_create_default_wifi_sta(); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init finished."); -} +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_phy_init.h" void app_main(void) { - //Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); + /* Whether the bin comes from the phy partition or from the application binary is + only observable in the log emitted while it is loaded, so trigger the load once + here to keep that visible in the boot output. */ + const esp_phy_init_data_t *init_data = esp_phy_get_init_data(); + if (init_data != NULL) { + esp_phy_release_init_data(init_data); } - ESP_ERROR_CHECK(ret); - wifi_init(); + unity_run_menu(); } diff --git a/tools/test_apps/phy/phy_multi_init_data_test/main/test_phy_multiple_init_data.c b/tools/test_apps/phy/phy_multi_init_data_test/main/test_phy_multiple_init_data.c new file mode 100644 index 00000000000..2fd99213d97 --- /dev/null +++ b/tools/test_apps/phy/phy_multi_init_data_test/main/test_phy_multiple_init_data.c @@ -0,0 +1,253 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" +#include "esp_err.h" +#include "esp_event.h" +#include "esp_phy_init.h" +#include "esp_private/phy.h" +#include "esp_rom_crc.h" +#include "esp_wifi.h" +#include "nvs_flash.h" +#include "phy_init_data.h" +#include "sdkconfig.h" + +/* esp_phy_get_init_data_type() only exists with this option on, and the whole point of + these cases is the multiple bin, so a build without it simply carries no test case. */ +#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN + +#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN_EMBED +extern const uint8_t multi_phy_init_data_bin_start[] asm("_binary_phy_multiple_init_data_bin_start"); +extern const uint8_t multi_phy_init_data_bin_end[] asm("_binary_phy_multiple_init_data_bin_end"); +#else +#include "esp_partition.h" +#endif + +/* phy_multiple_init_data.bin layout: + * [magic][default init data][magic][control info][certified init data] * number + */ +#define PHY_INIT_DATA_LEN (sizeof(esp_phy_init_data_t)) +#define CONTROL_INFO_OFFSET (PHY_INIT_MAGIC_LEN + PHY_INIT_DATA_LEN + PHY_INIT_MAGIC_LEN) +#define MULTIPLE_DATA_OFFSET (CONTROL_INFO_OFFSET + sizeof(phy_control_info_data_t)) + +static uint8_t *multiple_init_data_load(size_t *out_len) +{ + uint8_t *blob = NULL; + size_t len = 0; + +#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN_EMBED + len = (size_t)(multi_phy_init_data_bin_end - multi_phy_init_data_bin_start); + blob = malloc(len); + TEST_ASSERT_NOT_NULL(blob); + memcpy(blob, multi_phy_init_data_bin_start, len); +#else + const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_DATA_PHY, NULL); + TEST_ASSERT_NOT_NULL_MESSAGE(partition, "no phy data partition in the partition table"); + len = partition->size; + blob = malloc(len); + TEST_ASSERT_NOT_NULL(blob); + TEST_ESP_OK(esp_partition_read(partition, 0, blob, len)); +#endif + + *out_len = len; + return blob; +} + +/* The checksums in the bin are stored big-endian, see phy_crc_check_init_data() */ +static bool crc32_matches(const uint8_t *data, size_t len, const uint8_t *expected) +{ + uint32_t crc = esp_rom_crc32_le(0, data, len); + const uint8_t crc_be[4] = { crc >> 24, crc >> 16, crc >> 8, crc }; + + return memcmp(crc_be, expected, sizeof(crc_be)) == 0; +} + +static void control_info_get(const uint8_t *blob, phy_control_info_data_t *out_info) +{ + memcpy(out_info, blob + CONTROL_INFO_OFFSET, sizeof(*out_info)); +} + +static void wifi_start(void) +{ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + TEST_ESP_OK(nvs_flash_erase()); + err = nvs_flash_init(); + } + TEST_ESP_OK(err); + + TEST_ESP_OK(esp_event_loop_create_default()); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + TEST_ESP_OK(esp_wifi_init(&cfg)); + TEST_ESP_OK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA)); + TEST_ESP_OK(esp_wifi_start()); +} + +static void wifi_stop(void) +{ + TEST_ESP_OK(esp_wifi_stop()); + TEST_ESP_OK(esp_wifi_deinit()); + TEST_ESP_OK(esp_event_loop_delete_default()); + TEST_ESP_OK(nvs_flash_deinit()); +} + +TEST_CASE("multiple PHY init data bin matches the PHY init data of this target", "[phy_multiple_init_data]") +{ + size_t blob_len = 0; + uint8_t *blob = multiple_init_data_load(&blob_len); + TEST_ASSERT_GREATER_OR_EQUAL_UINT32(MULTIPLE_DATA_OFFSET, blob_len); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(PHY_INIT_MAGIC, blob, PHY_INIT_MAGIC_LEN, "leading magic"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(PHY_INIT_MAGIC, blob + CONTROL_INFO_OFFSET - PHY_INIT_MAGIC_LEN, + PHY_INIT_MAGIC_LEN, "trailing magic"); + /* Without this flag esp_phy_update_country_info() rejects every country code */ + TEST_ASSERT_NOT_EQUAL_MESSAGE(0, blob[PHY_INIT_MAGIC_LEN + PHY_SUPPORT_MULTIPLE_BIN_OFFSET], + "bin is not marked as supporting multiple init data"); + + phy_control_info_data_t info; + control_info_get(blob, &info); + TEST_ASSERT_EQUAL(PHY_CRC_ALGORITHM, info.check_algorithm); + TEST_ASSERT_GREATER_THAN(0, info.number); + /* Big-endian per-entry length, a mismatch means the bin was built for another PHY */ + TEST_ASSERT_EQUAL_MESSAGE(PHY_INIT_DATA_LEN, ((uint16_t)info.length[0] << 8) | info.length[1], + "per-entry length differs from sizeof(esp_phy_init_data_t)"); + + TEST_ASSERT_TRUE_MESSAGE(crc32_matches(info.multiple_bin_checksum, + sizeof(info) - sizeof(info.control_info_checksum), + info.control_info_checksum), + "control info checksum mismatch"); + + size_t multiple_data_len = PHY_INIT_DATA_LEN * info.number; + TEST_ASSERT_GREATER_OR_EQUAL_UINT32(MULTIPLE_DATA_OFFSET + multiple_data_len, blob_len); + TEST_ASSERT_TRUE_MESSAGE(crc32_matches(blob + MULTIPLE_DATA_OFFSET, multiple_data_len, + info.multiple_bin_checksum), + "certified init data checksum mismatch"); + + free(blob); +} + +TEST_CASE("certified PHY init data types are known and unique", "[phy_multiple_init_data]") +{ + size_t blob_len = 0; + uint8_t *blob = multiple_init_data_load(&blob_len); + phy_control_info_data_t info; + control_info_get(blob, &info); + + /* A bin may carry certifications that phy_init_data_type_t does not name yet, + so the type byte is only bounded by its own width */ + bool seen[256] = { false }; + unsigned unnamed = 0; + for (uint8_t i = 0; i < info.number; i++) { + uint8_t type = blob[MULTIPLE_DATA_OFFSET + i * PHY_INIT_DATA_LEN + PHY_INIT_DATA_TYPE_OFFSET]; + /* The DEFAULT type is the block in front of the control info, not a certified entry */ + TEST_ASSERT_NOT_EQUAL(ESP_PHY_INIT_DATA_TYPE_DEFAULT, type); + TEST_ASSERT_FALSE_MESSAGE(seen[type], "duplicated init data type"); + seen[type] = true; + if (type >= ESP_PHY_INIT_DATA_TYPE_NUMBER) { + unnamed++; + } + } + printf("%u certified entries, %u of them unnamed by phy_init_data_type_t\n", info.number, unnamed); + + /* The country codes exercised by this app have to be certified in the bin */ + static const phy_init_data_type_t required[] = { + ESP_PHY_INIT_DATA_TYPE_SRRC, + ESP_PHY_INIT_DATA_TYPE_FCC, + ESP_PHY_INIT_DATA_TYPE_CE, + ESP_PHY_INIT_DATA_TYPE_NCC, + ESP_PHY_INIT_DATA_TYPE_KCC, + ESP_PHY_INIT_DATA_TYPE_MIC, + }; + for (size_t i = 0; i < sizeof(required) / sizeof(required[0]); i++) { + TEST_ASSERT_TRUE_MESSAGE(seen[required[i]], "a country code tested below is not certified"); + } + + free(blob); +} + +TEST_CASE("esp_phy_get_init_data loads the multiple PHY init data bin", "[phy_multiple_init_data]") +{ + const esp_phy_init_data_t *init_data = esp_phy_get_init_data(); + TEST_ASSERT_NOT_NULL(init_data); + esp_phy_release_init_data(init_data); +} + +TEST_CASE("country code selects the certified PHY init data", "[phy_multiple_init_data]") +{ + static const struct { + const char *country; + phy_init_data_type_t type; + } certified[] = { + { "CN", ESP_PHY_INIT_DATA_TYPE_SRRC }, + { "US", ESP_PHY_INIT_DATA_TYPE_FCC }, + { "DE", ESP_PHY_INIT_DATA_TYPE_CE }, + { "TW", ESP_PHY_INIT_DATA_TYPE_NCC }, + { "KR", ESP_PHY_INIT_DATA_TYPE_KCC }, + { "JP", ESP_PHY_INIT_DATA_TYPE_MIC }, + }; + + wifi_start(); + + for (size_t i = 0; i < sizeof(certified) / sizeof(certified[0]); i++) { + TEST_ESP_OK(esp_phy_update_country_info(certified[i].country)); + TEST_ASSERT_EQUAL_MESSAGE(certified[i].type, esp_phy_get_init_data_type(), certified[i].country); + } + + /* Re-applying the same country keeps the PHY on the same init data */ + TEST_ESP_OK(esp_phy_update_country_info("JP")); + TEST_ASSERT_EQUAL(ESP_PHY_INIT_DATA_TYPE_MIC, esp_phy_get_init_data_type()); + + wifi_stop(); +} + +TEST_CASE("uncertified country codes fall back to the default PHY init data", "[phy_multiple_init_data]") +{ + wifi_start(); + + TEST_ESP_OK(esp_phy_update_country_info("CN")); + TEST_ASSERT_EQUAL(ESP_PHY_INIT_DATA_TYPE_SRRC, esp_phy_get_init_data_type()); + + /* AU maps to ACMA, for which the bin carries no certified init data */ + TEST_ESP_OK(esp_phy_update_country_info("AU")); + TEST_ASSERT_EQUAL(ESP_PHY_INIT_DATA_TYPE_DEFAULT, esp_phy_get_init_data_type()); + + /* An unmapped country code is answered with the default init data as well */ + TEST_ESP_OK(esp_phy_update_country_info("ZZ")); + TEST_ASSERT_EQUAL(ESP_PHY_INIT_DATA_TYPE_DEFAULT, esp_phy_get_init_data_type()); + + wifi_stop(); +} + +TEST_CASE("esp_wifi_set_country_code updates the PHY init data", "[phy_multiple_init_data]") +{ + wifi_start(); + + TEST_ESP_OK(esp_wifi_set_country_code("JP", false)); + + /* The Wi-Fi task drives the PHY update, so the type may lag the API call */ + for (int i = 0; i < 100 && esp_phy_get_init_data_type() != ESP_PHY_INIT_DATA_TYPE_MIC; i++) { + vTaskDelay(pdMS_TO_TICKS(10)); + } + TEST_ASSERT_EQUAL(ESP_PHY_INIT_DATA_TYPE_MIC, esp_phy_get_init_data_type()); + + /* wifi_country_t.cc is 3 octets (ISO code + environment), not a C string */ + char country_code[3] = { 0 }; + TEST_ESP_OK(esp_wifi_get_country_code(country_code)); + TEST_ASSERT_EQUAL('J', country_code[0]); + TEST_ASSERT_EQUAL('P', country_code[1]); + + wifi_stop(); +} + +#endif // CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN diff --git a/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py b/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py index fc73bb074e9..983cbcf532a 100644 --- a/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py +++ b/tools/test_apps/phy/phy_multi_init_data_test/pytest_phy_multi_init_data.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf.dut import IdfDut @@ -14,10 +14,17 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize('target', ['esp32', 'esp32c2', 'esp32c3', 'esp32c6', 'esp32s2', 'esp32s3'], indirect=['target']) +@idf_parametrize( + 'target', + ['esp32', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32s2', 'esp32s3'], + indirect=['target'], +) def test_phy_multi_init_data_bin(dut: IdfDut, config: str) -> None: - if config == 'phy_multiple_init_data': - dut.expect_exact('Support multiple PHY init data bins') - else: + # Where the bin was loaded from is only visible in the log, and app_main loads it + # once before handing over to the unity runner. + if config == 'phy_multiple_init_data_embed': dut.expect_exact('loading embedded multiple PHY init data') - dut.expect_exact('wifi_init finished') + dut.expect_exact('Support multiple PHY init data bins') + + # each case switches the PHY init data type, so start every one of them from a fresh boot + dut.run_all_single_board_cases(reset=True) diff --git a/tools/test_apps/phy/phy_multi_init_data_test/sdkconfig.defaults b/tools/test_apps/phy/phy_multi_init_data_test/sdkconfig.defaults new file mode 100644 index 00000000000..add233433ee --- /dev/null +++ b/tools/test_apps/phy/phy_multi_init_data_test/sdkconfig.defaults @@ -0,0 +1,2 @@ +# ignore task watchdog triggered by unity_run_menu +CONFIG_ESP_TASK_WDT_INIT=n From 55a52ccea691fd164bdb0720b2f6adff90424c33 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Fri, 28 Aug 2026 17:36:46 +0800 Subject: [PATCH 2/3] fix(phy): fix phy init data type and multiple bin offset incorrect --- components/esp_phy/esp32c61/include/phy_init_data.h | 4 ++-- components/esp_phy/src/phy_init.c | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/components/esp_phy/esp32c61/include/phy_init_data.h b/components/esp_phy/esp32c61/include/phy_init_data.h index 8a0eb240168..011632fa74f 100644 --- a/components/esp_phy/esp32c61/include/phy_init_data.h +++ b/components/esp_phy/esp32c61/include/phy_init_data.h @@ -26,8 +26,8 @@ extern "C" { #if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN #define PHY_CRC_ALGORITHM 1 #define PHY_COUNTRY_CODE_LEN 2 -#define PHY_INIT_DATA_TYPE_OFFSET 254 -#define PHY_SUPPORT_MULTIPLE_BIN_OFFSET 253 +#define PHY_INIT_DATA_TYPE_OFFSET 126 +#define PHY_SUPPORT_MULTIPLE_BIN_OFFSET 125 #endif extern const char phy_init_magic_pre[]; diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 0c8ef30e6e3..9ebf4905e46 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -118,6 +118,13 @@ static uint8_t s_phy_modem_init_ref = 0; extern uint8_t multi_phy_init_data_bin_start[] asm("_binary_phy_multiple_init_data_bin_start"); extern uint8_t multi_phy_init_data_bin_end[] asm("_binary_phy_multiple_init_data_bin_end"); #endif + +/* Both flags live in the last bytes of an init data entry */ +_Static_assert(PHY_INIT_DATA_TYPE_OFFSET == sizeof(esp_phy_init_data_t) - 2, + "PHY_INIT_DATA_TYPE_OFFSET does not match the PHY init data of this target"); +_Static_assert(PHY_SUPPORT_MULTIPLE_BIN_OFFSET == sizeof(esp_phy_init_data_t) - 3, + "PHY_SUPPORT_MULTIPLE_BIN_OFFSET does not match the PHY init data of this target"); + /* The following static variables are only used by Wi-Fi tasks, so they can be handled without lock */ static phy_init_data_type_t s_phy_init_data_type = 0; From 55b54fb0908ef09d8a55af1197eda23c88694ace Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Fri, 28 Aug 2026 17:45:30 +0800 Subject: [PATCH 3/3] fix(phy): update esp32c5 multiple phy init data bin --- .../esp32c5/phy_multiple_init_data.bin | Bin 1072 -> 2096 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/components/esp_phy/esp32c5/phy_multiple_init_data.bin b/components/esp_phy/esp32c5/phy_multiple_init_data.bin index 0f754a2c496b5cf7b712c49b15e83a02082692f4..2f31a6e5574851e9338f7512d4ead6beb8a0d6fb 100644 GIT binary patch literal 2096 zcmWIWi1hUH3}Ijh2=MXoaq;nR0b>Un4;Kdq4-XF)5Dn(oSb$iJ7AU|54h$4TMBp47 zTs)w-3(!`(4;U~pF+u0KfB;aOuvJ)9 zFfx6`W5oeSoe&_c1ImJiwtrssC9tu-K0r;SRWb w3?s(5*M1#v