efuse: Add the batch writing mode
This mode should be used when burning several efuses at one time.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user