Skip to content

Commit b25af06

Browse files
authored
Display the newer 'v{major}.{minor}' chip revision format (#307)
1 parent d555956 commit b25af06

File tree

9 files changed

+150
-78
lines changed

9 files changed

+150
-78
lines changed

espflash/src/error.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ https://github.com/espressif/esp32c3-direct-boot-example"
131131
chip: Chip,
132132
frequency: FlashFrequency,
133133
},
134+
#[error("The {chip} does not support {feature}")]
135+
#[diagnostic(code(espflash::unsupported_feature))]
136+
UnsupportedFeature { chip: Chip, feature: String },
134137
}
135138

136139
#[derive(Error, Debug, Diagnostic)]
@@ -449,7 +452,7 @@ impl From<u8> for FlashDetectError {
449452
pub struct UnsupportedImageFormatError {
450453
format: ImageFormatKind,
451454
chip: Chip,
452-
revision: Option<u32>,
455+
revision: Option<(u32, u32)>,
453456
}
454457

455458
impl Display for UnsupportedImageFormatError {
@@ -459,9 +462,11 @@ impl Display for UnsupportedImageFormatError {
459462
"Image format {} is not supported by the {}",
460463
self.format, self.chip
461464
)?;
462-
if let Some(revision) = self.revision {
463-
write!(f, " revision {}", revision)?;
465+
466+
if let Some((major, minor)) = self.revision {
467+
write!(f, " revision v{major}.{minor}")?;
464468
}
469+
465470
Ok(())
466471
}
467472
}
@@ -491,7 +496,7 @@ impl Diagnostic for UnsupportedImageFormatError {
491496
}
492497

493498
impl UnsupportedImageFormatError {
494-
pub fn new(format: ImageFormatKind, chip: Chip, revision: Option<u32>) -> Self {
499+
pub fn new(format: ImageFormatKind, chip: Chip, revision: Option<(u32, u32)>) -> Self {
495500
UnsupportedImageFormatError {
496501
format,
497502
chip,

espflash/src/flasher/mod.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -608,22 +608,25 @@ impl Flasher {
608608
/// Read and print any information we can about the connected board
609609
pub fn board_info(&mut self) -> Result<(), Error> {
610610
let chip = self.chip();
611-
612611
let target = chip.into_target();
613-
let maybe_revision = target.chip_revision(self.connection())?;
612+
614613
let features = target.chip_features(self.connection())?;
615614
let freq = target.crystal_freq(self.connection())?;
616615
let mac = target.mac_address(self.connection())?;
617616

618-
print!("Chip type: {}", chip);
619-
match maybe_revision {
620-
Some(revision) => println!(" (revision {})", revision),
621-
None => println!(),
617+
// The ESP8266 does not have readable major/minor revision numbers, so we have
618+
// nothing to print if targeting it.
619+
print!("Chip type: {chip}");
620+
if chip != Chip::Esp8266 {
621+
let (major, minor) = target.chip_revision(self.connection())?;
622+
println!(" (revision v{major}.{minor})");
623+
} else {
624+
println!("");
622625
}
623-
println!("Crystal frequency: {}MHz", freq);
626+
println!("Crystal frequency: {freq}MHz");
624627
println!("Flash size: {}", self.flash_size);
625628
println!("Features: {}", features.join(", "));
626-
println!("MAC address: {}", mac);
629+
println!("MAC address: {mac}");
627630

628631
Ok(())
629632
}
@@ -687,9 +690,11 @@ impl Flasher {
687690
bootloader,
688691
partition_table,
689692
image_format,
690-
self.chip
691-
.into_target()
692-
.chip_revision(&mut self.connection)?,
693+
Some(
694+
self.chip
695+
.into_target()
696+
.chip_revision(&mut self.connection)?,
697+
),
693698
flash_mode,
694699
flash_size.or(Some(self.flash_size)),
695700
flash_freq,

espflash/src/targets/esp32.rs

+16-15
Original file line numberDiff line numberDiff line change
@@ -118,24 +118,25 @@ impl Target for Esp32 {
118118
Ok(features)
119119
}
120120

121-
fn chip_revision(&self, connection: &mut Connection) -> Result<Option<u32>, Error> {
122-
let word3 = self.read_efuse(connection, 3)?;
123-
let word5 = self.read_efuse(connection, 5)?;
121+
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
122+
let apb_ctl_date = connection.read_reg(0x3FF6_607C)?;
124123

125-
let apb_ctrl_date = connection.read_reg(0x3ff6_607c)?;
124+
let rev_bit0 = (self.read_efuse(connection, 3)? >> 15) & 0x1;
125+
let rev_bit1 = (self.read_efuse(connection, 5)? >> 20) & 0x1;
126+
let rev_bit2 = (apb_ctl_date >> 31) & 0x1;
126127

127-
let rev_bit0 = (word3 >> 15) & 0x1 != 0;
128-
let rev_bit1 = (word5 >> 20) & 0x1 != 0;
129-
let rev_bit2 = (apb_ctrl_date >> 31) & 0x1 != 0;
128+
let combine_value = (rev_bit2 << 2) | (rev_bit1 << 1) | rev_bit0;
130129

131-
let revision = match (rev_bit0, rev_bit1, rev_bit2) {
132-
(true, true, true) => 3,
133-
(true, true, false) => 2,
134-
(true, false, _) => 1,
135-
(false, _, _) => 0,
136-
};
130+
match combine_value {
131+
1 => Ok(1),
132+
3 => Ok(2),
133+
7 => Ok(3),
134+
_ => Ok(0),
135+
}
136+
}
137137

138-
Ok(Some(revision))
138+
fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
139+
Ok((self.read_efuse(connection, 5)? >> 24) & 0x3)
139140
}
140141

141142
fn crystal_freq(&self, connection: &mut Connection) -> Result<u32, Error> {
@@ -152,7 +153,7 @@ impl Target for Esp32 {
152153
bootloader: Option<Vec<u8>>,
153154
partition_table: Option<PartitionTable>,
154155
image_format: Option<ImageFormatKind>,
155-
_chip_revision: Option<u32>,
156+
_chip_revision: Option<(u32, u32)>,
156157
flash_mode: Option<FlashMode>,
157158
flash_size: Option<FlashSize>,
158159
flash_freq: Option<FlashFrequency>,

espflash/src/targets/esp32c2.rs

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

33
use esp_idf_part::PartitionTable;
44

5-
use super::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target};
5+
use super::{bytes_to_mac_addr, Chip, Esp32Params, ReadEFuse, SpiRegisters, Target};
66
use crate::{
77
connection::Connection,
88
elf::FirmwareImage,
@@ -50,18 +50,15 @@ impl Target for Esp32c2 {
5050
}
5151

5252
fn chip_features(&self, _connection: &mut Connection) -> Result<Vec<&str>, Error> {
53-
Ok(vec!["WiFi"])
53+
Ok(vec!["WiFi", "BLE"])
5454
}
5555

56-
fn chip_revision(&self, connection: &mut Connection) -> Result<Option<u32>, Error> {
57-
let block1_addr = self.efuse_reg() + 0x44;
58-
let num_word = 3;
59-
let pos = 18;
60-
61-
let value = connection.read_reg(block1_addr + (num_word * 0x4))?;
62-
let value = (value & (0x7 << pos)) >> pos;
56+
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
57+
Ok(self.read_efuse(connection, 17)? >> 20 & 0x3)
58+
}
6359

64-
Ok(Some(value))
60+
fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
61+
Ok(self.read_efuse(connection, 17)? >> 16 & 0xf)
6562
}
6663

6764
fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
@@ -88,7 +85,7 @@ impl Target for Esp32c2 {
8885
bootloader: Option<Vec<u8>>,
8986
partition_table: Option<PartitionTable>,
9087
image_format: Option<ImageFormatKind>,
91-
_chip_revision: Option<u32>,
88+
_chip_revision: Option<(u32, u32)>,
9289
flash_mode: Option<FlashMode>,
9390
flash_size: Option<FlashSize>,
9491
flash_freq: Option<FlashFrequency>,
@@ -110,6 +107,18 @@ impl Target for Esp32c2 {
110107
}
111108
}
112109

110+
/// What is the MAC address?
111+
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
112+
let word5 = self.read_efuse(connection, 16)?;
113+
let word6 = self.read_efuse(connection, 17)?;
114+
115+
let bytes = ((word6 as u64) << 32) | word5 as u64;
116+
let bytes = bytes.to_be_bytes();
117+
let bytes = &bytes[2..];
118+
119+
Ok(bytes_to_mac_addr(bytes))
120+
}
121+
113122
fn spi_registers(&self) -> SpiRegisters {
114123
SpiRegisters {
115124
base: 0x6000_2000,

espflash/src/targets/esp32c3.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl Esp32c3 {
4040

4141
impl ReadEFuse for Esp32c3 {
4242
fn efuse_reg(&self) -> u32 {
43-
0x6000_8830
43+
0x6000_8800
4444
}
4545
}
4646

@@ -50,18 +50,18 @@ impl Target for Esp32c3 {
5050
}
5151

5252
fn chip_features(&self, _connection: &mut Connection) -> Result<Vec<&str>, Error> {
53-
Ok(vec!["WiFi"])
53+
Ok(vec!["WiFi", "BLE"])
5454
}
5555

56-
fn chip_revision(&self, connection: &mut Connection) -> Result<Option<u32>, Error> {
57-
let block1_addr = self.efuse_reg() + 0x14;
58-
let num_word = 3;
59-
let pos = 18;
56+
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
57+
Ok(self.read_efuse(connection, 22)? >> 24 & 0x3)
58+
}
6059

61-
let value = connection.read_reg(block1_addr + (num_word * 0x4))?;
62-
let value = (value & (0x7 << pos)) >> pos;
60+
fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
61+
let hi = self.read_efuse(connection, 22)? >> 23 & 0x1;
62+
let lo = self.read_efuse(connection, 20)? >> 18 & 0x7;
6363

64-
Ok(Some(value))
64+
Ok((hi << 3) + lo)
6565
}
6666

6767
fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
@@ -75,7 +75,7 @@ impl Target for Esp32c3 {
7575
bootloader: Option<Vec<u8>>,
7676
partition_table: Option<PartitionTable>,
7777
image_format: Option<ImageFormatKind>,
78-
chip_revision: Option<u32>,
78+
chip_revision: Option<(u32, u32)>,
7979
flash_mode: Option<FlashMode>,
8080
flash_size: Option<FlashSize>,
8181
flash_freq: Option<FlashFrequency>,
@@ -93,7 +93,7 @@ impl Target for Esp32c3 {
9393
flash_size,
9494
flash_freq,
9595
)?)),
96-
(ImageFormatKind::DirectBoot, None | Some(3..)) => {
96+
(ImageFormatKind::DirectBoot, None | Some((3.., _))) => {
9797
Ok(Box::new(DirectBootFormat::new(image, 0)?))
9898
}
9999
_ => Err(

espflash/src/targets/esp32s2.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,21 @@ impl Esp32s2 {
4040
}
4141

4242
fn get_block2_version(&self, connection: &mut Connection) -> Result<u32, Error> {
43-
let blk2_word4 = self.read_efuse(connection, 15)?;
43+
let blk2_word4 = self.read_efuse(connection, 27)?;
4444
let block2_version = (blk2_word4 >> 4) & 0x7;
4545

4646
Ok(block2_version)
4747
}
4848

4949
fn get_flash_version(&self, connection: &mut Connection) -> Result<u32, Error> {
50-
let blk1_word3 = self.read_efuse(connection, 8)?;
50+
let blk1_word3 = self.read_efuse(connection, 20)?;
5151
let flash_version = (blk1_word3 >> 21) & 0xf;
5252

5353
Ok(flash_version)
5454
}
5555

5656
fn get_psram_version(&self, connection: &mut Connection) -> Result<u32, Error> {
57-
let blk1_word3 = self.read_efuse(connection, 8)?;
57+
let blk1_word3 = self.read_efuse(connection, 20)?;
5858
let psram_version = (blk1_word3 >> 28) & 0xf;
5959

6060
Ok(psram_version)
@@ -67,7 +67,7 @@ impl Esp32s2 {
6767

6868
impl ReadEFuse for Esp32s2 {
6969
fn efuse_reg(&self) -> u32 {
70-
0x3f41_a030
70+
0x3f41_a000
7171
}
7272
}
7373

@@ -106,6 +106,17 @@ impl Target for Esp32s2 {
106106
Ok(features)
107107
}
108108

109+
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
110+
Ok(self.read_efuse(connection, 20)? >> 18 & 0x3)
111+
}
112+
113+
fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
114+
let hi = self.read_efuse(connection, 20)? >> 20 & 0x1;
115+
let lo = self.read_efuse(connection, 21)? >> 4 & 0x7;
116+
117+
Ok((hi << 3) + lo)
118+
}
119+
109120
fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
110121
// The ESP32-S2's XTAL has a fixed frequency of 40MHz.
111122
Ok(40)
@@ -125,7 +136,7 @@ impl Target for Esp32s2 {
125136
bootloader: Option<Vec<u8>>,
126137
partition_table: Option<PartitionTable>,
127138
image_format: Option<ImageFormatKind>,
128-
_chip_revision: Option<u32>,
139+
_chip_revision: Option<(u32, u32)>,
129140
flash_mode: Option<FlashMode>,
130141
flash_size: Option<FlashSize>,
131142
flash_freq: Option<FlashFrequency>,

0 commit comments

Comments
 (0)