Skip to main content

sftool_lib/common/
erase_flash.rs

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