(solved) working with efuses

Konstantin
Posts: 13
Joined: Tue Feb 05, 2019 7:31 am

Re: working with efuses

Postby Konstantin » Thu Jul 25, 2019 5:48 am

Hi mzimmers!

1. Your ESP_FUSE3 fuse3 is:
struct ESP_FUSE3 {
uint8_t crc;
uint8_t macAddr[6];
uint8_t reserved[8];
uint8_t version;
};

This structure is 8+8*6+8+8 = 72 bits. But in your code you do `rc = esp_efuse_read_block(EFUSE_BLK3, &fuse3, 0, 192);`. You have to use your real size of fuse3.
The right way is esp_efuse_read_block(EFUSE_BLK3, &fuse3, 0, sizeof(fuse3);

2. Please see the efuse table here: https://github.com/espressif/esp-idf/bl ... sv#L25-L27
Your ESP_FUSE3 does not fit this table.
You can read by one of these fields, look as an example: https://github.com/espressif/esp-idf/bl ... .c#L79-L98

3. The fuse3.version is wrong. It was read from the wrong offset.
Your struct must look as :
struct ESP_FUSE3 {
uint8_t crc; // , 0, 8, CRC8 for custom MAC address.
uint8_t macAddr[6]; // 8, 48, Custom MAC
uint8_t reserved[16]; <------------------------------------------------- increased
uint8_t version; //184, 8, Custom MAC version
};

4. Your ESP32 already has programmed the CUSTOM_MAC: `efuse BLK3 MAC field is programmed as 00:a0:d0:00:00:00.`
You can write a new CUSTOM MAC address only once.

5. Run command to see all efuse fields:
./../esp-idf/components/esptool_py/esptool/espefuse.py summary
./../esp-idf/components/esptool_py/esptool/espefuse.py dump

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: working with efuses

Postby mzimmers » Thu Jul 25, 2019 3:00 pm

Hi Konstantin -

Good catch on my struct; just a sloppy mistake on my part. Unfortunately, my program is still acting strangely. First, here's a look at fuse block 3:

Code: Select all

$ espefuse.py --port COM7 dump
espefuse.py v2.6
Connecting........__
EFUSE block 0:
00000000 bf5edbec 00853c71 0000a000 00000535 00000000 00000004
EFUSE block 1:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
EFUSE block 2:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
EFUSE block 3:
d0a00032 00000000 00000000 01000000 41564e49 0044494c 00000000 00000000
and from my program's telltales:

Code: Select all

I (69) Flash: initBaseMacAddress(): efuse BLK3 is programmed as follows:
I (69) Flash: initBaseMacAddress(): efuse BLK3 version field is programmed as 3f:
I (79) Flash: initBaseMacAddress(): efuse BLK3 MAC field is programmed as 00:a0:3f:1c:62:fb.
I (89) Flash: initBaseMacAddress(): efuse BLK3 CRC field is programmed as 32:
E (99) system_api: Base MAC address from BLK3 of EFUSE version error, version = 0
I have no idea why it's getting a value of 3f for the version; as you can see from the dump, there's no value of 3f in all of fuse 3.

WiFive: I did add the packed attribute to the struct -- doesn't seem to be making any difference.

Thanks...

Konstantin
Posts: 13
Joined: Tue Feb 05, 2019 7:31 am

Re: working with efuses

Postby Konstantin » Fri Jul 26, 2019 5:05 am

I tried so and it works for me:

typedef struct {
uint8_t crc;
uint8_t macAddr[6];
uint8_t reserved[16];
uint8_t version;
} ESP_FUSE3;

rc = esp_efuse_read_block(EFUSE_BLK3, &fuse3, 0, sizeof(fuse3)*8);
Propably I was wrong when suggest that size = sizeof(fuse3), need to use sizeof(fuse3) * 8 (due to it is in bits).


As an option, they can read separated as:

uint8_t mac[6];
esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48);
uint8_t efuse_crc;
esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM_CRC, &efuse_crc, 8);
uint8_t version;
esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM_VER, &version, 8);

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: working with efuses

Postby mzimmers » Fri Jul 26, 2019 4:46 pm

Hi Konstantin -

You're right - the bad length on the read call was confusing my results. I've also decided to write the fields individually; that way I don't risk overwriting anything in the reserved section. It seems to be working now...thanks!

Here's my revised code, for anyone who might be experiencing similar difficulties -- and of course, I welcome feedback on it.

Code: Select all

esp_err_t Flash::initMacAddress()
{
    char macAddrAscii[18] = { NULL_CHAR };
    uint8_t crc;
    uint8_t version;
    uint8_t macAddr[6];
    esp_err_t rc;

    // see whether eFuse has been programmed yet. (if programmed, the version won't be 0.)
    rc = esp_efuse_read_block(EFUSE_BLK3, &version, EFUSE3_VERSION_OFFSET, EFUSE3_VERSION_SIZE);
    if (rc == ESP_OK)
    {
        ESP_LOGI(TAG, "initMacAddress(): efuse BLK3 version field is programmed as %x: ", version);
        if (version != 0)
        {
            rc = esp_efuse_mac_get_custom(macAddr);
            if (rc == ESP_OK)
            {
                //ESP_LOGI(TAG, "initMacAddress(): esp_efuse_mac_get_custom returned successfully.");
                mac_itoa(macAddr, macAddrAscii);
                setMacAddr(macAddrAscii);
            }
            else 
            {
                ESP_LOGE(TAG, "initMacAddress(): esp_efuse_mac_get_custom() failed; halting execution.");
                vTaskDelay(portMAX_DELAY);
            }
        }
        else // this error suggests the MAC hasn't been programmed.
        {
            ESP_LOGW(TAG, "initMacAddress(): invalid version in efuse BLK3; attempting to program.");

            // write the fuse fields.
            // (1) the version field.
            version = 1;                                  // anything non-zero will do for now.
            rc = esp_efuse_write_block(EFUSE_BLK3, &version, EFUSE3_VERSION_OFFSET, EFUSE3_VERSION_SIZE);
            if (rc == ESP_OK)
            {
                ESP_LOGI(TAG, "initMacAddress(): version written to eFuse BLK3.");
            }
            else
            {
                ESP_LOGE(TAG, "initMacAddress(): esp_efuse_write_block() returned %x on write version.", rc);
                vTaskDelay(portMAX_DELAY);
            }

            // (2) the MAC address field. retrieve the MAC address from flash.
            strcpy(macAddrAscii, getMacAddr().c_str());       // get address in string format from flash.

            rc = mac_atoi(macAddr, macAddrAscii);            // convert to binary
            // if the conversion was good, proceed.
            if (rc == ESP_OK)
            {
                // write the MAC addr.
                rc = esp_efuse_write_block(EFUSE_BLK3, macAddr, EFUSE3_MACADDR_OFFSET, EFUSE3_MACADDR_SIZE);
                if (rc == ESP_OK)
                {
                    ESP_LOGI(TAG, "initMacAddress(): MAC address successfully written to efuse BLK3.");
                }
                else
                {
                    ESP_LOGE(TAG, "initMacAddress(): error writing custom MAC into eFuse BLK3; halting execution.");
                    vTaskDelay(portMAX_DELAY);
                }
            }
            else
            {
                ESP_LOGE(TAG, "initMacAddress(): invalid MAC address read from flash; halting execution.");
                vTaskDelay(portMAX_DELAY);
            }

            // (3) the CRC for the MAC address.
            crc = crc8Maxim(macAddr, sizeof(macAddr));
            rc = esp_efuse_write_block(EFUSE_BLK3, &crc, EFUSE3_CRC_OFFSET, EFUSE3_CRC_SIZE);
            if (rc == ESP_OK)
            {
                ESP_LOGI(TAG, "initMacAddress(): CRC successfully written to efuse BLK3.");
            }
            else
            {
                ESP_LOGE(TAG, "initMacAddress(): error writing CRC  into eFuse BLK3; halting execution.");
                vTaskDelay(portMAX_DELAY);
            }
        }
    }
    else // unable to read eFuse BLK3; falling back to default MAC (BLK0).
         // this shouldn't ever happen.
    {
        ESP_LOGE(TAG, "initMacAddress(): esp_efuse_mac_get_custom returned error %x.", rc);

        rc = esp_efuse_mac_get_default(macAddr);
        if (rc == ESP_OK)
        {
            ESP_LOGW(TAG, "initMacAddress(): reverting to default MAC.");
            mac_itoa(macAddr, macAddrAscii);
//            setMacAddr(macAddrAscii);
        }
        else
        {
            ESP_LOGE(TAG, "initMacAddress(): attempt to reverto to default MAC failed. \
                     that's enough of this nonsense; halting.");
            vTaskDelay(portMAX_DELAY);
        }
    }
    return rc;
}

Who is online

Users browsing this forum: No registered users and 120 guests