efuse: Add the batch writing mode

This mode should be used when burning several efuses at one time.
This commit is contained in:
KonstantinKondrashov
2019-09-18 21:19:48 +08:00
parent d7fa288a6c
commit cf762d91c2
4 changed files with 226 additions and 27 deletions
+84 -27
View File
@@ -24,13 +24,19 @@ const static char *TAG = "efuse";
#if defined(BOOTLOADER_BUILD)
#define EFUSE_LOCK_ACQUIRE()
#define EFUSE_LOCK_RELEASE()
#define EFUSE_LOCK_ACQUIRE_RUCURSIVE()
#define EFUSE_LOCK_RELEASE_RUCURSIVE()
#else
#include <sys/lock.h>
static _lock_t s_efuse_lock;
#define EFUSE_LOCK_ACQUIRE() _lock_acquire(&s_efuse_lock)
#define EFUSE_LOCK_RELEASE() _lock_release(&s_efuse_lock)
#define EFUSE_LOCK_ACQUIRE_RUCURSIVE() _lock_acquire_recursive(&s_efuse_lock)
#define EFUSE_LOCK_RELEASE_RUCURSIVE() _lock_release_recursive(&s_efuse_lock)
#endif
static bool s_batch_writing_mode = false;
// Public API functions
// read value from EFUSE, writing it into an array
@@ -66,51 +72,62 @@ esp_err_t esp_efuse_read_field_cnt(const esp_efuse_desc_t* field[], size_t* out_
// write array to EFUSE
esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t* field[], const void* src, size_t src_size_bits)
{
EFUSE_LOCK_ACQUIRE();
EFUSE_LOCK_ACQUIRE_RUCURSIVE();
esp_err_t err = ESP_OK;
if (field == NULL || src == NULL || src_size_bits == 0) {
err = ESP_ERR_INVALID_ARG;
} else {
esp_efuse_utility_reset();
if (s_batch_writing_mode == false) {
esp_efuse_utility_reset();
}
err = esp_efuse_utility_process(field, (void*)src, src_size_bits, esp_efuse_utility_write_blob);
if (err == ESP_OK) {
err = esp_efuse_utility_apply_new_coding_scheme();
if (s_batch_writing_mode == false) {
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
err = esp_efuse_utility_apply_new_coding_scheme();
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
}
}
esp_efuse_utility_reset();
}
esp_efuse_utility_reset();
}
EFUSE_LOCK_RELEASE();
EFUSE_LOCK_RELEASE_RUCURSIVE();
return err;
}
// program cnt bits to "1"
esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt)
{
EFUSE_LOCK_ACQUIRE();
EFUSE_LOCK_ACQUIRE_RUCURSIVE();
esp_err_t err = ESP_OK;
if (field == NULL || cnt == 0) {
err = ESP_ERR_INVALID_ARG;
} else {
esp_efuse_utility_reset();
if (s_batch_writing_mode == false) {
esp_efuse_utility_reset();
}
err = esp_efuse_utility_process(field, &cnt, 0, esp_efuse_utility_write_cnt);
if (cnt != 0) {
ESP_LOGE(TAG, "The required number of bits can not be set. [Not set %d]", cnt);
err = ESP_ERR_EFUSE_CNT_IS_FULL;
}
if (err == ESP_OK_EFUSE_CNT || err == ESP_OK) {
err = esp_efuse_utility_apply_new_coding_scheme();
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
}
if (err == ESP_OK_EFUSE_CNT) {
err = ESP_OK;
}
if (s_batch_writing_mode == false) {
if (err == ESP_OK) {
err = esp_efuse_utility_apply_new_coding_scheme();
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
}
}
esp_efuse_utility_reset();
}
esp_efuse_utility_reset();
}
EFUSE_LOCK_RELEASE();
EFUSE_LOCK_RELEASE_RUCURSIVE();
return err;
}
@@ -140,17 +157,21 @@ uint32_t esp_efuse_read_reg(esp_efuse_block_t blk, unsigned int num_reg)
// writing efuse register.
esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t val)
{
EFUSE_LOCK_ACQUIRE();
esp_efuse_utility_reset();
esp_err_t err = esp_efuse_utility_write_reg(blk, num_reg, val);
if (err == ESP_OK) {
err = esp_efuse_utility_apply_new_coding_scheme();
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
}
EFUSE_LOCK_ACQUIRE_RUCURSIVE();
if (s_batch_writing_mode == false) {
esp_efuse_utility_reset();
}
esp_efuse_utility_reset();
EFUSE_LOCK_RELEASE();
esp_err_t err = esp_efuse_utility_write_reg(blk, num_reg, val);
if (s_batch_writing_mode == false) {
if (err == ESP_OK) {
err = esp_efuse_utility_apply_new_coding_scheme();
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
}
}
esp_efuse_utility_reset();
}
EFUSE_LOCK_RELEASE_RUCURSIVE();
return err;
}
@@ -193,3 +214,39 @@ esp_err_t esp_efuse_write_block(esp_efuse_block_t blk, const void* src_key, size
}
return err;
}
esp_err_t esp_efuse_batch_write_begin(void)
{
EFUSE_LOCK_ACQUIRE();
s_batch_writing_mode = true;
esp_efuse_utility_reset();
ESP_LOGI(TAG, "Batch mode of writing fields is enabled");
return ESP_OK;
}
esp_err_t esp_efuse_batch_write_cancel(void)
{
if (s_batch_writing_mode == true) {
s_batch_writing_mode = false;
esp_efuse_utility_reset();
ESP_LOGI(TAG, "Batch mode of writing fields is disabled");
EFUSE_LOCK_RELEASE();
return ESP_OK;
} else {
return ESP_ERR_INVALID_STATE;
}
}
esp_err_t esp_efuse_batch_write_commit(void)
{
if (s_batch_writing_mode == false) {
return ESP_ERR_INVALID_STATE;
} else {
esp_err_t err = esp_efuse_utility_apply_new_coding_scheme();
if (err == ESP_OK) {
esp_efuse_utility_burn_efuses();
}
esp_efuse_batch_write_cancel();
return err;
}
}