From be517fa8c06623ea867e1ee2fe138519f2fc7ef6 Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Mon, 29 Dec 2025 18:38:24 +0200 Subject: [PATCH] feat(efuse): Defer WR_DIS eFuse burning --- components/efuse/esp32/esp_efuse_utility.c | 8 +-- components/efuse/esp32c2/esp_efuse_utility.c | 8 +-- components/efuse/esp32c3/esp_efuse_utility.c | 8 +-- components/efuse/esp32c5/esp_efuse_utility.c | 8 +-- components/efuse/esp32c6/esp_efuse_utility.c | 8 +-- components/efuse/esp32c61/esp_efuse_utility.c | 8 +-- components/efuse/esp32h2/esp_efuse_utility.c | 8 +-- components/efuse/esp32h21/esp_efuse_utility.c | 8 +-- components/efuse/esp32h4/esp_efuse_utility.c | 6 --- components/efuse/esp32p4/esp_efuse_utility.c | 8 +-- components/efuse/esp32s2/esp_efuse_utility.c | 8 +-- components/efuse/esp32s3/esp_efuse_utility.c | 8 +-- components/efuse/esp32s31/esp_efuse_utility.c | 6 --- components/efuse/include/esp_efuse.h | 9 ++++ components/efuse/linux/esp_efuse_utility.c | 8 +-- components/efuse/src/esp_efuse_utility.c | 54 ++++++++++++++++++- components/efuse/test_apps/main/test_efuse.c | 16 +++++- components/esp_common/src/esp_err_to_name.c | 3 ++ docs/en/api-reference/system/efuse.rst | 7 +++ 19 files changed, 99 insertions(+), 98 deletions(-) diff --git a/components/efuse/esp32/esp_efuse_utility.c b/components/efuse/esp32/esp_efuse_utility.c index 6040c644ae..8954a966fe 100644 --- a/components/efuse/esp32/esp_efuse_utility.c +++ b/components/efuse/esp32/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -68,12 +68,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32c2/esp_efuse_utility.c b/components/efuse/esp32c2/esp_efuse_utility.c index 0aae5dbea0..f350985133 100644 --- a/components/efuse/esp32c2/esp_efuse_utility.c +++ b/components/efuse/esp32c2/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -58,12 +58,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32c3/esp_efuse_utility.c b/components/efuse/esp32c3/esp_efuse_utility.c index 57f27dcaf1..a8514689d5 100644 --- a/components/efuse/esp32c3/esp_efuse_utility.c +++ b/components/efuse/esp32c3/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -88,12 +88,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32c5/esp_efuse_utility.c b/components/efuse/esp32c5/esp_efuse_utility.c index 0515f93748..7fccd9709e 100644 --- a/components/efuse/esp32c5/esp_efuse_utility.c +++ b/components/efuse/esp32c5/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32c6/esp_efuse_utility.c b/components/efuse/esp32c6/esp_efuse_utility.c index 7669df8a0b..a7319d1c70 100644 --- a/components/efuse/esp32c6/esp_efuse_utility.c +++ b/components/efuse/esp32c6/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32c61/esp_efuse_utility.c b/components/efuse/esp32c61/esp_efuse_utility.c index ef4598e029..c8323eb35a 100644 --- a/components/efuse/esp32c61/esp_efuse_utility.c +++ b/components/efuse/esp32c61/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32h2/esp_efuse_utility.c b/components/efuse/esp32h2/esp_efuse_utility.c index e1da5d691d..aff288b3d3 100644 --- a/components/efuse/esp32h2/esp_efuse_utility.c +++ b/components/efuse/esp32h2/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32h21/esp_efuse_utility.c b/components/efuse/esp32h21/esp_efuse_utility.c index 2216e8d42f..05893f67fb 100644 --- a/components/efuse/esp32h21/esp_efuse_utility.c +++ b/components/efuse/esp32h21/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32h4/esp_efuse_utility.c b/components/efuse/esp32h4/esp_efuse_utility.c index 82896accf1..0c5ee276cf 100644 --- a/components/efuse/esp32h4/esp_efuse_utility.c +++ b/components/efuse/esp32h4/esp_efuse_utility.c @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32p4/esp_efuse_utility.c b/components/efuse/esp32p4/esp_efuse_utility.c index 7c9c36583a..7e3eb05e25 100644 --- a/components/efuse/esp32p4/esp_efuse_utility.c +++ b/components/efuse/esp32p4/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32s2/esp_efuse_utility.c b/components/efuse/esp32s2/esp_efuse_utility.c index 03560be94c..5d2742ffd5 100644 --- a/components/efuse/esp32s2/esp_efuse_utility.c +++ b/components/efuse/esp32s2/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32s3/esp_efuse_utility.c b/components/efuse/esp32s3/esp_efuse_utility.c index 99fcbb148b..60417caba3 100644 --- a/components/efuse/esp32s3/esp_efuse_utility.c +++ b/components/efuse/esp32s3/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,12 +73,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/esp32s31/esp_efuse_utility.c b/components/efuse/esp32s31/esp_efuse_utility.c index 54e275456f..bc89d26524 100644 --- a/components/efuse/esp32s31/esp_efuse_utility.c +++ b/components/efuse/esp32s31/esp_efuse_utility.c @@ -72,12 +72,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index d12d20f67c..3e32ec92a5 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -26,6 +26,7 @@ extern "C" { #define ESP_ERR_CODING (ESP_ERR_EFUSE + 0x04) /*!< Error while a encoding operation. */ #define ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS (ESP_ERR_EFUSE + 0x05) /*!< Error not enough unused key blocks available */ #define ESP_ERR_DAMAGED_READING (ESP_ERR_EFUSE + 0x06) /*!< Error. Burn or reset was done during a reading operation leads to damage read data. This error is internal to the efuse component and not returned by any public API. */ +#define ESP_ERR_BURN_WR_DIS (ESP_ERR_EFUSE + 0x07) /*!< Error to burn WR_DIS field. */ /** * @brief Type definition for an eFuse field @@ -175,6 +176,7 @@ esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[]); * - ESP_ERR_INVALID_ARG: Error in the passed arguments. * - ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set. * - ESP_ERR_NOT_SUPPORTED: The block does not support this command. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk); @@ -498,6 +500,8 @@ esp_err_t esp_efuse_batch_write_cancel(void); * @return * - ESP_OK: Successful. * - ESP_ERR_INVALID_STATE: The deferred writing mode was not set. + * - ESP_FAIL: Failed to write efuse fields. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_batch_write_commit(void); @@ -553,6 +557,7 @@ bool esp_efuse_get_key_dis_write(esp_efuse_block_t block); * - ESP_ERR_INVALID_ARG: Error in the passed arguments. * - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden. * - ESP_ERR_CODING: Error range of data does not match the coding scheme. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block); @@ -651,6 +656,7 @@ esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t * - ESP_ERR_INVALID_ARG: Error in the passed arguments. * - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden. * - ESP_ERR_CODING: Error range of data does not match the coding scheme. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_set_keypurpose_dis_write(esp_efuse_block_t block); @@ -715,6 +721,7 @@ bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest); * - ESP_ERR_INVALID_ARG: Error in the passed arguments. * - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden. * - ESP_ERR_CODING: Error range of data does not match the coding scheme. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest); @@ -742,6 +749,7 @@ esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest); * - ESP_ERR_INVALID_STATE: Error in efuses state, unused block not found. * - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden. * - ESP_ERR_CODING: Error range of data does not match the coding scheme. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpose, const void *key, size_t key_size_bytes); @@ -767,6 +775,7 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo * - ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS: Error not enough unused key blocks available * - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden. * - ESP_ERR_CODING: Error range of data does not match the coding scheme. + * - ESP_ERR_BURN_WR_DIS: Failed to burn WR_DIS field. */ esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys); diff --git a/components/efuse/linux/esp_efuse_utility.c b/components/efuse/linux/esp_efuse_utility.c index a8af8c0b95..9229076484 100644 --- a/components/efuse/linux/esp_efuse_utility.c +++ b/components/efuse/linux/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -62,12 +62,6 @@ esp_err_t esp_efuse_utility_check_errors(void) return ESP_OK; } -// Burn values written to the efuse write registers -esp_err_t esp_efuse_utility_burn_chip(void) -{ - return esp_efuse_utility_burn_chip_opt(false, true); -} - esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; diff --git a/components/efuse/src/esp_efuse_utility.c b/components/efuse/src/esp_efuse_utility.c index 7660504776..7c522f4d63 100644 --- a/components/efuse/src/esp_efuse_utility.c +++ b/components/efuse/src/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ #include "assert.h" #include "sdkconfig.h" #include +#include "esp_efuse_table.h" ESP_LOG_ATTR_TAG(TAG, "efuse"); @@ -493,3 +494,54 @@ bool esp_efuse_utility_is_correct_written_data(esp_efuse_block_t block, unsigned } return correct_written_data; } + +// This function defers the programming of ESP_EFUSE_WR_DIS efuse field. +// This field is very critical, because it disables any further programming of some efuses. +// We want to defer its programming until all other efuses are programmed successfully. +// Returns the staged WR_DIS data, so that it can be restored later for programming. +static uint32_t defer_wr_dis(void) +{ + // ESP_EFUSE_WR_DIS is always in reg 0 of block 0, the only length is varied from chip to chip. + uint32_t staged_reg = REG_READ(range_write_addr_blocks[0].start); // array of staged write registers + uint32_t wr_dis_reg_mask = get_mask(ESP_EFUSE_WR_DIS[0]->bit_count, ESP_EFUSE_WR_DIS[0]->bit_start); + + // Clear WR_DIS field and keep other bits in the staged register unchanged + REG_WRITE(range_write_addr_blocks[0].start, staged_reg & ~wr_dis_reg_mask); + + // return WR_DIS value, excluding other bits in the staged register. + return staged_reg & wr_dis_reg_mask; +} + +static inline void restore_deferred_wr_dis(uint32_t staged_wr_dis_data) +{ + REG_WRITE(range_write_addr_blocks[0].start, staged_wr_dis_data); +} + +esp_err_t esp_efuse_utility_burn_chip(void) +{ + // Always defer the WR_DIS field burning to ensure that if any error occurs during the burn process of BLOCK0, + // the chip will have a chance to be recovered by the repeating burning mechanism in esp_efuse_utility_burn_chip_opt. + // This is critical because WR_DIS permanently disables further eFuse programming of some efuse fields. + + uint32_t staged_wr_dis_data = defer_wr_dis(); + + esp_err_t err = esp_efuse_utility_burn_chip_opt(false, true); + + if (err == ESP_OK) { + if (staged_wr_dis_data != 0) { + restore_deferred_wr_dis(staged_wr_dis_data); + err = esp_efuse_utility_burn_chip_opt(false, true); + if (err != ESP_OK) { + err = ESP_ERR_BURN_WR_DIS; + ESP_LOGE(TAG, "Failed to burn WR_DIS = 0x%08" PRIx32, staged_wr_dis_data); + } + } + } else { + ESP_LOGE(TAG, "Failed to burn eFuses"); + if (staged_wr_dis_data != 0) { + ESP_LOGW(TAG, "WR_DIS efuse was not burned (deferred): 0x%08" PRIx32, staged_wr_dis_data); + } + } + + return err; +} diff --git a/components/efuse/test_apps/main/test_efuse.c b/components/efuse/test_apps/main/test_efuse.c index 88af951f9f..08f7d0a80e 100644 --- a/components/efuse/test_apps/main/test_efuse.c +++ b/components/efuse/test_apps/main/test_efuse.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -869,3 +869,17 @@ TEST_CASE("Test chip_ver_pkg APIs return the same value", "[efuse]") esp_efuse_utility_update_virt_blocks(); TEST_ASSERT_EQUAL_INT(esp_efuse_get_pkg_ver(), efuse_ll_get_chip_ver_pkg()); } + +TEST_CASE("Test deferred WR_DIS programming", "[efuse]") +{ + esp_efuse_utility_erase_virt_blocks(); + esp_efuse_utility_update_virt_blocks(); + + esp_efuse_batch_write_begin(); + TEST_ESP_OK(esp_efuse_set_write_protect(EFUSE_BLK_KEY0)); + TEST_ESP_OK(esp_efuse_set_read_protect(EFUSE_BLK_KEY0)); + esp_efuse_batch_write_commit(); + + TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(EFUSE_BLK_KEY0)); + TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(EFUSE_BLK_KEY0)); +} diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index 6504f54650..490c9fb9f2 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -321,6 +321,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { data. This error is internal to the efuse component and not returned by any public API. */ +# endif +# ifdef ESP_ERR_BURN_WR_DIS + ERR_TBL_IT(ESP_ERR_BURN_WR_DIS), /* 5639 0x1607 Error to burn WR_DIS field. */ # endif // components/bootloader_support/include/esp_image_format.h # ifdef ESP_ERR_IMAGE_BASE diff --git a/docs/en/api-reference/system/efuse.rst b/docs/en/api-reference/system/efuse.rst index cfc99b5fa1..c078a27f41 100644 --- a/docs/en/api-reference/system/efuse.rst +++ b/docs/en/api-reference/system/efuse.rst @@ -570,6 +570,13 @@ To get a dump for all eFuse registers. .. include:: inc/espefuse_summary_{IDF_TARGET_NAME}_dump.rst +Deferred WR_DIS Burning +----------------------- + +``WR_DIS`` (Write Disable) is a special eFuse field that implements permanent write-protection. Each bit in ``WR_DIS`` disables further programming of one (or more) associated eFuse fields. Once burned, the affected fields can no longer be modified. + +When burning staged data in BLOCK0, ``WR_DIS`` bits are burned separately after all other BLOCK0 data to ensure the retry mechanism of the burn function can recover from coding errors. This approach guarantees that write-protection is applied only after other BLOCK0 data is successfully burned. + Application Examples --------------------