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);
}
...
Any idea what I'm doing wrong? Running V3.3.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.
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...