Page 1 of 1

EFUSE read/write BLOCK 1/2/3 from esp-idf

Posted: Thu May 17, 2018 8:34 am
by hgptamn
How would one do the writing of EFUSE BLOCK 1/2/3 and then the reading of EFUSE BLOCK 1/2/3 (to check that the write was successful) in esp-idf?

I'm well aware of:
1. https://github.com/espressif/esp-idf/bl ... sp_efuse.h
2. https://github.com/espressif/esp-idf/bl ... om/efuse.h
3. viewtopic.php?f=13&t=2976
4. Technical Reference Manual chapter 19: eFuse Controller

Using espefuse.py to do so, is quite simple and straight forward as described over here: https://github.com/espressif/esptool/wiki/espefuse

However, doing so in esp-idf, proves a bit challenging, especially if you consider that the API referenced at 1 and 2 comes with no real example at all. Thus, the risk of bricking the ESP32 is quite high, if i go by trial and error.

Any esp-idf example code would be of great help!

Re: EFUSE read/write BLOCK 1/2/3 from esp-idf

Posted: Thu May 17, 2018 9:58 am
by WiFive
https://github.com/espressif/esp-idf/bl ... .c#L56-L58

https://github.com/espressif/esp-idf/bl ... .c#L83-L89

The only potential issue is
When the value of BLK3_part_reserve is 1, coding_schemeBLOCK1BLOCK2 and BLOCK3 are controlled by 3/4 coding scheme. Meanwhile, BLOCK3[143 : 96], namely, eBLOCK3[191 : 128] is unavailable.
and
ESP32s with both Two Point Values and Vref burned into eFuse are required to also burn the EFUSE_BLK3_PART_RESERVE flag
and there is no support for writing encoded parameters yet. I am not entirely sure how flash encryption and 3/4 coding scheme works. Are key lengths reduced?

Re: EFUSE read/write BLOCK 1/2/3 from esp-idf

Posted: Fri May 18, 2018 2:43 pm
by hgptamn
@WiFive
Thank you sir! :ugeek: That was exactly what I was looking for.
What's the main difference between calling:

Code: Select all

REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_XPD_SDIO_REG, 1);
and

Code: Select all

 REG_WRITE(EFUSE_BLK0_WDATA4_REG, EFUSE_RD_XPD_SDIO_REG);
They both seem to do the same thing.
In case anyone is looking for the esp-idf code I'm pasting it bellow and also attaching it to this reply.

Code: Select all

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "driver/periph_ctrl.h"
#include "soc/rtc_cntl_reg.h"
#include "rom/efuse.h"
#include "soc/efuse_reg.h"
#include "soc/soc.h"
#include "esp_efuse.h"
#include "esp_log.h"

static const char *TAG = "efuse";

void app_main()
{	
	bool burned = false;
	
	printf("\nWarning! Once the eFuses are burned you cannot revert back!");
	vTaskDelay(5000 / portTICK_PERIOD_MS);
	
	//BLOCK3 is user reserved
	//You can write whatever you want here.
	
	//burning BLOCK3 bit0
	if (!!(REG_READ(EFUSE_BLK3_RDATA0_REG) & BIT0) == 0) { //check if eFuse was previously burned (if not burned eFuse == 0)
        ESP_EARLY_LOGI(TAG, "\nBurning BLOCK3 bit0 fuse to 1");
        esp_efuse_reset();
        REG_WRITE(EFUSE_BLK3_WDATA0_REG, BIT0);
		esp_efuse_burn_new_values();
		burned = true;
    }else{
		printf("\nBLOCK3 BIT0 already burned");
	}
	
	//Warning!!!
	//Burning SDIO_FORCE and SDIO_REG will permanently set the flash voltage from 3.3V to 1.8V 
	
	//burning SDIO_FORCE
	if (!!(REG_READ(EFUSE_BLK0_RDATA4_REG) & EFUSE_RD_SDIO_FORCE) == 0) {
        ESP_EARLY_LOGI(TAG, "\nBurning EFUSE_BLK0_WDATA4_RE fuse EFUSE_RD_SDIO_FORCE to 1");
        esp_efuse_reset();
        REG_WRITE(EFUSE_BLK0_WDATA4_REG, EFUSE_RD_SDIO_FORCE);
		esp_efuse_burn_new_values();
		burned = true;
    }else{
		printf("\nSDIO_FORCE already burned");
	}
	
	//burning SDIO_REG
	if (!!(REG_READ(EFUSE_BLK0_RDATA4_REG) & EFUSE_RD_XPD_SDIO_REG) == 0) {
        ESP_EARLY_LOGI(TAG, "\nBurning EFUSE_BLK0_WDATA4_RE fuse EFUSE_RD_XPD_SDIO_REG to 1");
        esp_efuse_reset();
        REG_WRITE(EFUSE_BLK0_WDATA4_REG, EFUSE_RD_XPD_SDIO_REG);
		esp_efuse_burn_new_values();
		burned = true;
    }else{
		printf("\nSDIO_REG already burned");
	}
	
	if(burned)
		printf("\nFuses burned!\n");
	
	for (int i = 5; i >= 0; i--) {
        printf("\nRestarting in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
    printf("\nRestarting now.\n");
    fflush(stdout);
    esp_restart();
}