sftool_lib/common/
erase_flash.rs

1use crate::SifliToolTrait;
2use crate::common::ram_command::{Command, RamCommand};
3use crate::utils::Utils;
4
5/// 通用的Flash擦除操作实现
6pub struct EraseOps;
7
8impl EraseOps {
9    /// 擦除整个Flash的通用实现
10    pub fn erase_all<T>(tool: &mut T, address: u32) -> Result<(), std::io::Error>
11    where
12        T: SifliToolTrait + RamCommand,
13    {
14        let progress = tool.progress();
15        let progress_bar =
16            progress.create_spinner(format!("Erasing entire flash at 0x{:08X}...", address));
17
18        // 发送擦除所有命令
19        let _ = tool.command(Command::EraseAll { address });
20
21        let mut buffer = Vec::new();
22        let now = std::time::SystemTime::now();
23
24        // 等待擦除完成
25        loop {
26            let elapsed = now.elapsed().unwrap().as_millis();
27            if elapsed > 30000 {
28                return Err(std::io::Error::new(
29                    std::io::ErrorKind::TimedOut,
30                    "Erase timeout",
31                ));
32            }
33
34            let mut byte = [0];
35            let ret = tool.port().read_exact(&mut byte);
36            if ret.is_err() {
37                continue;
38            }
39            buffer.push(byte[0]);
40
41            if buffer.windows(2).any(|window| window == b"OK") {
42                break;
43            }
44        }
45
46        progress_bar.finish_with_message("Erase complete");
47
48        Ok(())
49    }
50
51    /// 擦除指定区域的通用实现
52    pub fn erase_region<T>(tool: &mut T, address: u32, len: u32) -> Result<(), std::io::Error>
53    where
54        T: SifliToolTrait + RamCommand,
55    {
56        let progress = tool.progress();
57        let progress_bar = progress.create_spinner(format!(
58            "Erasing region at 0x{:08X} (size: 0x{:08X})...",
59            address, len
60        ));
61
62        // 发送擦除区域命令
63        let _ = tool.command(Command::Erase { address, len });
64
65        let mut buffer = Vec::new();
66        let now = std::time::SystemTime::now();
67
68        // 等待擦除完成
69        loop {
70            let elapsed = now.elapsed().unwrap().as_millis();
71            if elapsed > 30000 {
72                return Err(std::io::Error::new(
73                    std::io::ErrorKind::TimedOut,
74                    "Erase timeout",
75                ));
76            }
77
78            let mut byte = [0];
79            let ret = tool.port().read_exact(&mut byte);
80            if ret.is_err() {
81                continue;
82            }
83            buffer.push(byte[0]);
84
85            if buffer.windows(2).any(|window| window == b"OK") {
86                break;
87            }
88        }
89
90        let end_address = address + len - 1;
91        progress_bar.finish_with_message(&format!(
92            "Region erased successfully for 0x{:08X}..0x{:08X}",
93            address, end_address
94        ));
95
96        Ok(())
97    }
98
99    /// 解析擦除地址参数
100    pub fn parse_address(address_str: &str) -> Result<u32, std::io::Error> {
101        Utils::str_to_u32(address_str)
102            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))
103    }
104
105    /// 解析区域参数 (address:size格式)
106    pub fn parse_region(region_spec: &str) -> Result<(u32, u32), std::io::Error> {
107        let Some((addr_str, size_str)) = region_spec.split_once(':') else {
108            return Err(std::io::Error::new(
109                std::io::ErrorKind::InvalidInput,
110                format!(
111                    "Invalid region format: {}. Expected: address:size",
112                    region_spec
113                ),
114            ));
115        };
116
117        let address = Utils::str_to_u32(addr_str)
118            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
119        let len = Utils::str_to_u32(size_str)
120            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
121
122        Ok((address, len))
123    }
124}