(solved) working with efuses

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

(solved) working with efuses

Postby mzimmers » Mon Jul 22, 2019 2:49 pm

Hi all -

I recently started working with the efuse handler. I need to store a custom MAC address in BLK3, so I wrote the following routine:

Code: Select all

esp_err_t Flash::initBaseMacAddress()
{
    char macAddrAscii[18] = { NULL_CHAR };
    esp_err_t rc = ESP_OK;

    ESP_FUSE3 fuse3;

    // see whether efuse has been programmed yet.
    // (if programmed, won't be all 0s.)
    // if not programmed, do so using the flash value, and do the CRC as well.
    rc = esp_efuse_read_block(EFUSE_BLK3, &fuse3, 0, 192);
    ESP_LOGI(TAG, "initBaseMacAddress(): efuse BLK3 is programmed as follows:");
    ESP_LOGI(TAG, "initBaseMacAddress(): efuse BLK3 version field is programmed as %x: ", fuse3.version);
    ESP_LOGI(TAG, "initBaseMacAddress(): efuse BLK3 MAC field is programmed as %02x:%02x:%02x:%02x:%02x:%02x.",
             fuse3.macAddr[0], fuse3.macAddr[1], fuse3.macAddr[2],
            fuse3.macAddr[3],fuse3.macAddr[4],fuse3.macAddr[5]);
    ESP_LOGI(TAG, "initBaseMacAddress(): efuse BLK3 CRC field is programmed as %x: ", fuse3.crc);



    rc = esp_efuse_mac_get_custom(fuse3.macAddr);
    if (rc == ESP_OK)
    {
        ESP_LOGI(TAG, "taskInit(): esp_efuse_mac_get_custom returned successfully.");
        mac_itoa(fuse3.macAddr, macAddrAscii);
        setMacAddr(macAddrAscii);
    }
    else if (rc == ESP_ERR_INVALID_VERSION) // this error suggests the MAC hasn't been programmed.
    {
        ESP_LOGW(TAG, "initBaseMacAddress(): invalid version in efuse BLK3; attempting to program.");

        // fill the fields in the structure and program the fuse.
        fuse3.version = 1;                                  // anything non-zero will do for now.
        memset (fuse3.reserved, 0, sizeof(fuse3.reserved)); // make sure it's all zeroes (no write).
        strcpy(macAddrAscii, getMacAddr().c_str());       // get address in string format from flash.

        if (strcmp(macAddrAscii, NVS_INVALID))
        {
            rc = mac_atoi(fuse3.macAddr, macAddrAscii);            // convert to binary
            if (rc == ESP_OK)
            {
                fuse3.crc = crc8Maxim(fuse3.macAddr, 6);

                ESP_LOGI(TAG, "initBaseMacAddress(): programming efuse BLK3 as follows:");
                ESP_LOGI(TAG, "initBaseMacAddress(): programming efuse BLK3 version field as %x: ", fuse3.version);
                ESP_LOGI(TAG, "initBaseMacAddress(): programming efuse BLK3 MAC field as %02x:%02x:%02x:%02x:%02x:%02x.",
                         fuse3.macAddr[0], fuse3.macAddr[1], fuse3.macAddr[2],
                        fuse3.macAddr[3],fuse3.macAddr[4],fuse3.macAddr[5]);
                ESP_LOGI(TAG, "initBaseMacAddress(): programming efuse BLK3 CRC field as %x: ", fuse3.crc);

                // program fuse 3.
                rc = esp_efuse_write_block(EFUSE_BLK3, &fuse3, 0, 192);
                if (rc == ESP_OK)
                {
                    ESP_LOGI(TAG, "initBaseMacAddress(): efuse BLK3 successfully programmed.");
                    mac_itoa(fuse3.macAddr, macAddrAscii);
                    setMacAddr(macAddrAscii);
                }
                else
                {
                    ESP_LOGE(TAG, "initBaseMacAddress(): error writing custom MAC into efuse BLK3; halting execution.");
                    vTaskDelay(portMAX_DELAY);
                }
                ...
This gives me the following (unexpected) output:
I (69) Flash: initBaseMacAddress(): efuse BLK3 is programmed as follows:
I (79) Flash: initBaseMacAddress(): efuse BLK3 version field is programmed as 1:
I (89) Flash: initBaseMacAddress(): efuse BLK3 MAC field is programmed as 00:a0:d0:00:00:00.
I (99) Flash: initBaseMacAddress(): efuse BLK3 CRC field is programmed as 32:
E (109) system_api: Base MAC address from BLK3 of EFUSE version error, version = 0
W (109) Flash: initBaseMacAddress(): invalid version in efuse BLK3; attempting to program.
I (119) Flash: initBaseMacAddress(): programming efuse BLK3 as follows:
I (129) Flash: initBaseMacAddress(): programming efuse BLK3 version field as 1:
I (139) Flash: initBaseMacAddress(): programming efuse BLK3 MAC field as 12:23:34:45:56:67.
I (149) Flash: initBaseMacAddress(): programming efuse BLK3 CRC field as fa:
E (149) efuse: Repeated programming of programmed bits is strictly forbidden 0x10200032
E (159) Flash: initBaseMacAddress(): error writing custom MAC into efuse BLK3; halting execution.
Any idea what I'm doing wrong? Running V3.3.

Also, is there truly no way to reset the fuses once written? I'd like to minimize the number of devices I burn incorrectly while I troubleshoot this issue.

Thanks...
Last edited by mzimmers on Mon Aug 12, 2019 9:50 pm, edited 1 time in total.

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

Re: working with efuses

Postby mzimmers » Tue Jul 23, 2019 9:44 pm

BTT...anyone have any suggestions on this?

Thanks...

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

Re: working with efuses

Postby WiFive » Wed Jul 24, 2019 12:53 am

Are you saying that is the output on the first run meaning there are already nonzero values in block3 when you started? What is the efuse dump from esptool?

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

Re: working with efuses

Postby mzimmers » Wed Jul 24, 2019 2:27 pm

Hi WiFive - no, this isn't from the first run. In the first run, I programmed values into BLK3. But on subsequent runs, I'm getting this:

E (109) system_api: Base MAC address from BLK3 of EFUSE version error, version = 0

when I call esp_efuse_mac_get_custom(). According to the docs, that suggests the field wasn't programmed, but my program output indicates that it was.

A good starting point would be to see why I'm getting the above error, when my telltales indicate that I've programmed BLK3.

Thanks...

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

Re: working with efuses

Postby WiFive » Wed Jul 24, 2019 8:04 pm


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

Re: working with efuses

Postby mzimmers » Wed Jul 24, 2019 8:56 pm

I wasn't aware of that simulation option; thank you for pointing it out. I just tried it, and got essentially the same results.

Code: Select all

I (69) Flash: initBaseMacAddress(): efuse BLK3 is programmed as follows:
I (79) Flash: initBaseMacAddress(): efuse BLK3 version field is programmed as 1:
I (89) Flash: initBaseMacAddress(): efuse BLK3 MAC field is programmed as 00:a0:d0:00:00:00.
I (99) Flash: initBaseMacAddress(): efuse BLK3 CRC field is programmed as 32:
E (109) system_api: Base MAC address from BLK3 of EFUSE version error, version = 0
W (109) Flash: initBaseMacAddress(): invalid version in efuse BLK3; attempting to program.
I (119) Flash: initBaseMacAddress(): programming efuse BLK3 as follows:
I (129) Flash: initBaseMacAddress(): programming efuse BLK3 version field as 1:
I (139) Flash: initBaseMacAddress(): programming efuse BLK3 MAC field as 12:23:34:45:56:67.
I (149) Flash: initBaseMacAddress(): programming efuse BLK3 CRC field as fa:
E (149) efuse: Repeated programming of programmed bits is strictly forbidden 0x10200032
E (159) Flash: initBaseMacAddress(): error writing custom MAC into efuse BLK3; halting execution.
So, the code seems to be doing what I want it to...I must not understand how to use the system calls properly, as I'm still getting the version error when I call:

Code: Select all

 rc = esp_efuse_mac_get_custom(fuse3.macAddr);

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

Re: working with efuses

Postby WiFive » Wed Jul 24, 2019 11:28 pm

What is ESP_FUSE3? Have you tried writing the fields individually?

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 1:19 am

Code: Select all

struct ESP_FUSE3
{
    uint8_t crc;
    uint8_t macAddr[6];
    uint8_t reserved[8];
    uint8_t version;
};
I could try writing the fields individually, but the real mystery right now is why this call:

Code: Select all

rc = esp_efuse_mac_get_custom(fuse3.macAddr);


Is returning ESP_ERR_INVALID_VERSION. I have shown that the version field contains a non-zero value.

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

Re: working with efuses

Postby WiFive » Thu Jul 25, 2019 1:45 am

Do you need packed attribute to ensure struct is not padded?

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 2:22 am

I didn't think so, but I'll try again in the morning with the attribute and report back. Thanks...

Who is online

Users browsing this forum: No registered users and 106 guests