use std::time::Duration;
use base64::{Engine as _, engine::general_purpose};
use serde::{Deserialize, Serialize};
use crate::target::Chip;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FlashStub {
entry: u32,
text: String,
text_start: u32,
data: String,
data_start: u32,
}
pub(crate) const CHIP_DETECT_MAGIC_REG_ADDR: u32 = 0x40001000;
pub(crate) const DEFAULT_TIMEOUT: Duration = Duration::from_secs(3);
pub(crate) const EXPECTED_STUB_HANDSHAKE: &str = "OHAI";
const STUB_32: &str = include_str!("../../resources/stubs/esp32.toml");
const STUB_32C2: &str = include_str!("../../resources/stubs/esp32c2.toml");
const STUB_32C3: &str = include_str!("../../resources/stubs/esp32c3.toml");
const STUB_32C5: &str = include_str!("../../resources/stubs/esp32c5.toml");
const STUB_32C6: &str = include_str!("../../resources/stubs/esp32c6.toml");
const STUB_32C61: &str = include_str!("../../resources/stubs/esp32c61.toml");
const STUB_32H2: &str = include_str!("../../resources/stubs/esp32h2.toml");
const STUB_32P4: &str = include_str!("../../resources/stubs/esp32p4.toml");
const STUB_32P4RC1: &str = include_str!("../../resources/stubs/esp32p4rc1.toml");
const STUB_32S2: &str = include_str!("../../resources/stubs/esp32s2.toml");
const STUB_32S3: &str = include_str!("../../resources/stubs/esp32s3.toml");
impl FlashStub {
#[allow(dead_code)]
#[deprecated(note = "Use get_with_rev instead.")]
pub fn get(chip: Chip) -> FlashStub {
Self::get_with_rev(chip, None)
}
pub fn get_with_rev(chip: Chip, revision: Option<u32>) -> FlashStub {
let s = match chip {
Chip::Esp32 => STUB_32,
Chip::Esp32c2 => STUB_32C2,
Chip::Esp32c3 => STUB_32C3,
Chip::Esp32c5 => STUB_32C5,
Chip::Esp32c6 => STUB_32C6,
Chip::Esp32c61 => STUB_32C61,
Chip::Esp32h2 => STUB_32H2,
Chip::Esp32p4 => {
if revision.unwrap_or(300) < 300 {
STUB_32P4RC1
} else {
STUB_32P4
}
}
Chip::Esp32s2 => STUB_32S2,
Chip::Esp32s3 => STUB_32S3,
};
let stub: FlashStub = toml::from_str(s).unwrap();
stub
}
pub fn entry(&self) -> u32 {
self.entry
}
pub fn text(&self) -> (u32, Vec<u8>) {
let v = general_purpose::STANDARD.decode(&self.text).unwrap();
(self.text_start, v)
}
pub fn data(&self) -> (u32, Vec<u8>) {
let v = general_purpose::STANDARD.decode(&self.data).unwrap();
(self.data_start, v)
}
}
#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;
use super::FlashStub;
use crate::target::Chip;
#[test]
fn check_stub_encodings() {
for c in Chip::iter() {
let s = FlashStub::get_with_rev(c, None);
let _ = s.text();
let _ = s.data();
}
}
#[test]
fn check_esp32p4_rc1_stub() {
let s = FlashStub::get_with_rev(Chip::Esp32p4, Some(200));
let _ = s.text();
let _ = s.data();
}
}