Option to ignore CRC for EFuse MAC address (#2399)

* Accept changes as proposed by black.

* Added test and implemented optional correctly.

* Disable PHY RF full calibration (because it calls the breaking MAC retrieval function).

* Disable CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE instead of enable, dummy!

* Rename CONF_IGNORE_EFUSE_MAC_CRC to CONF_ESP32_IGNORE_EFUSE_MAC_CRC.

* Removed unused import.

* Fix ordering of constants.

* Moved all MAC address logic to core helpers.

* Use pretty MAC address for the log.

* Use standard MAC formatter function for debug component.

* Fix clang-formatting.

* Fix clang-formatting.

* Brought wording of comments in line with other function-describing comments.

* Processed code review by @OttoWinter

* Add USE_ESP32_IGNORE_EFUSE_MAC_CRC to defines.h

Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
This commit is contained in:
Maurice Makaay 2021-09-30 18:08:15 +02:00 committed by GitHub
parent 1031ea4313
commit c89018a431
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 14 deletions

View File

@ -104,10 +104,7 @@ void DebugComponent::dump_config() {
ESP_LOGD(TAG, "ESP-IDF Version: %s", esp_get_idf_version());
uint64_t chip_mac = 0LL;
esp_efuse_mac_get_default((uint8_t *) (&chip_mac));
std::string mac = uint64_to_string(chip_mac);
ESP_LOGD(TAG, "EFuse MAC: %s", mac.c_str());
ESP_LOGD(TAG, "EFuse MAC: %s", get_mac_address_pretty().c_str());
const char *reset_reason;
switch (rtc_get_reset_reason(0)) {

View File

@ -10,6 +10,8 @@ from esphome.const import (
CONF_TYPE,
CONF_VARIANT,
CONF_VERSION,
CONF_ADVANCED,
CONF_IGNORE_EFUSE_MAC_CRC,
KEY_CORE,
KEY_FRAMEWORK_VERSION,
KEY_TARGET_FRAMEWORK,
@ -230,6 +232,11 @@ ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
cv.string_strict: cv.string_strict
},
cv.Optional(CONF_PLATFORM_VERSION): cv.string_strict,
cv.Optional(CONF_ADVANCED, default={}): cv.Schema(
{
cv.Optional(CONF_IGNORE_EFUSE_MAC_CRC, default=False): cv.boolean,
}
),
}
),
_esp_idf_check_versions,
@ -295,6 +302,12 @@ async def to_code(config):
for name, value in conf[CONF_SDKCONFIG_OPTIONS].items():
add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
if conf[CONF_ADVANCED][CONF_IGNORE_EFUSE_MAC_CRC]:
cg.add_define("USE_ESP32_IGNORE_EFUSE_MAC_CRC")
add_idf_sdkconfig_option(
"CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE", False
)
elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
cg.add_platformio_option(
"platform", f"espressif32 @ {conf[CONF_PLATFORM_VERSION]}"

View File

@ -110,6 +110,12 @@ void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, voi
}
void WiFiComponent::wifi_pre_setup_() {
#ifdef USE_ESP32_IGNORE_EFUSE_MAC_CRC
uint8_t mac[6];
get_mac_address_raw(mac);
set_mac_address(mac);
ESP_LOGV(TAG, "Use EFuse MAC without checking CRC: %s", get_mac_address_pretty().c_str());
#endif
esp_err_t err = esp_netif_init();
if (err != ERR_OK) {
ESP_LOGE(TAG, "esp_netif_init failed: %s", esp_err_to_name(err));

View File

@ -42,6 +42,7 @@ CONF_ACTION_ID = "action_id"
CONF_ACTIVE_POWER = "active_power"
CONF_ADDRESS = "address"
CONF_ADDRESSABLE_LIGHT_ID = "addressable_light_id"
CONF_ADVANCED = "advanced"
CONF_ALPHA = "alpha"
CONF_ALTITUDE = "altitude"
CONF_AND = "and"
@ -281,6 +282,7 @@ CONF_IDLE_ACTION = "idle_action"
CONF_IDLE_LEVEL = "idle_level"
CONF_IDLE_TIME = "idle_time"
CONF_IF = "if"
CONF_IGNORE_EFUSE_MAC_CRC = "ignore_efuse_mac_crc"
CONF_IIR_FILTER = "iir_filter"
CONF_ILLUMINANCE = "illuminance"
CONF_IMPEDANCE = "impedance"

View File

@ -50,6 +50,7 @@
#ifdef USE_ESP32
#define USE_ESP32_BLE_SERVER
#define USE_ESP32_CAMERA
#define USE_ESP32_IGNORE_EFUSE_MAC_CRC
#define USE_IMPROV
#define USE_SOCKET_IMPL_BSD_SOCKETS

View File

@ -1,4 +1,5 @@
#include "esphome/core/helpers.h"
#include "esphome/core/defines.h"
#include <cstdio>
#include <algorithm>
#include <cmath>
@ -14,6 +15,10 @@
#include <freertos/FreeRTOS.h>
#include <freertos/portmacro.h>
#endif
#ifdef USE_ESP32_IGNORE_EFUSE_MAC_CRC
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#endif
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
@ -22,15 +27,27 @@ namespace esphome {
static const char *const TAG = "helpers";
std::string get_mac_address() {
char tmp[20];
uint8_t mac[6];
void get_mac_address_raw(uint8_t *mac) {
#ifdef USE_ESP32
#ifdef USE_ESP32_IGNORE_EFUSE_MAC_CRC
// On some devices, the MAC address that is burnt into EFuse does not
// match the CRC that goes along with it. For those devices, this
// work-around reads and uses the MAC address as-is from EFuse,
// without doing the CRC check.
esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, mac, 48);
#else
esp_efuse_mac_get_default(mac);
#endif
#endif
#ifdef USE_ESP8266
WiFi.macAddress(mac);
#endif
}
std::string get_mac_address() {
char tmp[20];
uint8_t mac[6];
get_mac_address_raw(mac);
sprintf(tmp, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return std::string(tmp);
}
@ -38,16 +55,15 @@ std::string get_mac_address() {
std::string get_mac_address_pretty() {
char tmp[20];
uint8_t mac[6];
#ifdef USE_ESP32
esp_efuse_mac_get_default(mac);
#endif
#ifdef USE_ESP8266
WiFi.macAddress(mac);
#endif
get_mac_address_raw(mac);
sprintf(tmp, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return std::string(tmp);
}
#ifdef USE_ESP32
void set_mac_address(uint8_t *mac) { esp_base_mac_addr_set(mac); }
#endif
std::string generate_hostname(const std::string &base) { return base + std::string("-") + get_mac_address(); }
uint32_t random_uint32() {

View File

@ -26,11 +26,21 @@ namespace esphome {
/// The characters that are allowed in a hostname.
extern const char *const HOSTNAME_CHARACTER_ALLOWLIST;
/// Gets the MAC address as a string, this can be used as way to identify this ESP.
/// Read the raw MAC address into the provided byte array (6 bytes).
void get_mac_address_raw(uint8_t *mac);
/// Get the MAC address as a string, using lower case hex notation.
/// This can be used as way to identify this ESP.
std::string get_mac_address();
/// Get the MAC address as a string, using colon-separated upper case hex notation.
std::string get_mac_address_pretty();
#ifdef USE_ESP32
/// Set the MAC address to use from the provided byte array (6 bytes).
void set_mac_address(uint8_t *mac);
#endif
std::string to_string(const std::string &val);
std::string to_string(int val);
std::string to_string(long val); // NOLINT

View File

@ -9,6 +9,8 @@ esp32:
board: nodemcu-32s
framework:
type: esp-idf
advanced:
ignore_efuse_mac_crc: true
wifi:
networks: