From f14ecbaf4cee2bfe015b29b2b7eae74ca42afc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 12:58:47 +0100 Subject: [PATCH 1/7] Fix and deprecate `read_efuse`, add `read_efuse_le` --- espflash/src/error.rs | 4 ++ espflash/src/target/mod.rs | 101 ++++++++++++++++++++++++++++++++++--- 2 files changed, 97 insertions(+), 8 deletions(-) diff --git a/espflash/src/error.rs b/espflash/src/error.rs index 2d56c617..f144b367 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -357,6 +357,10 @@ pub enum Error { /// Key is not in the expected section #[error("Misplaced key, check your configuration file. Key: {0}")] MisplacedKey(String), + + /// The efuse field is larger than 32 bit. + #[error("Requested efuse field is larger than 32 bit. Use `read_efuse_le`.")] + EfuseFieldTooLarge, } #[cfg(feature = "serialport")] diff --git a/espflash/src/target/mod.rs b/espflash/src/target/mod.rs index 101f5d90..fffc9b31 100644 --- a/espflash/src/target/mod.rs +++ b/espflash/src/target/mod.rs @@ -416,19 +416,104 @@ impl Chip { /// Given an active connection, read the specified field of the eFuse /// region. #[cfg(feature = "serialport")] + #[deprecated(note = "This only support u32. Use read_efuse_le instead.")] pub fn read_efuse(&self, connection: &mut Connection, field: EfuseField) -> Result { - let mask = if field.bit_count == 32 { - u32::MAX - } else { - (1u32 << field.bit_count) - 1 + if field.bit_count > 32 { + return Err(Error::EfuseFieldTooLarge); + } + + self.read_efuse_le::(connection, field) + } + + /// Given an active connection, read the specified field of the eFuse + /// in little endian order. + #[cfg(feature = "serialport")] + pub fn read_efuse_le( + &self, + connection: &mut Connection, + field: EfuseField, + ) -> Result { + // this is a port of the corresponding function in esp-hal + // see + let EfuseField { + block, + bit_start, + bit_count, + .. + } = field; + + fn block_address(chip: &Chip, block: u32) -> u32 { + let block0_addr = chip.efuse_reg() + chip.block0_offset(); + + let mut block_offset = 0; + for b in 0..block { + block_offset += chip.block_size(b as usize); + } + + block0_addr + block_offset + } + + fn read_raw(connection: &mut Connection, addr: u32) -> Result { + connection.read_reg(addr) + } + + // Represent output value as a bytes slice: + let mut output = std::mem::MaybeUninit::::uninit(); + let mut bytes = unsafe { + std::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, std::mem::size_of::()) }; - let shift = field.bit_start % 32; + let bit_off = bit_start as u32; + let bit_end = std::cmp::min(bit_count as u32, (bytes.len() * 8) as u32) + bit_off; + + let mut last_word_off = bit_off / 32; + let mut last_word = read_raw(connection, block_address(self, block) + last_word_off * 4)?; + + let word_bit_off = bit_off % 32; + let word_bit_ext = 32 - word_bit_off; + + let mut word_off = last_word_off; + for bit_off in (bit_off..bit_end).step_by(32) { + if word_off != last_word_off { + // Read a new word: + last_word_off = word_off; + last_word = read_raw(connection, block_address(self, block) + last_word_off * 4)?; + } + + let mut word = last_word >> word_bit_off; + word_off += 1; + + let word_bit_len = std::cmp::min(bit_end - bit_off, 32); + if word_bit_len > word_bit_ext { + // Read the next word: + last_word_off = word_off; + last_word = read_raw(connection, block_address(self, block) + last_word_off * 4)?; + // Append bits from a beginning of the next word: + word |= last_word.wrapping_shl((32 - word_bit_off) as u32); + }; + + if word_bit_len < 32 { + // Mask only needed bits of a word: + word &= u32::MAX >> (32 - word_bit_len); + } + + // Represent word as a byte slice: + let byte_len = word_bit_len.div_ceil(8); + let word_bytes = unsafe { + std::slice::from_raw_parts(&word as *const u32 as *const u8, byte_len as usize) + }; + + // Copy word bytes to output value bytes: + bytes[..byte_len as usize].copy_from_slice(word_bytes); + + // Move read window forward: + bytes = &mut bytes[(byte_len as usize)..]; + } - let value = self.read_efuse_raw(connection, field.block, field.word)?; - let value = (value >> shift) & mask; + // Fill untouched bytes with zeros: + bytes.fill(0); - Ok(value) + Ok(unsafe { output.assume_init() }) } /// Read the raw word in the specified eFuse block, without performing any From 27eb7036a068c4ff4643f926854ecf97044e1c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 13:43:26 +0100 Subject: [PATCH 2/7] Fix efuse definition gen, regen efuse data --- espflash/src/target/efuse/esp32.rs | 2 +- espflash/src/target/efuse/esp32c2.rs | 4 ++-- espflash/src/target/efuse/esp32c3.rs | 4 ++-- espflash/src/target/efuse/esp32c5.rs | 2 +- espflash/src/target/efuse/esp32c6.rs | 2 +- espflash/src/target/efuse/esp32h2.rs | 2 +- espflash/src/target/efuse/esp32p4.rs | 2 +- espflash/src/target/efuse/esp32s2.rs | 2 +- espflash/src/target/efuse/esp32s3.rs | 4 ++-- xtask/src/efuse_generator.rs | 6 +++++- 10 files changed, 17 insertions(+), 13 deletions(-) diff --git a/espflash/src/target/efuse/esp32.rs b/espflash/src/target/efuse/esp32.rs index 08810206..81d4c1e3 100644 --- a/espflash/src/target/efuse/esp32.rs +++ b/espflash/src/target/efuse/esp32.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-25 11:06 +//! Generated: 2025-11-19 12:31 //! Version: 369d2d860d34e777c0f7d545a7dfc3c4 #![allow(unused)] diff --git a/espflash/src/target/efuse/esp32c2.rs b/espflash/src/target/efuse/esp32c2.rs index 12a19be5..d4dad029 100644 --- a/espflash/src/target/efuse/esp32c2.rs +++ b/espflash/src/target/efuse/esp32c2.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-26 09:47 +//! Generated: 2025-11-19 12:31 //! Version: 897499b0349a608b895d467abbcf006b #![allow(unused)] @@ -10,7 +10,7 @@ use super::EfuseField; /// Total size in bytes of each block -pub(crate) const BLOCK_SIZES: &[u32] = &[8, 11, 32, 32]; +pub(crate) const BLOCK_SIZES: &[u32] = &[8, 12, 32, 32]; /// Disable programming of individual eFuses pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 8); diff --git a/espflash/src/target/efuse/esp32c3.rs b/espflash/src/target/efuse/esp32c3.rs index 3e570423..cfae4715 100644 --- a/espflash/src/target/efuse/esp32c3.rs +++ b/espflash/src/target/efuse/esp32c3.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-26 09:47 +//! Generated: 2025-11-19 12:31 //! Version: 4622cf9245401eca0eb1df8122449a6d #![allow(unused)] @@ -10,7 +10,7 @@ use super::EfuseField; /// Total size in bytes of each block -pub(crate) const BLOCK_SIZES: &[u32] = &[23, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32]; +pub(crate) const BLOCK_SIZES: &[u32] = &[24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32]; /// Disable programming of individual eFuses pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32); diff --git a/espflash/src/target/efuse/esp32c5.rs b/espflash/src/target/efuse/esp32c5.rs index af632a3b..af055171 100644 --- a/espflash/src/target/efuse/esp32c5.rs +++ b/espflash/src/target/efuse/esp32c5.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-26 09:47 +//! Generated: 2025-11-19 12:31 //! Version: 31c7fe3f5f4e0a55b178a57126c0aca7 #![allow(unused)] diff --git a/espflash/src/target/efuse/esp32c6.rs b/espflash/src/target/efuse/esp32c6.rs index 4adf01b1..eed1b593 100644 --- a/espflash/src/target/efuse/esp32c6.rs +++ b/espflash/src/target/efuse/esp32c6.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-25 11:06 +//! Generated: 2025-11-19 12:31 //! Version: df46b69f0ed3913114ba53d3a0b2b843 #![allow(unused)] diff --git a/espflash/src/target/efuse/esp32h2.rs b/espflash/src/target/efuse/esp32h2.rs index f1c86cb6..519167dc 100644 --- a/espflash/src/target/efuse/esp32h2.rs +++ b/espflash/src/target/efuse/esp32h2.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-25 11:06 +//! Generated: 2025-11-19 12:31 //! Version: 44563d2af4ebdba4db6c0a34a50c94f9 #![allow(unused)] diff --git a/espflash/src/target/efuse/esp32p4.rs b/espflash/src/target/efuse/esp32p4.rs index 7f40d640..73fea9b4 100644 --- a/espflash/src/target/efuse/esp32p4.rs +++ b/espflash/src/target/efuse/esp32p4.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-25 11:06 +//! Generated: 2025-11-19 12:31 //! Version: f7765f0ac3faf4b54f8c1f064307522c #![allow(unused)] diff --git a/espflash/src/target/efuse/esp32s2.rs b/espflash/src/target/efuse/esp32s2.rs index 951d9a99..ab61752b 100644 --- a/espflash/src/target/efuse/esp32s2.rs +++ b/espflash/src/target/efuse/esp32s2.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-26 09:47 +//! Generated: 2025-11-19 12:31 //! Version: 888a61f6f500d9c7ee0aa32016b0bee7 #![allow(unused)] diff --git a/espflash/src/target/efuse/esp32s3.rs b/espflash/src/target/efuse/esp32s3.rs index 1050a6b3..54e41bea 100644 --- a/espflash/src/target/efuse/esp32s3.rs +++ b/espflash/src/target/efuse/esp32s3.rs @@ -2,7 +2,7 @@ //! //! This file was automatically generated, please do not edit it manually! //! -//! Generated: 2025-06-26 09:47 +//! Generated: 2025-11-19 12:31 //! Version: 7127dd097e72bb90d0b790d460993126 #![allow(unused)] @@ -10,7 +10,7 @@ use super::EfuseField; /// Total size in bytes of each block -pub(crate) const BLOCK_SIZES: &[u32] = &[23, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32]; +pub(crate) const BLOCK_SIZES: &[u32] = &[24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32]; /// Disable programming of individual eFuses pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32); diff --git a/xtask/src/efuse_generator.rs b/xtask/src/efuse_generator.rs index 65c75ba8..c389be96 100644 --- a/xtask/src/efuse_generator.rs +++ b/xtask/src/efuse_generator.rs @@ -217,7 +217,11 @@ fn generate_efuse_block_sizes( let size_bits = last.start + last.len; assert!(size_bits % 8 == 0); - (block, size_bits / 8) + // not all bits for all blocks are defined, this is to avoid + // ending up with block sizes like 23 or 11 + // + // while this fixes the problem, it's not ideal to rely on this + (block, ((size_bits / 8).div_ceil(4)) * 4) }) .collect::>(); From 3ac0a232d8092338dbbdd91f69ac398710248289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 15:06:16 +0100 Subject: [PATCH 3/7] Don't use deprecated API ourselves --- espflash/src/target/mod.rs | 70 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/espflash/src/target/mod.rs b/espflash/src/target/mod.rs index fffc9b31..4e29f31a 100644 --- a/espflash/src/target/mod.rs +++ b/espflash/src/target/mod.rs @@ -613,12 +613,12 @@ impl Chip { Chip::Esp32 => { let mut features = vec!["WiFi"]; - let disable_bt = self.read_efuse(connection, efuse::esp32::DISABLE_BT)?; + let disable_bt = self.read_efuse_le::(connection, efuse::esp32::DISABLE_BT)?; if disable_bt == 0 { features.push("BT"); } - let disable_app_cpu = self.read_efuse(connection, efuse::esp32::DISABLE_APP_CPU)?; + let disable_app_cpu = self.read_efuse_le::(connection, efuse::esp32::DISABLE_APP_CPU)?; if disable_app_cpu == 0 { features.push("Dual Core"); } else { @@ -626,10 +626,10 @@ impl Chip { } let chip_cpu_freq_rated = - self.read_efuse(connection, efuse::esp32::CHIP_CPU_FREQ_RATED)?; + self.read_efuse_le::(connection, efuse::esp32::CHIP_CPU_FREQ_RATED)?; if chip_cpu_freq_rated != 0 { let chip_cpu_freq_low = - self.read_efuse(connection, efuse::esp32::CHIP_CPU_FREQ_LOW)?; + self.read_efuse_le::(connection, efuse::esp32::CHIP_CPU_FREQ_LOW)?; if chip_cpu_freq_low != 0 { features.push("160MHz"); } else { @@ -646,18 +646,18 @@ impl Chip { features.push("Embedded PSRAM"); } - let adc_vref = self.read_efuse(connection, efuse::esp32::ADC_VREF)?; + let adc_vref = self.read_efuse_le::(connection, efuse::esp32::ADC_VREF)?; if adc_vref != 0 { features.push("VRef calibration in efuse"); } let blk3_part_reserve = - self.read_efuse(connection, efuse::esp32::BLK3_PART_RESERVE)?; + self.read_efuse_le::(connection, efuse::esp32::BLK3_PART_RESERVE)?; if blk3_part_reserve != 0 { features.push("BLK3 partially reserved"); } - let coding_scheme = self.read_efuse(connection, efuse::esp32::CODING_SCHEME)?; + let coding_scheme = self.read_efuse_le::(connection, efuse::esp32::CODING_SCHEME)?; features.push(match coding_scheme { 0 => "Coding Scheme None", 1 => "Coding Scheme 3/4", @@ -751,27 +751,27 @@ impl Chip { _ => Ok(0), } } - Chip::Esp32c2 => self.read_efuse(connection, efuse::esp32c2::WAFER_VERSION_MAJOR), - Chip::Esp32c3 => self.read_efuse(connection, efuse::esp32c3::WAFER_VERSION_MAJOR), - Chip::Esp32c5 => self.read_efuse(connection, efuse::esp32c5::WAFER_VERSION_MAJOR), - Chip::Esp32c6 => self.read_efuse(connection, efuse::esp32c6::WAFER_VERSION_MAJOR), - Chip::Esp32h2 => self.read_efuse(connection, efuse::esp32h2::WAFER_VERSION_MAJOR), + Chip::Esp32c2 => self.read_efuse_le::(connection, efuse::esp32c2::WAFER_VERSION_MAJOR), + Chip::Esp32c3 => self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MAJOR), + Chip::Esp32c5 => self.read_efuse_le::(connection, efuse::esp32c5::WAFER_VERSION_MAJOR), + Chip::Esp32c6 => self.read_efuse_le::(connection, efuse::esp32c6::WAFER_VERSION_MAJOR), + Chip::Esp32h2 => self.read_efuse_le::(connection, efuse::esp32h2::WAFER_VERSION_MAJOR), Chip::Esp32p4 => { - let hi = self.read_efuse(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_HI)?; - let lo = self.read_efuse(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_LO)?; + let hi = self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_HI)?; + let lo = self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_LO)?; let version = (hi << 2) | lo; Ok(version) } - Chip::Esp32s2 => self.read_efuse(connection, efuse::esp32s2::WAFER_VERSION_MAJOR), + Chip::Esp32s2 => self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MAJOR), Chip::Esp32s3 => { if self.esp32s3_blk_version_major(connection)? == 1 && self.esp32s3_blk_version_minor(connection)? == 1 { Ok(0) } else { - self.read_efuse(connection, efuse::esp32s3::WAFER_VERSION_MAJOR) + self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MAJOR) } } } @@ -781,27 +781,27 @@ impl Chip { #[cfg(feature = "serialport")] pub fn minor_version(&self, connection: &mut Connection) -> Result { match self { - Chip::Esp32 => self.read_efuse(connection, efuse::esp32::WAFER_VERSION_MINOR), - Chip::Esp32c2 => self.read_efuse(connection, efuse::esp32c2::WAFER_VERSION_MINOR), + Chip::Esp32 => self.read_efuse_le::(connection, efuse::esp32::WAFER_VERSION_MINOR), + Chip::Esp32c2 => self.read_efuse_le::(connection, efuse::esp32c2::WAFER_VERSION_MINOR), Chip::Esp32c3 => { - let hi = self.read_efuse(connection, efuse::esp32c3::WAFER_VERSION_MINOR_HI)?; - let lo = self.read_efuse(connection, efuse::esp32c3::WAFER_VERSION_MINOR_LO)?; + let hi = self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MINOR_HI)?; + let lo = self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MINOR_LO)?; Ok((hi << 3) + lo) } - Chip::Esp32c5 => self.read_efuse(connection, efuse::esp32c5::WAFER_VERSION_MINOR), - Chip::Esp32c6 => self.read_efuse(connection, efuse::esp32c6::WAFER_VERSION_MINOR), - Chip::Esp32h2 => self.read_efuse(connection, efuse::esp32h2::WAFER_VERSION_MINOR), - Chip::Esp32p4 => self.read_efuse(connection, efuse::esp32p4::WAFER_VERSION_MINOR), + Chip::Esp32c5 => self.read_efuse_le::(connection, efuse::esp32c5::WAFER_VERSION_MINOR), + Chip::Esp32c6 => self.read_efuse_le::(connection, efuse::esp32c6::WAFER_VERSION_MINOR), + Chip::Esp32h2 => self.read_efuse_le::(connection, efuse::esp32h2::WAFER_VERSION_MINOR), + Chip::Esp32p4 => self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MINOR), Chip::Esp32s2 => { - let hi = self.read_efuse(connection, efuse::esp32s2::WAFER_VERSION_MINOR_HI)?; - let lo = self.read_efuse(connection, efuse::esp32s2::WAFER_VERSION_MINOR_LO)?; + let hi = self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MINOR_HI)?; + let lo = self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MINOR_LO)?; Ok((hi << 3) + lo) } Chip::Esp32s3 => { - let hi = self.read_efuse(connection, efuse::esp32s3::WAFER_VERSION_MINOR_HI)?; - let lo = self.read_efuse(connection, efuse::esp32s3::WAFER_VERSION_MINOR_LO)?; + let hi = self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MINOR_HI)?; + let lo = self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MINOR_LO)?; Ok((hi << 3) + lo) } @@ -896,8 +896,8 @@ impl Chip { Chip::Esp32s3 => (self::efuse::esp32s3::MAC0, self::efuse::esp32s3::MAC1), }; - let mac0 = self.read_efuse(connection, mac0_field)?; - let mac1 = self.read_efuse(connection, mac1_field)?; + let mac0 = self.read_efuse_le::(connection, mac0_field)?; + let mac1 = self.read_efuse_le::(connection, mac1_field)?; let bytes = ((mac1 as u64) << 32) | mac0 as u64; let bytes = bytes.to_be_bytes(); @@ -1002,31 +1002,31 @@ impl Chip { #[cfg(feature = "serialport")] /// Returns the block2 version based on eFuses for ESP32-S2 fn esp32s2_block2_version(&self, connection: &mut Connection) -> Result { - self.read_efuse(connection, efuse::esp32s2::BLK_VERSION_MINOR) + self.read_efuse_le::(connection, efuse::esp32s2::BLK_VERSION_MINOR) } #[cfg(feature = "serialport")] /// Returns the flash version based on eFuses for ESP32-S2 fn esp32s2_flash_version(&self, connection: &mut Connection) -> Result { - self.read_efuse(connection, efuse::esp32s2::FLASH_VERSION) + self.read_efuse_le::(connection, efuse::esp32s2::FLASH_VERSION) } #[cfg(feature = "serialport")] /// Returns the PSRAM version based on eFuses for ESP32-S2 fn esp32s2_psram_version(&self, connection: &mut Connection) -> Result { - self.read_efuse(connection, efuse::esp32s2::PSRAM_VERSION) + self.read_efuse_le::(connection, efuse::esp32s2::PSRAM_VERSION) } #[cfg(feature = "serialport")] /// Returns the major BLK version based on eFuses for ESP32-S3 fn esp32s3_blk_version_major(&self, connection: &mut Connection) -> Result { - self.read_efuse(connection, efuse::esp32s3::BLK_VERSION_MAJOR) + self.read_efuse_le::(connection, efuse::esp32s3::BLK_VERSION_MAJOR) } #[cfg(feature = "serialport")] /// Returns the minor BLK version based on eFuses for ESP32-S3 fn esp32s3_blk_version_minor(&self, connection: &mut Connection) -> Result { - self.read_efuse(connection, efuse::esp32s3::BLK_VERSION_MINOR) + self.read_efuse_le::(connection, efuse::esp32s3::BLK_VERSION_MINOR) } } From 81f4abb5d39741e1b35e8336fa32ea392032ba13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 15:06:24 +0100 Subject: [PATCH 4/7] Un-annoy --- espflash/src/error.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/espflash/src/error.rs b/espflash/src/error.rs index f144b367..c671fc7c 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -319,7 +319,7 @@ pub enum Error { #[error("Invalid `address`({address}) and/or `size`({size}) argument(s)")] #[diagnostic( code(espflash::erase_region::invalid_argument), - help("`address` and `size` must be multiples of 0x1000 (4096)") + help("`address` ({address}) and `size` ({size}) must be multiples of 0x1000 (4096)") )] InvalidEraseRegionArgument { /// Address argument @@ -332,7 +332,9 @@ pub enum Error { #[error("The firmware was built for {elf}, but the detected chip is {detected}")] #[diagnostic( code(espflash::chip_mismatch), - help("Ensure that the device is connected and your host recognizes the serial adapter") + help( + "Ensure that the device is connected and your host recognizes the serial adapter. (File {elf}, detected chip is {detected})" + ) )] FirmwareChipMismatch { /// Chip which the ELF file was built for From 839998882b25f07894ef935cd1c6c3370e181f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 15:07:30 +0100 Subject: [PATCH 5/7] Remove unused casts --- espflash/src/target/mod.rs | 80 ++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/espflash/src/target/mod.rs b/espflash/src/target/mod.rs index 4e29f31a..1d8f7ebd 100644 --- a/espflash/src/target/mod.rs +++ b/espflash/src/target/mod.rs @@ -463,8 +463,8 @@ impl Chip { std::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, std::mem::size_of::()) }; - let bit_off = bit_start as u32; - let bit_end = std::cmp::min(bit_count as u32, (bytes.len() * 8) as u32) + bit_off; + let bit_off = bit_start; + let bit_end = std::cmp::min(bit_count, (bytes.len() * 8) as u32) + bit_off; let mut last_word_off = bit_off / 32; let mut last_word = read_raw(connection, block_address(self, block) + last_word_off * 4)?; @@ -489,7 +489,7 @@ impl Chip { last_word_off = word_off; last_word = read_raw(connection, block_address(self, block) + last_word_off * 4)?; // Append bits from a beginning of the next word: - word |= last_word.wrapping_shl((32 - word_bit_off) as u32); + word |= last_word.wrapping_shl(32 - word_bit_off); }; if word_bit_len < 32 { @@ -618,7 +618,8 @@ impl Chip { features.push("BT"); } - let disable_app_cpu = self.read_efuse_le::(connection, efuse::esp32::DISABLE_APP_CPU)?; + let disable_app_cpu = + self.read_efuse_le::(connection, efuse::esp32::DISABLE_APP_CPU)?; if disable_app_cpu == 0 { features.push("Dual Core"); } else { @@ -657,7 +658,8 @@ impl Chip { features.push("BLK3 partially reserved"); } - let coding_scheme = self.read_efuse_le::(connection, efuse::esp32::CODING_SCHEME)?; + let coding_scheme = + self.read_efuse_le::(connection, efuse::esp32::CODING_SCHEME)?; features.push(match coding_scheme { 0 => "Coding Scheme None", 1 => "Coding Scheme 3/4", @@ -751,20 +753,34 @@ impl Chip { _ => Ok(0), } } - Chip::Esp32c2 => self.read_efuse_le::(connection, efuse::esp32c2::WAFER_VERSION_MAJOR), - Chip::Esp32c3 => self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MAJOR), - Chip::Esp32c5 => self.read_efuse_le::(connection, efuse::esp32c5::WAFER_VERSION_MAJOR), - Chip::Esp32c6 => self.read_efuse_le::(connection, efuse::esp32c6::WAFER_VERSION_MAJOR), - Chip::Esp32h2 => self.read_efuse_le::(connection, efuse::esp32h2::WAFER_VERSION_MAJOR), + Chip::Esp32c2 => { + self.read_efuse_le::(connection, efuse::esp32c2::WAFER_VERSION_MAJOR) + } + Chip::Esp32c3 => { + self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MAJOR) + } + Chip::Esp32c5 => { + self.read_efuse_le::(connection, efuse::esp32c5::WAFER_VERSION_MAJOR) + } + Chip::Esp32c6 => { + self.read_efuse_le::(connection, efuse::esp32c6::WAFER_VERSION_MAJOR) + } + Chip::Esp32h2 => { + self.read_efuse_le::(connection, efuse::esp32h2::WAFER_VERSION_MAJOR) + } Chip::Esp32p4 => { - let hi = self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_HI)?; - let lo = self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_LO)?; + let hi = + self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_HI)?; + let lo = + self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MAJOR_LO)?; let version = (hi << 2) | lo; Ok(version) } - Chip::Esp32s2 => self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MAJOR), + Chip::Esp32s2 => { + self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MAJOR) + } Chip::Esp32s3 => { if self.esp32s3_blk_version_major(connection)? == 1 && self.esp32s3_blk_version_minor(connection)? == 1 @@ -782,26 +798,42 @@ impl Chip { pub fn minor_version(&self, connection: &mut Connection) -> Result { match self { Chip::Esp32 => self.read_efuse_le::(connection, efuse::esp32::WAFER_VERSION_MINOR), - Chip::Esp32c2 => self.read_efuse_le::(connection, efuse::esp32c2::WAFER_VERSION_MINOR), + Chip::Esp32c2 => { + self.read_efuse_le::(connection, efuse::esp32c2::WAFER_VERSION_MINOR) + } Chip::Esp32c3 => { - let hi = self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MINOR_HI)?; - let lo = self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MINOR_LO)?; + let hi = + self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MINOR_HI)?; + let lo = + self.read_efuse_le::(connection, efuse::esp32c3::WAFER_VERSION_MINOR_LO)?; Ok((hi << 3) + lo) } - Chip::Esp32c5 => self.read_efuse_le::(connection, efuse::esp32c5::WAFER_VERSION_MINOR), - Chip::Esp32c6 => self.read_efuse_le::(connection, efuse::esp32c6::WAFER_VERSION_MINOR), - Chip::Esp32h2 => self.read_efuse_le::(connection, efuse::esp32h2::WAFER_VERSION_MINOR), - Chip::Esp32p4 => self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MINOR), + Chip::Esp32c5 => { + self.read_efuse_le::(connection, efuse::esp32c5::WAFER_VERSION_MINOR) + } + Chip::Esp32c6 => { + self.read_efuse_le::(connection, efuse::esp32c6::WAFER_VERSION_MINOR) + } + Chip::Esp32h2 => { + self.read_efuse_le::(connection, efuse::esp32h2::WAFER_VERSION_MINOR) + } + Chip::Esp32p4 => { + self.read_efuse_le::(connection, efuse::esp32p4::WAFER_VERSION_MINOR) + } Chip::Esp32s2 => { - let hi = self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MINOR_HI)?; - let lo = self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MINOR_LO)?; + let hi = + self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MINOR_HI)?; + let lo = + self.read_efuse_le::(connection, efuse::esp32s2::WAFER_VERSION_MINOR_LO)?; Ok((hi << 3) + lo) } Chip::Esp32s3 => { - let hi = self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MINOR_HI)?; - let lo = self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MINOR_LO)?; + let hi = + self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MINOR_HI)?; + let lo = + self.read_efuse_le::(connection, efuse::esp32s3::WAFER_VERSION_MINOR_LO)?; Ok((hi << 3) + lo) } From 0ce13e9485c1fead3f6dbcbbab3ff77b36b21657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 16:21:57 +0100 Subject: [PATCH 6/7] Changelog entries --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f3b557..4a1f4a67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,14 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- `read_efuse_le` should be preferred over `read_efuse` - A new CLI argument `rom-elf` was added which will be used for backtraces (#963) ### Changed +- `read_efuse` is deprecated ### Fixed - Corrected eFuse BLOCK0 definitions for ESP32-C2, ESP32-C3, and ESP32-S3 (#961) +- Several fixes in `read_efuse` ### Removed From b5504d385a4c6366d92846fbb5643da229005bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 19 Nov 2025 16:30:11 +0100 Subject: [PATCH 7/7] CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a1f4a67..70af60da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,17 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- `read_efuse_le` should be preferred over `read_efuse` +- `read_efuse_le` should be preferred over `read_efuse` (#969) - A new CLI argument `rom-elf` was added which will be used for backtraces (#963) ### Changed -- `read_efuse` is deprecated +- `read_efuse` is deprecated (#969) ### Fixed - Corrected eFuse BLOCK0 definitions for ESP32-C2, ESP32-C3, and ESP32-S3 (#961) -- Several fixes in `read_efuse` +- Several fixes in `read_efuse` (#969) ### Removed