diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index 0a53e096..0a1427f0 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -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)?; } } } @@ -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(()) } diff --git a/espflash/src/targets/esp32c2.rs b/espflash/src/targets/esp32c2.rs index 76529439..811074a3 100644 --- a/espflash/src/targets/esp32c2.rs +++ b/espflash/src/targets/esp32c2.rs @@ -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; @@ -61,9 +66,12 @@ impl Target for Esp32c2 { Ok(self.read_efuse(connection, 17)? >> 16 & 0xf) } - fn crystal_freq(&self, _connection: &mut Connection) -> Result { - // The ESP32-C2's XTAL has a fixed frequency of 40MHz. - Ok(40) + fn crystal_freq(&self, connection: &mut Connection) -> Result { + 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 { diff --git a/espflash/src/targets/esp8266.rs b/espflash/src/targets/esp8266.rs index 2b132371..5e60ea65 100644 --- a/espflash/src/targets/esp8266.rs +++ b/espflash/src/targets/esp8266.rs @@ -20,7 +20,7 @@ const FLASH_RANGES: &[Range] = &[ 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;