Skip to main content

sftool_lib/common/
erase_flash.rs

1use crate::common::ram_command::{Command, RamCommand};
2use crate::common::serial_io::for_tool;
3use crate::progress::{EraseFlashStyle, EraseRegionStyle, ProgressOperation, ProgressStatus};
4use crate::utils::Utils;
5use crate::{Error, Result, SifliToolTrait};
6
7/// 通用的Flash擦除操作实现
8pub struct EraseOps;
9
10impl EraseOps {
11    /// 擦除整个Flash的通用实现
12    pub fn erase_all<T>(tool: &mut T, address: u32) -> Result<()>
13    where
14        T: SifliToolTrait + RamCommand,
15    {
16        tool.check_cancelled()?;
17        let progress = tool.progress();
18        let progress_bar = progress.create_spinner(ProgressOperation::EraseFlash {
19            address,
20            style: EraseFlashStyle::Complete,
21        });
22
23        // 发送擦除所有命令
24        let _ = tool.command(Command::EraseAll { address });
25
26        let mut io = for_tool(tool);
27        io.wait_for_pattern(
28            b"OK",
29            std::time::Duration::from_millis(30_000),
30            &format!("erasing flash at 0x{:08X}", address),
31        )?;
32
33        progress_bar.finish(ProgressStatus::Success);
34
35        Ok(())
36    }
37
38    /// 擦除指定区域的通用实现
39    pub fn erase_region<T>(tool: &mut T, address: u32, len: u32) -> Result<()>
40    where
41        T: SifliToolTrait + RamCommand,
42    {
43        tool.check_cancelled()?;
44        let progress = tool.progress();
45        let progress_bar = progress.create_spinner(ProgressOperation::EraseRegion {
46            address,
47            len,
48            style: EraseRegionStyle::Range,
49        });
50
51        // 发送擦除区域命令
52        let _ = tool.command(Command::Erase { address, len });
53
54        let mut io = for_tool(tool);
55        io.wait_for_pattern(
56            b"OK",
57            std::time::Duration::from_millis(30_000),
58            &format!(
59                "erasing region 0x{:08X}..0x{:08X}",
60                address,
61                address + len.saturating_sub(1)
62            ),
63        )?;
64
65        progress_bar.finish(ProgressStatus::Success);
66
67        Ok(())
68    }
69
70    /// 解析擦除地址参数
71    pub fn parse_address(address_str: &str) -> Result<u32> {
72        Utils::str_to_u32(address_str)
73            .map_err(|e| Error::invalid_input(format!("Invalid address '{}': {}", address_str, e)))
74    }
75
76    /// 解析区域参数 (address:size格式)
77    pub fn parse_region(region_spec: &str) -> Result<(u32, u32)> {
78        let Some((addr_str, size_str)) = region_spec.split_once(':') else {
79            return Err(Error::invalid_input(format!(
80                "Invalid region format: {}. Expected: address:size",
81                region_spec
82            )));
83        };
84
85        let address = Utils::str_to_u32(addr_str)
86            .map_err(|e| Error::invalid_input(format!("Invalid address '{}': {}", addr_str, e)))?;
87        let len = Utils::str_to_u32(size_str)
88            .map_err(|e| Error::invalid_input(format!("Invalid size '{}': {}", size_str, e)))?;
89
90        Ok((address, len))
91    }
92}