Skip to content

Commit

Permalink
Display the newer 'v{major}.{minor}' chip revision format (esp-rs#307)
Browse files Browse the repository at this point in the history
  • Loading branch information
jessebraham authored Nov 30, 2022
1 parent d555956 commit b25af06
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 78 deletions.
13 changes: 9 additions & 4 deletions espflash/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ https://github.com/espressif/esp32c3-direct-boot-example"
chip: Chip,
frequency: FlashFrequency,
},
#[error("The {chip} does not support {feature}")]
#[diagnostic(code(espflash::unsupported_feature))]
UnsupportedFeature { chip: Chip, feature: String },
}

#[derive(Error, Debug, Diagnostic)]
Expand Down Expand Up @@ -449,7 +452,7 @@ impl From<u8> for FlashDetectError {
pub struct UnsupportedImageFormatError {
format: ImageFormatKind,
chip: Chip,
revision: Option<u32>,
revision: Option<(u32, u32)>,
}

impl Display for UnsupportedImageFormatError {
Expand All @@ -459,9 +462,11 @@ impl Display for UnsupportedImageFormatError {
"Image format {} is not supported by the {}",
self.format, self.chip
)?;
if let Some(revision) = self.revision {
write!(f, " revision {}", revision)?;

if let Some((major, minor)) = self.revision {
write!(f, " revision v{major}.{minor}")?;
}

Ok(())
}
}
Expand Down Expand Up @@ -491,7 +496,7 @@ impl Diagnostic for UnsupportedImageFormatError {
}

impl UnsupportedImageFormatError {
pub fn new(format: ImageFormatKind, chip: Chip, revision: Option<u32>) -> Self {
pub fn new(format: ImageFormatKind, chip: Chip, revision: Option<(u32, u32)>) -> Self {
UnsupportedImageFormatError {
format,
chip,
Expand Down
27 changes: 16 additions & 11 deletions espflash/src/flasher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,22 +608,25 @@ impl Flasher {
/// Read and print any information we can about the connected board
pub fn board_info(&mut self) -> Result<(), Error> {
let chip = self.chip();

let target = chip.into_target();
let maybe_revision = target.chip_revision(self.connection())?;

let features = target.chip_features(self.connection())?;
let freq = target.crystal_freq(self.connection())?;
let mac = target.mac_address(self.connection())?;

print!("Chip type: {}", chip);
match maybe_revision {
Some(revision) => println!(" (revision {})", revision),
None => println!(),
// The ESP8266 does not have readable major/minor revision numbers, so we have
// nothing to print if targeting it.
print!("Chip type: {chip}");
if chip != Chip::Esp8266 {
let (major, minor) = target.chip_revision(self.connection())?;
println!(" (revision v{major}.{minor})");
} else {
println!("");
}
println!("Crystal frequency: {}MHz", freq);
println!("Crystal frequency: {freq}MHz");
println!("Flash size: {}", self.flash_size);
println!("Features: {}", features.join(", "));
println!("MAC address: {}", mac);
println!("MAC address: {mac}");

Ok(())
}
Expand Down Expand Up @@ -687,9 +690,11 @@ impl Flasher {
bootloader,
partition_table,
image_format,
self.chip
.into_target()
.chip_revision(&mut self.connection)?,
Some(
self.chip
.into_target()
.chip_revision(&mut self.connection)?,
),
flash_mode,
flash_size.or(Some(self.flash_size)),
flash_freq,
Expand Down
31 changes: 16 additions & 15 deletions espflash/src/targets/esp32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,25 @@ impl Target for Esp32 {
Ok(features)
}

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

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

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

let revision = match (rev_bit0, rev_bit1, rev_bit2) {
(true, true, true) => 3,
(true, true, false) => 2,
(true, false, _) => 1,
(false, _, _) => 0,
};
match combine_value {
1 => Ok(1),
3 => Ok(2),
7 => Ok(3),
_ => Ok(0),
}
}

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

fn crystal_freq(&self, connection: &mut Connection) -> Result<u32, Error> {
Expand All @@ -152,7 +153,7 @@ impl Target for Esp32 {
bootloader: Option<Vec<u8>>,
partition_table: Option<PartitionTable>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<u32>,
_chip_revision: Option<(u32, u32)>,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand Down
31 changes: 20 additions & 11 deletions espflash/src/targets/esp32c2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::HashMap, ops::Range};

use esp_idf_part::PartitionTable;

use super::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target};
use super::{bytes_to_mac_addr, Chip, Esp32Params, ReadEFuse, SpiRegisters, Target};
use crate::{
connection::Connection,
elf::FirmwareImage,
Expand Down Expand Up @@ -50,18 +50,15 @@ impl Target for Esp32c2 {
}

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

fn chip_revision(&self, connection: &mut Connection) -> Result<Option<u32>, Error> {
let block1_addr = self.efuse_reg() + 0x44;
let num_word = 3;
let pos = 18;

let value = connection.read_reg(block1_addr + (num_word * 0x4))?;
let value = (value & (0x7 << pos)) >> pos;
fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
Ok(self.read_efuse(connection, 17)? >> 20 & 0x3)
}

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

fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
Expand All @@ -88,7 +85,7 @@ impl Target for Esp32c2 {
bootloader: Option<Vec<u8>>,
partition_table: Option<PartitionTable>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<u32>,
_chip_revision: Option<(u32, u32)>,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -110,6 +107,18 @@ impl Target for Esp32c2 {
}
}

/// What is the MAC address?
fn mac_address(&self, connection: &mut Connection) -> Result<String, Error> {
let word5 = self.read_efuse(connection, 16)?;
let word6 = self.read_efuse(connection, 17)?;

let bytes = ((word6 as u64) << 32) | word5 as u64;
let bytes = bytes.to_be_bytes();
let bytes = &bytes[2..];

Ok(bytes_to_mac_addr(bytes))
}

fn spi_registers(&self) -> SpiRegisters {
SpiRegisters {
base: 0x6000_2000,
Expand Down
22 changes: 11 additions & 11 deletions espflash/src/targets/esp32c3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Esp32c3 {

impl ReadEFuse for Esp32c3 {
fn efuse_reg(&self) -> u32 {
0x6000_8830
0x6000_8800
}
}

Expand All @@ -50,18 +50,18 @@ impl Target for Esp32c3 {
}

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

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

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

Ok(Some(value))
Ok((hi << 3) + lo)
}

fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
Expand All @@ -75,7 +75,7 @@ impl Target for Esp32c3 {
bootloader: Option<Vec<u8>>,
partition_table: Option<PartitionTable>,
image_format: Option<ImageFormatKind>,
chip_revision: Option<u32>,
chip_revision: Option<(u32, u32)>,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -93,7 +93,7 @@ impl Target for Esp32c3 {
flash_size,
flash_freq,
)?)),
(ImageFormatKind::DirectBoot, None | Some(3..)) => {
(ImageFormatKind::DirectBoot, None | Some((3.., _))) => {
Ok(Box::new(DirectBootFormat::new(image, 0)?))
}
_ => Err(
Expand Down
21 changes: 16 additions & 5 deletions espflash/src/targets/esp32s2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,21 @@ impl Esp32s2 {
}

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

Ok(block2_version)
}

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

Ok(flash_version)
}

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

Ok(psram_version)
Expand All @@ -67,7 +67,7 @@ impl Esp32s2 {

impl ReadEFuse for Esp32s2 {
fn efuse_reg(&self) -> u32 {
0x3f41_a030
0x3f41_a000
}
}

Expand Down Expand Up @@ -106,6 +106,17 @@ impl Target for Esp32s2 {
Ok(features)
}

fn major_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
Ok(self.read_efuse(connection, 20)? >> 18 & 0x3)
}

fn minor_chip_version(&self, connection: &mut Connection) -> Result<u32, Error> {
let hi = self.read_efuse(connection, 20)? >> 20 & 0x1;
let lo = self.read_efuse(connection, 21)? >> 4 & 0x7;

Ok((hi << 3) + lo)
}

fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
// The ESP32-S2's XTAL has a fixed frequency of 40MHz.
Ok(40)
Expand All @@ -125,7 +136,7 @@ impl Target for Esp32s2 {
bootloader: Option<Vec<u8>>,
partition_table: Option<PartitionTable>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<u32>,
_chip_revision: Option<(u32, u32)>,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand Down
Loading

0 comments on commit b25af06

Please sign in to comment.