1pub mod erase_flash;
2mod ram_stub;
3pub mod read_flash;
4pub mod reset;
5pub mod speed;
6pub mod stub_config;
7pub mod utils;
8pub mod write_flash;
9
10pub mod error;
11
12pub mod progress;
14
15pub mod common;
17
18pub mod sf32lb52;
20pub mod sf32lb55;
21pub mod sf32lb56;
22pub mod sf32lb58;
23
24pub use crate::erase_flash::EraseFlashTrait;
26pub use crate::read_flash::ReadFlashTrait;
27pub use crate::write_flash::WriteFlashTrait;
28pub use error::{Error, Result};
29
30use crate::progress::{ProgressCallbackArc, ProgressHelper, no_op_progress_callback};
31use serialport::SerialPort;
32use std::sync::Arc;
33
34pub fn load_stub_bytes(
36 external_path: Option<&str>,
37 chip_type: ChipType,
38 memory_type: &str,
39) -> Result<Vec<u8>> {
40 let chip_key = match chip_type {
41 ChipType::SF32LB52 => "sf32lb52",
42 ChipType::SF32LB55 => "sf32lb55",
43 ChipType::SF32LB56 => "sf32lb56",
44 ChipType::SF32LB58 => "sf32lb58",
45 };
46 let key = format!("{}_{}", chip_key, memory_type.to_lowercase());
47 let stub = ram_stub::load_stub_file(external_path, &key)?;
48 Ok(stub.data.into_owned())
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
53pub enum BeforeOperation {
54 #[cfg_attr(feature = "cli", clap(name = "default_reset"))]
55 DefaultReset,
56 #[cfg_attr(feature = "cli", clap(name = "no_reset"))]
57 NoReset,
58 #[cfg_attr(feature = "cli", clap(name = "no_reset_no_sync"))]
59 NoResetNoSync,
60}
61
62impl BeforeOperation {
63 pub fn requires_reset(&self) -> bool {
64 matches!(self, Self::DefaultReset)
65 }
66
67 pub fn should_download_stub(&self) -> bool {
68 !matches!(self, Self::NoResetNoSync)
69 }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq)]
73#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
74pub enum AfterOperation {
75 #[cfg_attr(feature = "cli", clap(name = "no_reset"))]
76 NoReset,
77 #[cfg_attr(feature = "cli", clap(name = "soft_reset"))]
78 SoftReset,
79}
80
81impl AfterOperation {
82 pub fn requires_soft_reset(&self) -> bool {
83 matches!(self, Self::SoftReset)
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
89pub enum ChipType {
90 #[cfg_attr(feature = "cli", clap(name = "SF32LB52"))]
91 SF32LB52,
92 #[cfg_attr(feature = "cli", clap(name = "SF32LB55"))]
93 SF32LB55,
94 #[cfg_attr(feature = "cli", clap(name = "SF32LB56"))]
95 SF32LB56,
96 #[cfg_attr(feature = "cli", clap(name = "SF32LB58"))]
97 SF32LB58,
98}
99
100#[derive(Clone)]
101pub struct SifliToolBase {
102 pub port_name: String,
103 pub before: BeforeOperation,
104 pub memory_type: String,
105 pub baud: u32,
106 pub connect_attempts: i8,
107 pub compat: bool,
108 pub progress_callback: ProgressCallbackArc,
109 pub progress_helper: Arc<ProgressHelper>,
110 pub external_stub_path: Option<String>,
112}
113
114impl SifliToolBase {
115 pub fn new_with_no_progress(
117 port_name: String,
118 before: BeforeOperation,
119 memory_type: String,
120 baud: u32,
121 connect_attempts: i8,
122 compat: bool,
123 ) -> Self {
124 let progress_callback = no_op_progress_callback();
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 external_stub_path: None,
136 }
137 }
138
139 pub fn new_with_progress(
141 port_name: String,
142 before: BeforeOperation,
143 memory_type: String,
144 baud: u32,
145 connect_attempts: i8,
146 compat: bool,
147 progress_callback: ProgressCallbackArc,
148 ) -> Self {
149 let progress_helper = Arc::new(ProgressHelper::new(progress_callback.clone(), 0));
150 Self {
151 port_name,
152 before,
153 memory_type,
154 baud,
155 connect_attempts,
156 compat,
157 progress_callback,
158 progress_helper,
159 external_stub_path: None,
160 }
161 }
162
163 #[allow(clippy::too_many_arguments)]
165 pub fn new_with_external_stub(
166 port_name: String,
167 before: BeforeOperation,
168 memory_type: String,
169 baud: u32,
170 connect_attempts: i8,
171 compat: bool,
172 progress_callback: ProgressCallbackArc,
173 external_stub_path: Option<String>,
174 ) -> Self {
175 let progress_helper = Arc::new(ProgressHelper::new(progress_callback.clone(), 0));
176 Self {
177 port_name,
178 before,
179 memory_type,
180 baud,
181 connect_attempts,
182 compat,
183 progress_callback,
184 progress_helper,
185 external_stub_path,
186 }
187 }
188}
189
190pub struct WriteFlashParams {
191 pub files: Vec<WriteFlashFile>,
192 pub verify: bool,
193 pub no_compress: bool,
194 pub erase_all: bool,
195}
196
197#[derive(Debug)]
198pub struct WriteFlashFile {
199 pub address: u32,
200 pub file: std::fs::File,
201 pub crc32: u32,
202}
203
204pub struct ReadFlashParams {
205 pub files: Vec<ReadFlashFile>,
206}
207
208#[derive(Debug)]
209pub struct ReadFlashFile {
210 pub file_path: String,
211 pub address: u32,
212 pub size: u32,
213}
214
215#[derive(Clone)]
216pub struct EraseFlashParams {
217 pub address: u32,
218}
219
220pub struct EraseRegionParams {
221 pub regions: Vec<EraseRegionFile>,
222}
223
224#[derive(Debug)]
225pub struct EraseRegionFile {
226 pub address: u32,
227 pub size: u32,
228}
229
230pub trait SifliToolTrait: Send + Sync {
231 fn port(&mut self) -> &mut Box<dyn SerialPort>;
233
234 fn base(&self) -> &SifliToolBase;
236
237 fn progress(&mut self) -> Arc<ProgressHelper> {
239 self.base().progress_helper.clone()
241 }
242
243 fn set_speed(&mut self, baud: u32) -> Result<()>;
244 fn soft_reset(&mut self) -> Result<()>;
245}
246
247pub trait SifliTool:
248 SifliToolTrait + WriteFlashTrait + ReadFlashTrait + EraseFlashTrait + Send + Sync
249{
250 fn create_tool(base_param: SifliToolBase) -> Box<dyn SifliTool>
252 where
253 Self: Sized;
254}
255
256pub fn create_sifli_tool(chip_type: ChipType, base_param: SifliToolBase) -> Box<dyn SifliTool> {
258 match chip_type {
259 ChipType::SF32LB52 => sf32lb52::SF32LB52Tool::create_tool(base_param),
260 ChipType::SF32LB55 => sf32lb55::SF32LB55Tool::create_tool(base_param),
261 ChipType::SF32LB56 => sf32lb56::SF32LB56Tool::create_tool(base_param),
262 ChipType::SF32LB58 => sf32lb58::SF32LB58Tool::create_tool(base_param),
263 }
264}