Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crystal frequency detection for ESP32-C2 and ESP8266 #314

Merged
merged 3 commits into from
Dec 9, 2022
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
23 changes: 18 additions & 5 deletions espflash/src/flasher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,13 @@ impl Flasher {

// Now that we have established a connection and detected the chip and flash
// size, we can set the baud rate of the connection to the configured value.
if let Some(b) = speed {
if let Some(baud) = speed {
match flasher.chip {
Chip::Esp8266 => (), // Not available
_ => {
if b > 115_200 {
if baud > 115_200 {
warn!("Setting baud rate higher than 115,200 can cause issues");
flasher.change_baud(b)?;
flasher.change_baud(baud)?;
}
}
}
Expand Down Expand Up @@ -776,16 +776,29 @@ impl Flasher {
false => 0,
};

let target = self.chip.into_target();
let xtal_freq = target.crystal_freq(&mut self.connection)?;

// Probably this is just a temporary solution until the next chip revision.
//
// The ROM code thinks it uses a 40 MHz XTAL. Recompute the baud rate in order
// to trick the ROM code to set the correct baud rate for a 26 MHz XTAL.
let mut new_baud = speed;
if self.chip == Chip::Esp32c2 && !self.use_stub && xtal_freq == 26 {
new_baud = new_baud * 40 / 26;
}

self.connection
.with_timeout(CommandType::ChangeBaud.timeout(), |connection| {
connection.command(Command::ChangeBaud {
new_baud: speed,
new_baud,
prior_baud,
})
})?;
self.connection.set_baud(speed)?;
std::thread::sleep(Duration::from_secs_f32(0.05));
sleep(Duration::from_secs_f32(0.05));
self.connection.flush()?;

Ok(())
}

Expand Down
14 changes: 11 additions & 3 deletions espflash/src/targets/esp32c2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ const PARAMS: Esp32Params = Esp32Params::new(
include_bytes!("../../resources/bootloaders/esp32c2-bootloader.bin"),
);

const UART_CLKDIV_REG: u32 = 0x6000_0014;
const UART_CLKDIV_MASK: u32 = 0xfffff;

const XTAL_CLK_DIVIDER: u32 = 1;

/// ESP32-C2 Target
pub struct Esp32c2;

Expand Down Expand Up @@ -61,9 +66,12 @@ impl Target for Esp32c2 {
Ok(self.read_efuse(connection, 17)? >> 16 & 0xf)
}

fn crystal_freq(&self, _connection: &mut Connection) -> Result<u32, Error> {
// The ESP32-C2's XTAL has a fixed frequency of 40MHz.
Ok(40)
fn crystal_freq(&self, connection: &mut Connection) -> Result<u32, Error> {
let uart_div = connection.read_reg(UART_CLKDIV_REG)? & UART_CLKDIV_MASK;
let est_xtal = (connection.get_baud()? * uart_div) / 1_000_000 / XTAL_CLK_DIVIDER;
let norm_xtal = if est_xtal > 33 { 40 } else { 26 };

Ok(norm_xtal)
}

fn flash_frequency_encodings(&self) -> HashMap<FlashFrequency, u8> {
Expand Down
2 changes: 1 addition & 1 deletion espflash/src/targets/esp8266.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const FLASH_RANGES: &[Range<u32>] = &[
const UART_CLKDIV_REG: u32 = 0x6000_0014;
const UART_CLKDIV_MASK: u32 = 0xfffff;

const XTAL_CLK_DIVIDER: u32 = 1;
const XTAL_CLK_DIVIDER: u32 = 2;

/// ESP8266 Target
pub struct Esp8266;
Expand Down