Просмотр исходного кода

efuse: Add new esp_efuse_write_field_bit() convenience function

Angus Gratton 5 лет назад
Родитель
Сommit
9ca02bd8ac

+ 1 - 5
components/bootloader_support/src/flash_encrypt.c

@@ -71,11 +71,7 @@ void esp_flash_encryption_init_checks()
 
 void esp_flash_write_protect_crypt_cnt()
 {
-    uint8_t flash_crypt_cnt_wr_dis = 0;
-    esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
-    if (!flash_crypt_cnt_wr_dis) {
-        esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, 1);
-    }
+    esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT);
 }
 
 esp_flash_enc_mode_t esp_get_flash_encryption_mode()

+ 17 - 0
components/efuse/include/esp_efuse.h

@@ -123,6 +123,23 @@ esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t* field[], const void
  */
 esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt);
 
+/**
+ * @brief Write a single bit eFuse field to 1
+ *
+ * For use with eFuse fields that are a single bit. This function will write the bit to value 1 if
+ * it is not already set, or does nothing if the bit is already set.
+ *
+ * This is equivalent to calling esp_efuse_write_field_cnt() with the cnt parameter equal to 1,
+ * except that it will return ESP_OK if the field is already set to 1.
+ *
+ * @param[in] field Pointer to the structure describing the efuse field.
+ *
+ * @return
+ * - ESP_OK: The operation was successfully completed, or the bit was already set to value 1.
+ * - ESP_ERR_INVALID_ARG: Error in the passed arugments, including if the efuse field is not 1 bit wide.
+ */
+esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[]);
+
 /**
  * @brief   Sets a write protection for the whole block.
  *

+ 19 - 0
components/efuse/src/esp_efuse_api.c

@@ -140,6 +140,25 @@ esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
     return ESP_ERR_NOT_SUPPORTED;
 }
 
+esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[])
+{
+    esp_err_t err;
+    uint8_t existing = 0;
+    const uint8_t one = 1;
+
+    if (field == NULL || field[0]->bit_count != 1) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    /* Check existing value. esp_efuse_write_field_blob() also checks this, but will log an error */
+    err = esp_efuse_read_field_blob(field, &existing, 1);
+    if (err != ESP_OK || existing) {
+        return err; // Error reading, or the bit is already written and we can no-op this
+    }
+
+    return esp_efuse_write_field_blob(field, &one, 1);
+}
+
 // get the length of the field in bits
 int esp_efuse_get_field_size(const esp_efuse_desc_t* field[])
 {

+ 21 - 0
components/efuse/test/test_efuse.c

@@ -224,6 +224,27 @@ TEST_CASE("efuse test write_field_cnt", "[efuse]")
     test_write_cnt();
 }
 
+TEST_CASE("efuse test write_field_bit", "[efuse]")
+{
+    esp_efuse_utility_erase_virt_blocks();
+    esp_efuse_utility_debug_dump_blocks();
+
+    uint8_t test_bit;
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
+    TEST_ASSERT_EQUAL_HEX8(0, test_bit);
+
+    TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
+    TEST_ASSERT_EQUAL_HEX8(1, test_bit);
+
+    // Can write the bit again and it's a no-op
+    TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
+    TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
+    TEST_ASSERT_EQUAL_HEX8(1, test_bit);
+
+    esp_efuse_utility_debug_dump_blocks();
+}
+
 void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
 {
     if ((num_used_bits + count_bits) % 8) {