Skip to content

Commit 985af73

Browse files
committed
feat: Improve reading efuses
1 parent 8aa91ef commit 985af73

File tree

10 files changed

+760
-89
lines changed

10 files changed

+760
-89
lines changed

espflash/src/cli/monitor/parser/esp_defmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl InputParser for EspDefmt {
231231
if let Ok(frame) = decoder.decode() {
232232
self.defmt_data.print(frame, out);
233233
} else {
234-
log::warn!("Failed to decode defmt frame");
234+
warn!("Failed to decode defmt frame");
235235
}
236236
}
237237
FrameKind::Raw(bytes) => out.write_all(bytes).unwrap(),

espflash/src/targets/esp32.rs

+160-28
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
#[cfg(feature = "serialport")]
2+
use std::collections::HashMap;
13
use std::ops::Range;
24

35
#[cfg(feature = "serialport")]
4-
use crate::{connection::Connection, targets::bytes_to_mac_addr};
6+
use crate::connection::Connection;
57
use crate::{
68
flasher::{FlashData, FlashFrequency},
79
image_format::IdfBootloaderFormat,
8-
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
10+
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
911
Error,
1012
};
1113

@@ -38,19 +40,151 @@ impl Esp32 {
3840
#[cfg(feature = "serialport")]
3941
/// Return the package version based on the eFuses
4042
fn package_version(&self, connection: &mut Connection) -> Result<u32, Error> {
41-
let word3 = self.read_efuse(connection, 3)?;
42-
43-
let pkg_version = (word3 >> 9) & 0x7;
44-
let pkg_version = pkg_version + (((word3 >> 2) & 0x1) << 3);
43+
let fields = self.common_fields();
44+
let pkg_version = self.read_field(connection, fields["CHIP_VER_PKG"])?;
45+
let pkg_version_4bit = self.read_field(connection, fields["CHIP_VER_PKG_4BIT"])?;
4546

46-
Ok(pkg_version)
47+
Ok(pkg_version + (pkg_version_4bit << 3))
4748
}
4849
}
4950

5051
impl ReadEFuse for Esp32 {
5152
fn efuse_reg(&self) -> u32 {
5253
0x3ff5_a000
5354
}
55+
56+
#[cfg(feature = "serialport")]
57+
fn common_fields(&self) -> HashMap<&'static str, EfuseField> {
58+
let mut fields = HashMap::new();
59+
60+
// MAC address fields
61+
fields.insert(
62+
"MAC_FACTORY_0",
63+
EfuseField {
64+
word_offset: 1,
65+
bit_offset: 0,
66+
bit_count: 32,
67+
},
68+
);
69+
fields.insert(
70+
"MAC_FACTORY_1",
71+
EfuseField {
72+
word_offset: 2,
73+
bit_offset: 0,
74+
bit_count: 16,
75+
},
76+
);
77+
78+
// Chip version fields
79+
fields.insert(
80+
"CHIP_VER_REV1",
81+
EfuseField {
82+
word_offset: 3,
83+
bit_offset: 15,
84+
bit_count: 1,
85+
},
86+
);
87+
fields.insert(
88+
"CHIP_VERSION",
89+
EfuseField {
90+
word_offset: 3,
91+
bit_offset: 12,
92+
bit_count: 2,
93+
},
94+
);
95+
fields.insert(
96+
"CHIP_VER_REV2",
97+
EfuseField {
98+
word_offset: 5,
99+
bit_offset: 20,
100+
bit_count: 1,
101+
},
102+
);
103+
fields.insert(
104+
"CHIP_CPU_FREQ_RATED",
105+
EfuseField {
106+
word_offset: 3,
107+
bit_offset: 13,
108+
bit_count: 1,
109+
},
110+
);
111+
fields.insert(
112+
"CHIP_CPU_FREQ_LOW",
113+
EfuseField {
114+
word_offset: 3,
115+
bit_offset: 12,
116+
bit_count: 1,
117+
},
118+
);
119+
fields.insert(
120+
"CHIP_VER_PKG",
121+
EfuseField {
122+
word_offset: 3,
123+
bit_offset: 9,
124+
bit_count: 3,
125+
},
126+
);
127+
fields.insert(
128+
"CHIP_VER_PKG_4BIT",
129+
EfuseField {
130+
word_offset: 3,
131+
bit_offset: 2,
132+
bit_count: 1,
133+
},
134+
);
135+
fields.insert(
136+
"CODING_SCHEME",
137+
EfuseField {
138+
word_offset: 6,
139+
bit_offset: 0,
140+
bit_count: 2,
141+
},
142+
);
143+
144+
// Feature bits
145+
fields.insert(
146+
"CHIP_VER_DIS_APP_CPU",
147+
EfuseField {
148+
word_offset: 3,
149+
bit_offset: 0,
150+
bit_count: 1,
151+
},
152+
);
153+
fields.insert(
154+
"CHIP_VER_DIS_BT",
155+
EfuseField {
156+
word_offset: 3,
157+
bit_offset: 1,
158+
bit_count: 1,
159+
},
160+
);
161+
fields.insert(
162+
"ADC_VREF",
163+
EfuseField {
164+
word_offset: 4,
165+
bit_offset: 8,
166+
bit_count: 1,
167+
},
168+
);
169+
fields.insert(
170+
"BLK3_PART_RESERVE",
171+
EfuseField {
172+
word_offset: 3,
173+
bit_offset: 14,
174+
bit_count: 1,
175+
},
176+
);
177+
fields.insert(
178+
"MINOR_VERSION",
179+
EfuseField {
180+
word_offset: 5,
181+
bit_offset: 24,
182+
bit_count: 2,
183+
},
184+
);
185+
186+
fields
187+
}
54188
}
55189

56190
impl Target for Esp32 {
@@ -60,27 +194,25 @@ impl Target for Esp32 {
60194

61195
#[cfg(feature = "serialport")]
62196
fn chip_features(&self, connection: &mut Connection) -> Result<Vec<&str>, Error> {
63-
let word3 = self.read_efuse(connection, 3)?;
64-
let word4 = self.read_efuse(connection, 4)?;
65-
let word6 = self.read_efuse(connection, 6)?;
197+
let fields = self.common_fields();
66198

67199
let mut features = vec!["WiFi"];
68200

69-
let chip_ver_dis_bt = word3 & 0x2;
201+
let chip_ver_dis_bt = self.read_field(connection, fields["CHIP_VER_DIS_BT"])?;
70202
if chip_ver_dis_bt == 0 {
71203
features.push("BT");
72204
}
73205

74-
let chip_ver_dis_app_cpu = word3 & 0x1;
206+
let chip_ver_dis_app_cpu = self.read_field(connection, fields["CHIP_VER_DIS_APP_CPU"])?;
75207
if chip_ver_dis_app_cpu == 0 {
76208
features.push("Dual Core");
77209
} else {
78210
features.push("Single Core");
79211
}
80212

81-
let chip_cpu_freq_rated = word3 & (1 << 13);
213+
let chip_cpu_freq_rated = self.read_field(connection, fields["CHIP_CPU_FREQ_RATED"])?;
82214
if chip_cpu_freq_rated != 0 {
83-
let chip_cpu_freq_low = word3 & (1 << 12);
215+
let chip_cpu_freq_low = self.read_field(connection, fields["CHIP_CPU_FREQ_LOW"])?;
84216
if chip_cpu_freq_low != 0 {
85217
features.push("160MHz");
86218
} else {
@@ -96,17 +228,17 @@ impl Target for Esp32 {
96228
features.push("Embedded PSRAM");
97229
}
98230

99-
let adc_vref = (word4 >> 8) & 0x1;
231+
let adc_vref = self.read_field(connection, fields["ADC_VREF"])?;
100232
if adc_vref != 0 {
101233
features.push("VRef calibration in efuse");
102234
}
103235

104-
let blk3_part_res = (word3 >> 14) & 0x1;
236+
let blk3_part_res = self.read_field(connection, fields["BLK3_PART_RESERVE"])?;
105237
if blk3_part_res != 0 {
106238
features.push("BLK3 partially reserved");
107239
}
108240

109-
let coding_scheme = word6 & 0x3;
241+
let coding_scheme = self.read_field(connection, fields["CODING_SCHEME"])?;
110242
features.push(match coding_scheme {
111243
0 => "Coding Scheme None",
112244
1 => "Coding Scheme 3/4",
@@ -120,9 +252,10 @@ impl Target for Esp32 {
120252
#[cfg(feature = "serialport")]
121253
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
122254
let apb_ctl_date = connection.read_reg(0x3FF6_607C)?;
255+
let fields = self.common_fields();
123256

124-
let rev_bit0 = (self.read_efuse(connection, 3)? >> 15) & 0x1;
125-
let rev_bit1 = (self.read_efuse(connection, 5)? >> 20) & 0x1;
257+
let rev_bit0 = self.read_field(connection, fields["CHIP_VER_REV1"])?;
258+
let rev_bit1 = self.read_field(connection, fields["CHIP_VER_REV2"])?;
126259
let rev_bit2 = (apb_ctl_date >> 31) & 0x1;
127260

128261
let combine_value = (rev_bit2 << 2) | (rev_bit1 << 1) | rev_bit0;
@@ -137,7 +270,8 @@ impl Target for Esp32 {
137270

138271
#[cfg(feature = "serialport")]
139272
fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
140-
Ok((self.read_efuse(connection, 5)? >> 24) & 0x3)
273+
let fields = self.common_fields();
274+
self.read_field(connection, fields["MINOR_VERSION"])
141275
}
142276

143277
#[cfg(feature = "serialport")]
@@ -189,14 +323,12 @@ impl Target for Esp32 {
189323

190324
#[cfg(feature = "serialport")]
191325
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
192-
let word1 = self.read_efuse(connection, 1)?;
193-
let word2 = self.read_efuse(connection, 2)?;
194-
195-
let words = ((word2 as u64) << 32) | word1 as u64;
196-
let bytes = words.to_be_bytes();
197-
let bytes = &bytes[2..8];
198-
199-
Ok(bytes_to_mac_addr(bytes))
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+
)
200332
}
201333

202334
fn spi_registers(&self) -> SpiRegisters {

espflash/src/targets/esp32c2.rs

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

35
use log::debug;
46

57
#[cfg(feature = "serialport")]
6-
use crate::{connection::Connection, targets::bytes_to_mac_addr};
8+
use crate::connection::Connection;
79
use crate::{
810
flasher::{FlashData, FlashFrequency},
911
image_format::IdfBootloaderFormat,
10-
targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
12+
targets::{Chip, EfuseField, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency},
1113
Error,
1214
};
1315

@@ -46,6 +48,49 @@ impl ReadEFuse for Esp32c2 {
4648
fn efuse_reg(&self) -> u32 {
4749
0x6000_8800
4850
}
51+
52+
#[cfg(feature = "serialport")]
53+
fn common_fields(&self) -> HashMap<&'static str, EfuseField> {
54+
let mut fields = HashMap::new();
55+
56+
// MAC address fields
57+
fields.insert(
58+
"MAC_FACTORY_0",
59+
EfuseField {
60+
word_offset: 16,
61+
bit_offset: 0,
62+
bit_count: 32,
63+
},
64+
);
65+
fields.insert(
66+
"MAC_FACTORY_1",
67+
EfuseField {
68+
word_offset: 17,
69+
bit_offset: 0,
70+
bit_count: 16,
71+
},
72+
);
73+
74+
// Chip version fields
75+
fields.insert(
76+
"MAJOR_VERSION",
77+
EfuseField {
78+
word_offset: 17,
79+
bit_offset: 20,
80+
bit_count: 2,
81+
},
82+
);
83+
fields.insert(
84+
"MINOR_VERSION",
85+
EfuseField {
86+
word_offset: 17,
87+
bit_offset: 16,
88+
bit_count: 4,
89+
},
90+
);
91+
92+
fields
93+
}
4994
}
5095

5196
impl Target for Esp32c2 {
@@ -60,12 +105,14 @@ impl Target for Esp32c2 {
60105

61106
#[cfg(feature = "serialport")]
62107
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
63-
Ok((self.read_efuse(connection, 17)? >> 20) & 0x3)
108+
let fields = self.common_fields();
109+
self.read_field(connection, fields["MAJOR_VERSION"])
64110
}
65111

66112
#[cfg(feature = "serialport")]
67113
fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
68-
Ok((self.read_efuse(connection, 17)? >> 16) & 0xf)
114+
let fields = self.common_fields();
115+
self.read_field(connection, fields["MINOR_VERSION"])
69116
}
70117

71118
#[cfg(feature = "serialport")]
@@ -128,14 +175,12 @@ impl Target for Esp32c2 {
128175
#[cfg(feature = "serialport")]
129176
/// What is the MAC address?
130177
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
131-
let word5 = self.read_efuse(connection, 16)?;
132-
let word6 = self.read_efuse(connection, 17)?;
133-
134-
let bytes = ((word6 as u64) << 32) | word5 as u64;
135-
let bytes = bytes.to_be_bytes();
136-
let bytes = &bytes[2..];
137-
138-
Ok(bytes_to_mac_addr(bytes))
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+
)
139184
}
140185

141186
fn spi_registers(&self) -> SpiRegisters {

0 commit comments

Comments
 (0)