use crate::SifliToolTrait;
use crate::common::ram_command::{Command, RamCommand};
use crate::utils::Utils;
pub struct EraseOps;
impl EraseOps {
pub fn erase_all<T>(tool: &mut T, address: u32) -> Result<(), std::io::Error>
where
T: SifliToolTrait + RamCommand,
{
let progress = tool.progress();
let progress_bar =
progress.create_spinner(format!("Erasing entire flash at 0x{:08X}...", address));
let _ = tool.command(Command::EraseAll { address });
let mut buffer = Vec::new();
let now = std::time::SystemTime::now();
loop {
let elapsed = now.elapsed().unwrap().as_millis();
if elapsed > 30000 {
return Err(std::io::Error::new(
std::io::ErrorKind::TimedOut,
"Erase timeout",
));
}
let mut byte = [0];
let ret = tool.port().read_exact(&mut byte);
if ret.is_err() {
continue;
}
buffer.push(byte[0]);
if buffer.windows(2).any(|window| window == b"OK") {
break;
}
}
progress_bar.finish_with_message("Erase complete");
Ok(())
}
pub fn erase_region<T>(tool: &mut T, address: u32, len: u32) -> Result<(), std::io::Error>
where
T: SifliToolTrait + RamCommand,
{
let progress = tool.progress();
let progress_bar = progress.create_spinner(format!(
"Erasing region at 0x{:08X} (size: 0x{:08X})...",
address, len
));
let _ = tool.command(Command::Erase { address, len });
let mut buffer = Vec::new();
let now = std::time::SystemTime::now();
loop {
let elapsed = now.elapsed().unwrap().as_millis();
if elapsed > 30000 {
return Err(std::io::Error::new(
std::io::ErrorKind::TimedOut,
"Erase timeout",
));
}
let mut byte = [0];
let ret = tool.port().read_exact(&mut byte);
if ret.is_err() {
continue;
}
buffer.push(byte[0]);
if buffer.windows(2).any(|window| window == b"OK") {
break;
}
}
progress_bar.finish_with_message("Region erase complete");
Ok(())
}
pub fn parse_address(address_str: &str) -> Result<u32, std::io::Error> {
Utils::str_to_u32(address_str)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))
}
pub fn parse_region(region_spec: &str) -> Result<(u32, u32), std::io::Error> {
let Some((addr_str, size_str)) = region_spec.split_once(':') else {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!(
"Invalid region format: {}. Expected: address:size",
region_spec
),
));
};
let address = Utils::str_to_u32(addr_str)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
let len = Utils::str_to_u32(size_str)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
Ok((address, len))
}
}