Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions cargo-espflash/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::cargo_config::parse_cargo_config;
use crate::error::UnsupportedTargetError;
use std::{
fs,
path::PathBuf,
process::{exit, Command, ExitStatus, Stdio},
string::ToString,
};

use cargo_metadata::Message;
use clap::{App, Arg, SubCommand};
use error::Error;
Expand All @@ -8,12 +13,8 @@ use miette::{IntoDiagnostic, Result, WrapErr};
use monitor::monitor;
use package_metadata::CargoEspFlashMeta;
use serial::{BaudRate, FlowControl, SerialPort};
use std::{
fs,
path::PathBuf,
process::{exit, Command, ExitStatus, Stdio},
string::ToString,
};

use crate::{cargo_config::parse_cargo_config, error::UnsupportedTargetError};

mod cargo_config;
mod error;
Expand All @@ -23,6 +24,7 @@ mod package_metadata;

fn main() -> Result<()> {
miette::set_panic_hook();

let mut app = App::new(env!("CARGO_PKG_NAME"))
.bin_name("cargo")
.subcommand(
Expand Down Expand Up @@ -139,11 +141,13 @@ fn main() -> Result<()> {
None
};

// Connect the Flasher to the target device. If the '--board-info' flag has been
// provided, display the board info and terminate the application.
// Connect the Flasher to the target device and print the board information
// upon connection. If the '--board-info' flag has been provided, we have
// nothing left to do so exit early.
let mut flasher = Flasher::connect(serial, speed)?;
flasher.board_info()?;

if matches.is_present("board_info") {
board_info(&flasher);
return Ok(());
}

Expand Down Expand Up @@ -191,6 +195,7 @@ fn main() -> Result<()> {
} else {
flasher.load_elf_to_flash(&elf_data, bootloader, partition_table)?;
}
println!("\nFlashing has completed!");

if matches.is_present("monitor") {
monitor(flasher.into_serial()).into_diagnostic()?;
Expand All @@ -200,11 +205,6 @@ fn main() -> Result<()> {
Ok(())
}

fn board_info(flasher: &Flasher) {
println!("Chip type: {}", flasher.chip());
println!("Flash size: {}", flasher.flash_size());
}

fn build(
release: bool,
example: Option<&str>,
Expand Down
40 changes: 34 additions & 6 deletions espflash/src/chip/esp32.rs → espflash/src/chip/esp32/esp32.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::chip::Esp32Params;
use std::ops::Range;

use crate::image_format::{Esp32BootloaderFormat, ImageFormat, ImageFormatId};
use super::Esp32Params;
use crate::{
chip::{Chip, ChipType, SpiRegisters},
chip::{Chip, ChipType, ReadEFuse, SpiRegisters},
connection::Connection,
elf::FirmwareImage,
image_format::{Esp32BootloaderFormat, ImageFormat, ImageFormatId},
Error, PartitionTable,
};

use std::ops::Range;

pub struct Esp32;

const IROM_MAP_START: u32 = 0x400d0000;
Expand All @@ -27,12 +27,14 @@ pub const PARAMS: Esp32Params = Esp32Params {
app_addr: 0x10000,
app_size: 0x3f0000,
chip_id: 0,
default_bootloader: include_bytes!("../../bootloader/esp32-bootloader.bin"),
default_bootloader: include_bytes!("../../../bootloader/esp32-bootloader.bin"),
};

impl ChipType for Esp32 {
const CHIP_DETECT_MAGIC_VALUE: u32 = 0x00f01d83;

const UART_CLKDIV_REG: u32 = 0x3ff40014;

const SPI_REGISTERS: SpiRegisters = SpiRegisters {
base: 0x3ff42000,
usr_offset: 0x1c,
Expand Down Expand Up @@ -77,6 +79,32 @@ impl ChipType for Esp32 {
}
}

impl ReadEFuse for Esp32 {
const EFUSE_REG_BASE: u32 = 0x3ff5a000;
}

impl Esp32 {
pub fn chip_revision(&self, connection: &mut Connection) -> Result<u32, Error> {
let word3 = self.read_efuse(connection, 3)?;
let word5 = self.read_efuse(connection, 5)?;

let apb_ctrl_date = connection.read_reg(0x3FF6607C)?;

let rev_bit0 = (word3 >> 15) & 0x1 != 0;
let rev_bit1 = (word5 >> 20) & 0x1 != 0;
let rev_bit2 = (apb_ctrl_date >> 31) & 0x1 != 0;

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

Ok(revision)
}
}

#[test]
fn test_esp32_rom() {
use std::fs::read;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use crate::chip::Esp32Params;
use crate::image_format::{Esp32BootloaderFormat, ImageFormat, ImageFormatId};
use std::ops::Range;

use super::Esp32Params;
use crate::{
chip::{ChipType, SpiRegisters},
chip::{ChipType, ReadEFuse, SpiRegisters},
connection::Connection,
elf::FirmwareImage,
image_format::{Esp32BootloaderFormat, ImageFormat, ImageFormatId},
Chip, Error, PartitionTable,
};

use std::ops::Range;

pub struct Esp32c3;

const IROM_MAP_START: u32 = 0x42000000;
Expand All @@ -26,13 +27,15 @@ pub const PARAMS: Esp32Params = Esp32Params {
app_addr: 0x10000,
app_size: 0x3f0000,
chip_id: 5,
default_bootloader: include_bytes!("../../bootloader/esp32c3-bootloader.bin"),
default_bootloader: include_bytes!("../../../bootloader/esp32c3-bootloader.bin"),
};

impl ChipType for Esp32c3 {
const CHIP_DETECT_MAGIC_VALUE: u32 = 0x6921506f;
const CHIP_DETECT_MAGIC_VALUE2: u32 = 0x1b31506f;

const UART_CLKDIV_REG: u32 = 0x3ff40014;

const SPI_REGISTERS: SpiRegisters = SpiRegisters {
base: 0x60002000,
usr_offset: 0x18,
Expand All @@ -53,6 +56,11 @@ impl ChipType for Esp32c3 {
const SUPPORTED_TARGETS: &'static [&'static str] =
&["riscv32imc-uknown-none-elf", "riscv32imc-esp-espidf"];

fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
// The ESP32-C3's XTAL has a fixed frequency of 40MHz.
Ok(40)
}

fn get_flash_segments<'a>(
image: &'a FirmwareImage,
bootloader: Option<Vec<u8>>,
Expand All @@ -77,3 +85,20 @@ impl ChipType for Esp32c3 {
target.starts_with("riscv32imc-")
}
}

impl ReadEFuse for Esp32c3 {
const EFUSE_REG_BASE: u32 = 0x60008830;
}

impl Esp32c3 {
pub fn chip_revision(&self, connection: &mut Connection) -> Result<u32, Error> {
let block1_addr = Self::EFUSE_REG_BASE + 0x14;
let num_word = 3;
let pos = 18;

let value = connection.read_reg(block1_addr + (num_word * 0x4))?;
let value = (value & (0x7 << pos)) >> pos;

Ok(value)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use crate::chip::Esp32Params;
use crate::image_format::{Esp32BootloaderFormat, ImageFormat, ImageFormatId};
use std::ops::Range;

use super::Esp32Params;
use crate::{
chip::{ChipType, SpiRegisters},
chip::{ChipType, ReadEFuse, SpiRegisters},
connection::Connection,
elf::FirmwareImage,
image_format::{Esp32BootloaderFormat, ImageFormat, ImageFormatId},
Chip, Error, PartitionTable,
};

use std::ops::Range;

pub struct Esp32s2;

const IROM_MAP_START: u32 = 0x40080000;
Expand All @@ -26,12 +27,14 @@ pub const PARAMS: Esp32Params = Esp32Params {
app_addr: 0x10000,
app_size: 0x100000,
chip_id: 2,
default_bootloader: include_bytes!("../../bootloader/esp32s2-bootloader.bin"),
default_bootloader: include_bytes!("../../../bootloader/esp32s2-bootloader.bin"),
};

impl ChipType for Esp32s2 {
const CHIP_DETECT_MAGIC_VALUE: u32 = 0x000007c6;

const UART_CLKDIV_REG: u32 = 0x3f400014;

const SPI_REGISTERS: SpiRegisters = SpiRegisters {
base: 0x3f402000,
usr_offset: 0x18,
Expand All @@ -51,6 +54,11 @@ impl ChipType for Esp32s2 {
const SUPPORTED_TARGETS: &'static [&'static str] =
&["xtensa-esp32s2-none-elf", "xtensa-esp32s2-espidf"];

fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
// The ESP32-S2's XTAL has a fixed frequency of 40MHz.
Ok(40)
}

fn get_flash_segments<'a>(
image: &'a FirmwareImage,
bootloader: Option<Vec<u8>>,
Expand All @@ -75,3 +83,7 @@ impl ChipType for Esp32s2 {
target.starts_with("xtensa-esp32s2-")
}
}

impl ReadEFuse for Esp32s2 {
const EFUSE_REG_BASE: u32 = 0x3F41A030;
}
37 changes: 37 additions & 0 deletions espflash/src/chip/esp32/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::PartitionTable;

#[allow(clippy::module_inception)]
mod esp32;
mod esp32c3;
mod esp32s2;

pub use esp32::Esp32;
pub use esp32c3::Esp32c3;
pub use esp32s2::Esp32s2;

#[derive(Clone, Copy, Debug)]
pub struct Esp32Params {
pub boot_addr: u32,
pub partition_addr: u32,
pub nvs_addr: u32,
pub nvs_size: u32,
pub phy_init_data_addr: u32,
pub phy_init_data_size: u32,
pub app_addr: u32,
pub app_size: u32,
pub chip_id: u16,
pub default_bootloader: &'static [u8],
}

impl Esp32Params {
pub fn default_partition_table(&self) -> PartitionTable {
PartitionTable::basic(
self.nvs_addr,
self.nvs_size,
self.phy_init_data_addr,
self.phy_init_data_size,
self.app_addr,
self.app_size,
)
}
}
27 changes: 19 additions & 8 deletions espflash/src/chip/esp8266.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
use super::ChipType;
use crate::{chip::SpiRegisters, elf::FirmwareImage, Chip, Error, PartitionTable};

use crate::error::UnsupportedImageFormatError;
use crate::image_format::{Esp8266Format, ImageFormat, ImageFormatId};

use std::ops::Range;

pub const IROM_MAP_START: u32 = 0x40200000;
use super::ChipType;
use crate::{
chip::{ReadEFuse, SpiRegisters},
elf::FirmwareImage,
error::UnsupportedImageFormatError,
image_format::{Esp8266Format, ImageFormat, ImageFormatId},
Chip, Error, PartitionTable,
};

const IROM_MAP_START: u32 = 0x40200000;
const IROM_MAP_END: u32 = 0x40300000;

pub struct Esp8266;

impl ChipType for Esp8266 {
const CHIP_DETECT_MAGIC_VALUE: u32 = 0xfff0c101;

const UART_CLKDIV_REG: u32 = 0x60000014;
const XTAL_CLK_DIVIDER: u32 = 2;

const SPI_REGISTERS: SpiRegisters = SpiRegisters {
base: 0x60000200,
usr_offset: 0x1c,
Expand Down Expand Up @@ -48,11 +54,16 @@ impl ChipType for Esp8266 {
}
}

impl ReadEFuse for Esp8266 {
const EFUSE_REG_BASE: u32 = 0x3ff00050;
}

#[test]
fn test_esp8266_rom() {
use pretty_assertions::assert_eq;
use std::fs::read;

use pretty_assertions::assert_eq;

let input_bytes = read("./tests/data/esp8266").unwrap();
let expected_bin = read("./tests/data/esp8266.bin").unwrap();

Expand Down
Loading