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