sftool_lib/
lib.rs

1pub mod erase_flash;
2mod ram_stub;
3pub mod read_flash;
4pub mod reset;
5pub mod speed;
6pub mod utils;
7pub mod write_flash;
8
9pub mod error;
10
11// 进度条回调系统
12pub mod progress;
13
14// 公共模块,包含可复用的逻辑
15pub mod common;
16
17// 芯片特定的实现模块
18pub mod sf32lb52;
19pub mod sf32lb55;
20pub mod sf32lb56;
21pub mod sf32lb58;
22
23// 重新导出 trait,使其在 crate 外部可用
24pub use crate::erase_flash::EraseFlashTrait;
25pub use crate::read_flash::ReadFlashTrait;
26pub use crate::write_flash::WriteFlashTrait;
27pub use error::{Error, Result};
28
29use crate::progress::{ProgressCallbackArc, ProgressHelper, no_op_progress_callback};
30use serialport::SerialPort;
31use std::sync::Arc;
32
33#[derive(Debug, Clone, PartialEq, Eq)]
34#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
35pub enum BeforeOperation {
36    #[cfg_attr(feature = "cli", clap(name = "default_reset"))]
37    DefaultReset,
38    #[cfg_attr(feature = "cli", clap(name = "no_reset"))]
39    NoReset,
40    #[cfg_attr(feature = "cli", clap(name = "no_reset_no_sync"))]
41    NoResetNoSync,
42}
43
44impl BeforeOperation {
45    pub fn requires_reset(&self) -> bool {
46        matches!(self, Self::DefaultReset)
47    }
48
49    pub fn should_download_stub(&self) -> bool {
50        !matches!(self, Self::NoResetNoSync)
51    }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
55#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
56pub enum AfterOperation {
57    #[cfg_attr(feature = "cli", clap(name = "no_reset"))]
58    NoReset,
59    #[cfg_attr(feature = "cli", clap(name = "soft_reset"))]
60    SoftReset,
61}
62
63impl AfterOperation {
64    pub fn requires_soft_reset(&self) -> bool {
65        matches!(self, Self::SoftReset)
66    }
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
70#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
71pub enum ChipType {
72    #[cfg_attr(feature = "cli", clap(name = "SF32LB52"))]
73    SF32LB52,
74    #[cfg_attr(feature = "cli", clap(name = "SF32LB55"))]
75    SF32LB55,
76    #[cfg_attr(feature = "cli", clap(name = "SF32LB56"))]
77    SF32LB56,
78    #[cfg_attr(feature = "cli", clap(name = "SF32LB58"))]
79    SF32LB58,
80}
81
82#[derive(Clone)]
83pub struct SifliToolBase {
84    pub port_name: String,
85    pub before: BeforeOperation,
86    pub memory_type: String,
87    pub baud: u32,
88    pub connect_attempts: i8,
89    pub compat: bool,
90    pub progress_callback: ProgressCallbackArc,
91    pub progress_helper: Arc<ProgressHelper>,
92    /// 外部 stub 文件路径,如果指定则优先使用外部文件而非内嵌文件
93    pub external_stub_path: Option<String>,
94}
95
96impl SifliToolBase {
97    /// 创建一个使用默认空进度回调的 SifliToolBase
98    pub fn new_with_no_progress(
99        port_name: String,
100        before: BeforeOperation,
101        memory_type: String,
102        baud: u32,
103        connect_attempts: i8,
104        compat: bool,
105    ) -> Self {
106        let progress_callback = no_op_progress_callback();
107        let progress_helper = Arc::new(ProgressHelper::new(progress_callback.clone(), 0));
108        Self {
109            port_name,
110            before,
111            memory_type,
112            baud,
113            connect_attempts,
114            compat,
115            progress_callback,
116            progress_helper,
117            external_stub_path: None,
118        }
119    }
120
121    /// 创建一个使用自定义进度回调的 SifliToolBase
122    pub fn new_with_progress(
123        port_name: String,
124        before: BeforeOperation,
125        memory_type: String,
126        baud: u32,
127        connect_attempts: i8,
128        compat: bool,
129        progress_callback: ProgressCallbackArc,
130    ) -> Self {
131        let progress_helper = Arc::new(ProgressHelper::new(progress_callback.clone(), 0));
132        Self {
133            port_name,
134            before,
135            memory_type,
136            baud,
137            connect_attempts,
138            compat,
139            progress_callback,
140            progress_helper,
141            external_stub_path: None,
142        }
143    }
144
145    /// 创建一个使用自定义进度回调和外部 stub 文件的 SifliToolBase
146    #[allow(clippy::too_many_arguments)]
147    pub fn new_with_external_stub(
148        port_name: String,
149        before: BeforeOperation,
150        memory_type: String,
151        baud: u32,
152        connect_attempts: i8,
153        compat: bool,
154        progress_callback: ProgressCallbackArc,
155        external_stub_path: Option<String>,
156    ) -> Self {
157        let progress_helper = Arc::new(ProgressHelper::new(progress_callback.clone(), 0));
158        Self {
159            port_name,
160            before,
161            memory_type,
162            baud,
163            connect_attempts,
164            compat,
165            progress_callback,
166            progress_helper,
167            external_stub_path,
168        }
169    }
170}
171
172pub struct WriteFlashParams {
173    pub files: Vec<WriteFlashFile>,
174    pub verify: bool,
175    pub no_compress: bool,
176    pub erase_all: bool,
177}
178
179#[derive(Debug)]
180pub struct WriteFlashFile {
181    pub address: u32,
182    pub file: std::fs::File,
183    pub crc32: u32,
184}
185
186pub struct ReadFlashParams {
187    pub files: Vec<ReadFlashFile>,
188}
189
190#[derive(Debug)]
191pub struct ReadFlashFile {
192    pub file_path: String,
193    pub address: u32,
194    pub size: u32,
195}
196
197#[derive(Clone)]
198pub struct EraseFlashParams {
199    pub address: u32,
200}
201
202pub struct EraseRegionParams {
203    pub regions: Vec<EraseRegionFile>,
204}
205
206#[derive(Debug)]
207pub struct EraseRegionFile {
208    pub address: u32,
209    pub size: u32,
210}
211
212pub trait SifliToolTrait: Send + Sync {
213    /// 获取串口的可变引用
214    fn port(&mut self) -> &mut Box<dyn SerialPort>;
215
216    /// 获取基础配置的引用
217    fn base(&self) -> &SifliToolBase;
218
219    /// 获取进度助手
220    fn progress(&mut self) -> Arc<ProgressHelper> {
221        // 使用共享的进度助手,它会自动处理步骤计数
222        self.base().progress_helper.clone()
223    }
224
225    fn set_speed(&mut self, baud: u32) -> Result<()>;
226    fn soft_reset(&mut self) -> Result<()>;
227}
228
229pub trait SifliTool:
230    SifliToolTrait + WriteFlashTrait + ReadFlashTrait + EraseFlashTrait + Send + Sync
231{
232    /// 工厂函数,根据芯片类型创建对应的 SifliTool 实现
233    fn create_tool(base_param: SifliToolBase) -> Box<dyn SifliTool>
234    where
235        Self: Sized;
236}
237
238/// 工厂函数,根据芯片类型创建对应的 SifliTool 实现
239pub fn create_sifli_tool(chip_type: ChipType, base_param: SifliToolBase) -> Box<dyn SifliTool> {
240    match chip_type {
241        ChipType::SF32LB52 => sf32lb52::SF32LB52Tool::create_tool(base_param),
242        ChipType::SF32LB55 => sf32lb55::SF32LB55Tool::create_tool(base_param),
243        ChipType::SF32LB56 => sf32lb56::SF32LB56Tool::create_tool(base_param),
244        ChipType::SF32LB58 => sf32lb58::SF32LB58Tool::create_tool(base_param),
245    }
246}