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

hgptamn
Posts: 25
Joined: Mon Oct 16, 2017 4:47 pm

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

Postby hgptamn » Thu May 17, 2018 8:34 am

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/blob/master/components/bootloader_support/include/esp_efuse.h
2. https://github.com/espressif/esp-idf/blob/master/components/esp32/include/rom/efuse.h
3. https://www.esp32.com/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!

WiFive
Posts: 1675
Joined: Tue Dec 01, 2015 7:35 am

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

Postby WiFive » Thu May 17, 2018 9:58 am

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?

hgptamn
Posts: 25
Joined: Mon Oct 16, 2017 4:47 pm

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

Postby hgptamn » Fri May 18, 2018 2:43 pm

@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();
}
Attachments
efuse.zip
(9.39 KiB) Downloaded 2 times

Who is online

Users browsing this forum: No registered users and 2 guests