From c37df81da24b461666ddc9a1d928ef43b4893ba5 Mon Sep 17 00:00:00 2001 From: Eagle Claw <301410538+ladyada-eagleclaw@users.noreply.github.com> Date: Fri, 2 Oct 2026 19:53:03 -0400 Subject: [PATCH 1/3] Initialize ESP32-P4 unique ID from its factory MAC The P4 implementation previously returned without writing raw_id, causing uninitialized USB serial numbers that changed between firmware builds. Read the factory MAC using ESP-IDF. Verified the UID matches the ROM downloader and all six P4 boards build. Co-authored-by: Limor Fried --- ports/espressif/common-hal/microcontroller/Processor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/espressif/common-hal/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 26cec5eb467..0b117ec779a 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -15,6 +15,7 @@ #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" +#include "esp_mac.h" #include "esp_sleep.h" #include "esp_system.h" #include "esp_pm.h" @@ -161,8 +162,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mac_address_part >>= 8; *ptr-- = swap_nibbles(mac_address_part & 0xff); #else - // TODO: Get UID for ESP32-P4. - return; + CHECK_ESP_RESULT(esp_efuse_mac_get_default(raw_id)); #endif } From 513a55f64ce28620a4aa5cb597063cd33927f55c Mon Sep 17 00:00:00 2001 From: Eagle Claw <301410538+ladyada-eagleclaw@users.noreply.github.com> Date: Mon, 5 Oct 2026 10:05:38 -0400 Subject: [PATCH 2/3] espressif: avoid raising on P4 UID read failure UID reads also run during USB descriptor setup outside the VM. Return a fully zeroed UID if the factory MAC read fails, without raising an exception or aborting startup. Co-authored-by: Limor Fried --- ports/espressif/common-hal/microcontroller/Processor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/espressif/common-hal/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 0b117ec779a..1bcade7903c 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -162,7 +162,10 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mac_address_part >>= 8; *ptr-- = swap_nibbles(mac_address_part & 0xff); #else - CHECK_ESP_RESULT(esp_efuse_mac_get_default(raw_id)); + // USB descriptor setup also calls this outside the VM, so do not raise. + if (esp_efuse_mac_get_default(raw_id) != ESP_OK) { + memset(raw_id, 0, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); + } #endif } From 4e53b0268d64fe008491171dcd5af33d3180fd15 Mon Sep 17 00:00:00 2001 From: Eagle Claw <301410538+ladyada-eagleclaw@users.noreply.github.com> Date: Mon, 5 Oct 2026 11:16:03 -0400 Subject: [PATCH 3/3] espressif: use canonical factory MACs for processor UIDs Read ESP_MAC_EFUSE_FACTORY for every Espressif target, retaining the six-byte UID on IEEE 802.15.4 chips. Remove the legacy register-specific nibble swapping so cpu.uid, boot output, and USB serials use factory MAC order. Return zeros on read failure without raising outside the VM. Co-authored-by: Limor Fried --- .../common-hal/microcontroller/Processor.c | 55 +------------------ 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/ports/espressif/common-hal/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 1bcade7903c..54592bbdf78 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -20,8 +20,6 @@ #include "esp_system.h" #include "esp_pm.h" -#include "soc/efuse_reg.h" - #if !defined(CONFIG_IDF_TARGET_ESP32) #include "driver/temperature_sensor.h" #endif @@ -112,61 +110,12 @@ void common_hal_mcu_processor_set_frequency(mcu_processor_obj_t *self, uint32_t } #endif -#ifndef CONFIG_IDF_TARGET_ESP32P4 -static uint8_t swap_nibbles(uint8_t v) { - return ((v << 4) | (v >> 4)) & 0xff; -} -#endif - void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { - #ifndef CONFIG_IDF_TARGET_ESP32P4 - memset(raw_id, 0, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); - - uint8_t *ptr = &raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH - 1]; - // MAC address contains 48 bits (6 bytes), 32 in the low order word - - #if defined(CONFIG_IDF_TARGET_ESP32) - uint32_t mac_address_part = REG_READ(EFUSE_BLK0_RDATA1_REG); - #elif defined(CONFIG_IDF_TARGET_ESP32H2) - uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SYS_0_REG); - #elif defined(CONFIG_IDF_TARGET_ESP32C2) - uint32_t mac_address_part = REG_READ(EFUSE_RD_BLK2_DATA0_REG); - #elif defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32C5) - uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SYS0_REG); - #else - uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SPI_SYS_0_REG); - #endif - - *ptr-- = swap_nibbles(mac_address_part & 0xff); - mac_address_part >>= 8; - *ptr-- = swap_nibbles(mac_address_part & 0xff); - mac_address_part >>= 8; - *ptr-- = swap_nibbles(mac_address_part & 0xff); - mac_address_part >>= 8; - *ptr-- = swap_nibbles(mac_address_part & 0xff); - - // and 16 in the high order word - #if defined(CONFIG_IDF_TARGET_ESP32) - mac_address_part = REG_READ(EFUSE_BLK0_RDATA2_REG); - #elif defined(CONFIG_IDF_TARGET_ESP32H2) - mac_address_part = REG_READ(EFUSE_RD_MAC_SYS_1_REG); - #elif defined(CONFIG_IDF_TARGET_ESP32C2) - mac_address_part = REG_READ(EFUSE_RD_BLK2_DATA1_REG); - #elif defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32C5) - mac_address_part = REG_READ(EFUSE_RD_MAC_SYS1_REG); - #else - mac_address_part = REG_READ(EFUSE_RD_MAC_SPI_SYS_1_REG); - #endif - - *ptr-- = swap_nibbles(mac_address_part & 0xff); - mac_address_part >>= 8; - *ptr-- = swap_nibbles(mac_address_part & 0xff); - #else + // The factory MAC is six bytes even on IEEE 802.15.4 chips. // USB descriptor setup also calls this outside the VM, so do not raise. - if (esp_efuse_mac_get_default(raw_id) != ESP_OK) { + if (esp_read_mac(raw_id, ESP_MAC_EFUSE_FACTORY) != ESP_OK) { memset(raw_id, 0, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); } - #endif } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {