Skip to content

Commit af641cc

Browse files
authored
Fix crystal frequency detection for ESP32-C2 and ESP8266 (#314)
* Add a workaround for setting baud rate on 26MHz ESP32-C2 * Detect crystal frequency for ESP32-C2 * Fix clock divider value for ESP8266
1 parent f8ef0b4 commit af641cc

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

espflash/src/flasher/mod.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,13 @@ impl Flasher {
348348

349349
// Now that we have established a connection and detected the chip and flash
350350
// size, we can set the baud rate of the connection to the configured value.
351-
if let Some(b) = speed {
351+
if let Some(baud) = speed {
352352
match flasher.chip {
353353
Chip::Esp8266 => (), // Not available
354354
_ => {
355-
if b > 115_200 {
355+
if baud > 115_200 {
356356
warn!("Setting baud rate higher than 115,200 can cause issues");
357-
flasher.change_baud(b)?;
357+
flasher.change_baud(baud)?;
358358
}
359359
}
360360
}
@@ -776,16 +776,29 @@ impl Flasher {
776776
false => 0,
777777
};
778778

779+
let target = self.chip.into_target();
780+
let xtal_freq = target.crystal_freq(&mut self.connection)?;
781+
782+
// Probably this is just a temporary solution until the next chip revision.
783+
//
784+
// The ROM code thinks it uses a 40 MHz XTAL. Recompute the baud rate in order
785+
// to trick the ROM code to set the correct baud rate for a 26 MHz XTAL.
786+
let mut new_baud = speed;
787+
if self.chip == Chip::Esp32c2 && !self.use_stub && xtal_freq == 26 {
788+
new_baud = new_baud * 40 / 26;
789+
}
790+
779791
self.connection
780792
.with_timeout(CommandType::ChangeBaud.timeout(), |connection| {
781793
connection.command(Command::ChangeBaud {
782-
new_baud: speed,
794+
new_baud,
783795
prior_baud,
784796
})
785797
})?;
786798
self.connection.set_baud(speed)?;
787-
std::thread::sleep(Duration::from_secs_f32(0.05));
799+
sleep(Duration::from_secs_f32(0.05));
788800
self.connection.flush()?;
801+
789802
Ok(())
790803
}
791804

espflash/src/targets/esp32c2.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ const PARAMS: Esp32Params = Esp32Params::new(
2929
include_bytes!("../../resources/bootloaders/esp32c2-bootloader.bin"),
3030
);
3131

32+
const UART_CLKDIV_REG: u32 = 0x6000_0014;
33+
const UART_CLKDIV_MASK: u32 = 0xfffff;
34+
35+
const XTAL_CLK_DIVIDER: u32 = 1;
36+
3237
/// ESP32-C2 Target
3338
pub struct Esp32c2;
3439

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

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

6977
fn flash_frequency_encodings(&self) -> HashMap<FlashFrequency, u8> {

espflash/src/targets/esp8266.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const FLASH_RANGES: &[Range<u32>] = &[
2020
const UART_CLKDIV_REG: u32 = 0x6000_0014;
2121
const UART_CLKDIV_MASK: u32 = 0xfffff;
2222

23-
const XTAL_CLK_DIVIDER: u32 = 1;
23+
const XTAL_CLK_DIVIDER: u32 = 2;
2424

2525
/// ESP8266 Target
2626
pub struct Esp8266;

0 commit comments

Comments
 (0)