Skip to content

Commit 63b5cff

Browse files
Merge pull request #2 from jessebraham/feat/efuses
Simplify the `ReadEfuse` trait
2 parents 985af73 + c7c80e1 commit 63b5cff

File tree

9 files changed

+44
-164
lines changed

9 files changed

+44
-164
lines changed

espflash/src/targets/esp32.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::collections::HashMap;
33
use std::ops::Range;
44

55
#[cfg(feature = "serialport")]
6-
use crate::connection::Connection;
6+
use crate::{connection::Connection, targets::EfuseField};
77
use crate::{
88
flasher::{FlashData, FlashFrequency},
99
image_format::IdfBootloaderFormat,
10-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1111
Error,
1212
};
1313

@@ -321,16 +321,6 @@ impl Target for Esp32 {
321321
IdfBootloaderFormat::new(elf_data, Chip::Esp32, flash_data, params)
322322
}
323323

324-
#[cfg(feature = "serialport")]
325-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
326-
let fields = self.common_fields();
327-
self.read_mac_address_from_words(
328-
connection,
329-
fields["MAC_FACTORY_0"],
330-
fields["MAC_FACTORY_1"],
331-
)
332-
}
333-
334324
fn spi_registers(&self) -> SpiRegisters {
335325
SpiRegisters {
336326
base: 0x3ff4_2000,

espflash/src/targets/esp32c2.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
#[cfg(feature = "serialport")]
2-
use std::collections::HashMap;
3-
use std::ops::Range;
1+
use std::{collections::HashMap, ops::Range};
42

53
use log::debug;
64

75
#[cfg(feature = "serialport")]
8-
use crate::connection::Connection;
6+
use crate::{connection::Connection, targets::EfuseField};
97
use crate::{
108
flasher::{FlashData, FlashFrequency},
119
image_format::IdfBootloaderFormat,
12-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1311
Error,
1412
};
1513

@@ -172,17 +170,6 @@ impl Target for Esp32c2 {
172170
IdfBootloaderFormat::new(elf_data, Chip::Esp32c2, flash_data, params)
173171
}
174172

175-
#[cfg(feature = "serialport")]
176-
/// What is the MAC address?
177-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
178-
let fields = self.common_fields();
179-
self.read_mac_address_from_words(
180-
connection,
181-
fields["MAC_FACTORY_0"],
182-
fields["MAC_FACTORY_1"],
183-
)
184-
}
185-
186173
fn spi_registers(&self) -> SpiRegisters {
187174
SpiRegisters {
188175
base: 0x6000_2000,

espflash/src/targets/esp32c3.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::collections::HashMap;
33
use std::ops::Range;
44

55
#[cfg(feature = "serialport")]
6-
use crate::connection::Connection;
6+
use crate::{connection::Connection, targets::EfuseField};
77
use crate::{
88
flasher::{FlashData, FlashFrequency},
99
image_format::IdfBootloaderFormat,
10-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1111
Error,
1212
};
1313

@@ -168,16 +168,6 @@ impl Target for Esp32c3 {
168168
"riscv32imc-unknown-none-elf",
169169
]
170170
}
171-
172-
#[cfg(feature = "serialport")]
173-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
174-
let fields = self.common_fields();
175-
self.read_mac_address_from_words(
176-
connection,
177-
fields["MAC_FACTORY_0"],
178-
fields["MAC_FACTORY_1"],
179-
)
180-
}
181171
}
182172

183173
#[cfg(feature = "serialport")]

espflash/src/targets/esp32c6.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::collections::HashMap;
33
use std::ops::Range;
44

55
#[cfg(feature = "serialport")]
6-
use crate::connection::Connection;
6+
use crate::{connection::Connection, targets::EfuseField};
77
use crate::{
88
flasher::{FlashData, FlashFrequency},
99
image_format::IdfBootloaderFormat,
10-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1111
Error,
1212
};
1313

@@ -159,14 +159,4 @@ impl Target for Esp32c6 {
159159
fn supported_build_targets(&self) -> &[&str] {
160160
&["riscv32imac-esp-espidf", "riscv32imac-unknown-none-elf"]
161161
}
162-
163-
#[cfg(feature = "serialport")]
164-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
165-
let fields = self.common_fields();
166-
self.read_mac_address_from_words(
167-
connection,
168-
fields["MAC_FACTORY_0"],
169-
fields["MAC_FACTORY_1"],
170-
)
171-
}
172162
}

espflash/src/targets/esp32h2.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::{collections::HashMap, ops::Range};
22

33
#[cfg(feature = "serialport")]
4-
use crate::connection::Connection;
4+
use crate::{connection::Connection, targets::EfuseField};
55
use crate::{
66
flasher::{FlashData, FlashFrequency},
77
image_format::IdfBootloaderFormat,
8-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
8+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
99
Error,
1010
};
1111

@@ -164,14 +164,4 @@ impl Target for Esp32h2 {
164164
fn supported_build_targets(&self) -> &[&str] {
165165
&["riscv32imac-esp-espidf", "riscv32imac-unknown-none-elf"]
166166
}
167-
168-
#[cfg(feature = "serialport")]
169-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
170-
let fields = self.common_fields();
171-
self.read_mac_address_from_words(
172-
connection,
173-
fields["MAC_FACTORY_0"],
174-
fields["MAC_FACTORY_1"],
175-
)
176-
}
177167
}

espflash/src/targets/esp32p4.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::collections::HashMap;
33
use std::ops::Range;
44

55
#[cfg(feature = "serialport")]
6-
use crate::connection::Connection;
6+
use crate::{connection::Connection, targets::EfuseField};
77
use crate::{
88
flasher::{FlashData, FlashFrequency},
99
image_format::IdfBootloaderFormat,
10-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1111
Error,
1212
};
1313

@@ -148,16 +148,6 @@ impl Target for Esp32p4 {
148148
fn supported_build_targets(&self) -> &[&str] {
149149
&["riscv32imafc-esp-espidf", "riscv32imafc-unknown-none-elf"]
150150
}
151-
152-
#[cfg(feature = "serialport")]
153-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
154-
let fields = self.common_fields();
155-
self.read_mac_address_from_words(
156-
connection,
157-
fields["MAC_FACTORY_0"],
158-
fields["MAC_FACTORY_1"],
159-
)
160-
}
161151
}
162152

163153
#[cfg(feature = "serialport")]

espflash/src/targets/esp32s2.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use std::ops::Range;
55
#[cfg(feature = "serialport")]
66
use super::flash_target::MAX_RAM_BLOCK_SIZE;
77
#[cfg(feature = "serialport")]
8-
use crate::{connection::Connection, flasher::FLASH_WRITE_SIZE};
8+
use crate::{connection::Connection, flasher::FLASH_WRITE_SIZE, targets::EfuseField};
99
use crate::{
1010
flasher::{FlashData, FlashFrequency},
1111
image_format::IdfBootloaderFormat,
12-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
12+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1313
Error,
1414
};
1515

@@ -259,16 +259,6 @@ impl Target for Esp32s2 {
259259
fn supported_build_targets(&self) -> &[&str] {
260260
&["xtensa-esp32s2-none-elf", "xtensa-esp32s2-espidf"]
261261
}
262-
263-
#[cfg(feature = "serialport")]
264-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
265-
let fields = self.common_fields();
266-
self.read_mac_address_from_words(
267-
connection,
268-
fields["MAC_FACTORY_0"],
269-
fields["MAC_FACTORY_1"],
270-
)
271-
}
272262
}
273263

274264
#[cfg(feature = "serialport")]

espflash/src/targets/esp32s3.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::collections::HashMap;
33
use std::ops::Range;
44

55
#[cfg(feature = "serialport")]
6-
use crate::connection::Connection;
6+
use crate::{connection::Connection, targets::EfuseField};
77
use crate::{
88
flasher::{FlashData, FlashFrequency},
99
image_format::IdfBootloaderFormat,
10-
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1111
Error,
1212
};
1313

@@ -203,16 +203,6 @@ impl Target for Esp32s3 {
203203
fn supported_build_targets(&self) -> &[&str] {
204204
&["xtensa-esp32s3-none-elf", "xtensa-esp32s3-espidf"]
205205
}
206-
207-
#[cfg(feature = "serialport")]
208-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
209-
let fields = self.common_fields();
210-
self.read_mac_address_from_words(
211-
connection,
212-
fields["MAC_FACTORY_0"],
213-
fields["MAC_FACTORY_1"],
214-
)
215-
}
216206
}
217207

218208
#[cfg(feature = "serialport")]

espflash/src/targets/mod.rs

+27-64
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ pub trait ReadEFuse {
311311
/// Returns the base address of the eFuse register
312312
fn efuse_reg(&self) -> u32;
313313

314+
#[cfg(feature = "serialport")]
315+
/// Return fields common to most/all chips
316+
fn common_fields(&self) -> HashMap<&'static str, EfuseField>;
317+
314318
#[cfg(feature = "serialport")]
315319
/// Given an active connection, read the nth word of the eFuse region
316320
fn read_efuse(&self, connection: &mut Connection, n: u32) -> Result<u32, Error> {
@@ -319,75 +323,22 @@ pub trait ReadEFuse {
319323
}
320324

321325
#[cfg(feature = "serialport")]
322-
/// Read an eFuse field defined by its position parameters
323-
fn read_efuse_field(
324-
&self,
325-
connection: &mut Connection,
326-
word_offset: u32,
327-
bit_offset: u32,
328-
bit_count: u32,
329-
) -> Result<u32, Error> {
326+
/// Read an eFuse field defined by a structured EfuseField
327+
fn read_field(&self, connection: &mut Connection, field: EfuseField) -> Result<u32, Error> {
328+
let EfuseField {
329+
word_offset,
330+
bit_offset,
331+
bit_count,
332+
} = field;
333+
330334
let value = self.read_efuse(connection, word_offset)?;
331335
let mask = if bit_count == 32 {
332-
0xFFFF_FFFF
336+
u32::MAX
333337
} else {
334338
(1 << bit_count) - 1
335339
};
336-
Ok((value >> bit_offset) & mask)
337-
}
338340

339-
#[cfg(feature = "serialport")]
340-
/// Read an eFuse field defined by a structured EfuseField
341-
fn read_field(&self, connection: &mut Connection, field: EfuseField) -> Result<u32, Error> {
342-
self.read_efuse_field(
343-
connection,
344-
field.word_offset,
345-
field.bit_offset,
346-
field.bit_count,
347-
)
348-
}
349-
350-
#[cfg(feature = "serialport")]
351-
/// Read a MAC address from eFuse fields
352-
fn read_mac_address(
353-
&self,
354-
connection: &mut Connection,
355-
fields: &[EfuseField; 6],
356-
) -> Result<String, Error> {
357-
let mut mac_bytes = [0u8; 6];
358-
359-
for (i, field) in fields.iter().enumerate() {
360-
let byte_value = self.read_field(connection, *field)? as u8;
361-
mac_bytes[i] = byte_value;
362-
}
363-
364-
Ok(bytes_to_mac_addr(&mac_bytes))
365-
}
366-
367-
#[cfg(feature = "serialport")]
368-
/// Read a MAC address using word-based fields
369-
fn read_mac_address_from_words(
370-
&self,
371-
connection: &mut Connection,
372-
word_field_1: EfuseField,
373-
word_field_2: EfuseField,
374-
) -> Result<String, Error> {
375-
let word1 = self.read_field(connection, word_field_1)?;
376-
let word2 = self.read_field(connection, word_field_2)?;
377-
378-
let bytes = ((word2 as u64) << 32) | word1 as u64;
379-
let bytes = bytes.to_be_bytes();
380-
// Skip first two bytes as MAC address is typically stored in the last 6 bytes
381-
let mac_bytes = &bytes[2..8];
382-
383-
Ok(bytes_to_mac_addr(mac_bytes))
384-
}
385-
386-
#[cfg(feature = "serialport")]
387-
/// Return fields common to most/all chips
388-
fn common_fields(&self) -> HashMap<&'static str, EfuseField> {
389-
HashMap::new() // Default empty implementation, to be overridden by
390-
// chips
341+
Ok((value >> bit_offset) & mask)
391342
}
392343
}
393344

@@ -445,7 +396,19 @@ pub trait Target: ReadEFuse {
445396

446397
#[cfg(feature = "serialport")]
447398
/// What is the MAC address?
448-
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error>;
399+
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
400+
let fields = self.common_fields();
401+
402+
let word1 = self.read_field(connection, fields["MAC_FACTORY_0"])?;
403+
let word2 = self.read_field(connection, fields["MAC_FACTORY_1"])?;
404+
405+
let bytes = ((word2 as u64) << 32) | word1 as u64;
406+
let bytes = bytes.to_be_bytes();
407+
408+
// Skip the first two bytes, as the MAC address is typically stored in
409+
// the last 6 bytes:
410+
Ok(bytes_to_mac_addr(&bytes[2..8]))
411+
}
449412

450413
#[cfg(feature = "serialport")]
451414
/// Maximum RAM block size for writing

0 commit comments

Comments
 (0)