1pub mod erase_flash;
4pub mod ram_command;
5pub mod read_flash;
6pub mod reset;
7pub mod sifli_debug;
8pub mod speed;
9pub mod write_flash;
10
11use crate::common::serial_io::is_cancelled_io_error;
12use crate::common::serial_io::{for_tool, sleep_with_cancel};
13use crate::common::sifli_debug::{
14 ChipFrameFormat, RecvError, START_WORD, SifliDebug, SifliUartCommand, SifliUartResponse,
15 common_debug,
16};
17use crate::progress::{
18 EraseFlashStyle, EraseRegionStyle, ProgressOperation, ProgressStatus, StubStage,
19};
20use crate::sf32lb56::ram_command::DownloadStub;
21use crate::{Result, SifliTool, SifliToolBase, SifliToolTrait};
22use serialport::SerialPort;
23use std::io::{BufReader, Read};
24use std::time::Duration;
25
26pub struct SF32LB56FrameFormat;
28
29impl ChipFrameFormat for SF32LB56FrameFormat {
30 fn create_header(len: u16) -> Vec<u8> {
31 let mut header = vec![];
32 header.extend_from_slice(&START_WORD);
33 header.extend_from_slice(&len.to_be_bytes());
35 header.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]);
37 header.push(0x10);
39 header.push(0x00);
41 header.extend_from_slice(&[0x00, 0x00]);
43 header
44 }
45
46 fn parse_frame_header<R: Read>(
47 reader: &mut BufReader<R>,
48 ) -> std::result::Result<usize, RecvError> {
49 let mut length_bytes = [0; 2];
51 if let Err(e) = reader.read_exact(&mut length_bytes) {
52 if is_cancelled_io_error(&e) {
53 return Err(RecvError::Cancelled);
54 }
55 tracing::error!("Failed to read length bytes: {}", e);
56 return Err(RecvError::InvalidHeaderLength);
57 }
58
59 let payload_size = u16::from_be_bytes(length_bytes) as usize;
60
61 let mut timestamp_bytes = [0; 4];
63 if let Err(e) = reader.read_exact(&mut timestamp_bytes) {
64 if is_cancelled_io_error(&e) {
65 return Err(RecvError::Cancelled);
66 }
67 tracing::error!("Failed to read timestamp bytes: {}", e);
68 return Err(RecvError::InvalidHeaderChannel);
69 }
70
71 let mut channel_crc = [0; 2];
73 if let Err(e) = reader.read_exact(&mut channel_crc) {
74 if is_cancelled_io_error(&e) {
75 return Err(RecvError::Cancelled);
76 }
77 tracing::error!("Failed to read channel and CRC bytes: {}", e);
78 return Err(RecvError::InvalidHeaderChannel);
79 }
80
81 let mut reserved_bytes = [0; 2];
83 if let Err(e) = reader.read_exact(&mut reserved_bytes) {
84 if is_cancelled_io_error(&e) {
85 return Err(RecvError::Cancelled);
86 }
87 tracing::error!("Failed to read reserved bytes: {}", e);
88 return Err(RecvError::ReadError(e));
89 }
90
91 Ok(payload_size)
92 }
93
94 fn encode_command_data(command: &SifliUartCommand) -> Vec<u8> {
95 let mut send_data = vec![];
96 match command {
97 SifliUartCommand::Enter => {
98 let temp = [0x41, 0x54, 0x53, 0x46, 0x33, 0x32, 0x05, 0x21];
99 send_data.extend_from_slice(&temp);
100 }
101 SifliUartCommand::Exit => {
102 let temp = [0x41, 0x54, 0x53, 0x46, 0x33, 0x32, 0x18, 0x21];
103 send_data.extend_from_slice(&temp);
104 }
105 SifliUartCommand::MEMRead { addr, len } => {
106 send_data.push(0x40);
107 send_data.push(0x72);
108 send_data.extend_from_slice(&addr.to_be_bytes());
110 send_data.extend_from_slice(&len.to_be_bytes());
111 }
112 SifliUartCommand::MEMWrite { addr, data } => {
113 send_data.push(0x40);
114 send_data.push(0x77);
115 send_data.extend_from_slice(&addr.to_be_bytes());
117 send_data.extend_from_slice(&(data.len() as u16).to_be_bytes());
118 for d in data.iter() {
119 send_data.extend_from_slice(&d.to_be_bytes());
120 }
121 }
122 }
123 send_data
124 }
125
126 fn decode_response_data(data: &[u8]) -> u32 {
127 u32::from_be_bytes([data[0], data[1], data[2], data[3]])
129 }
130
131 fn map_address(addr: u32) -> u32 {
133 let mut l_addr = addr;
134 if (0xE0000000..0xF0000000).contains(&addr) {
135 l_addr = (addr & 0x0fffffff) | 0xF0000000;
136 } else if (0x00400000..=0x0041FFFF).contains(&addr) {
138 l_addr += 0x20000000;
140 } else if (0x20C00000..=0x20C1FFFF).contains(&addr) {
141 l_addr -= 0x00800000;
143 } else if (0x20000000..=0x200C7FFF).contains(&addr) {
144 l_addr += 0x0A000000;
146 } else if (0x20800000..=0x20BFFFFF).contains(&addr) {
147 l_addr -= 0x20800000;
149 } else if (0x10000000..=0x1FFFFFFF).contains(&addr) {
150 l_addr += 0x50000000;
152 }
153 l_addr
154 }
155}
156
157pub struct SF32LB56Tool {
158 pub base: SifliToolBase,
159 pub port: Box<dyn SerialPort>,
160}
161
162unsafe impl Send for SF32LB56Tool {}
164unsafe impl Sync for SF32LB56Tool {}
165
166impl SifliDebug for SF32LB56Tool {
168 fn debug_command(&mut self, command: SifliUartCommand) -> Result<SifliUartResponse> {
169 common_debug::debug_command_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self, command)
170 }
171
172 fn debug_read_word32(&mut self, addr: u32) -> Result<u32> {
173 common_debug::debug_read_word32_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self, addr)
174 }
175
176 fn debug_write_word32(&mut self, addr: u32, data: u32) -> Result<()> {
177 common_debug::debug_write_word32_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self, addr, data)
178 }
179
180 fn debug_write_memory(&mut self, addr: u32, data: &[u8]) -> Result<()> {
181 common_debug::debug_write_memory_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self, addr, data)
182 }
183
184 fn debug_write_core_reg(&mut self, reg: u16, data: u32) -> Result<()> {
185 common_debug::debug_write_core_reg_impl::<SF32LB56Tool, SF32LB56FrameFormat>(
186 self, reg, data,
187 )
188 }
189
190 fn debug_step(&mut self) -> Result<()> {
191 common_debug::debug_step_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self)
192 }
193
194 fn debug_run(&mut self) -> Result<()> {
195 common_debug::debug_run_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self)
196 }
197
198 fn debug_halt(&mut self) -> Result<()> {
199 common_debug::debug_halt_impl::<SF32LB56Tool, SF32LB56FrameFormat>(self)
200 }
201}
202
203impl SF32LB56Tool {
204 pub fn internal_erase_all(&mut self, address: u32) -> Result<()> {
206 use ram_command::{Command, RamCommand};
207
208 let progress = self.progress();
209 let spinner = progress.create_spinner(ProgressOperation::EraseFlash {
210 address,
211 style: EraseFlashStyle::Addressed,
212 });
213
214 let _ = self.command(Command::EraseAll { address });
216
217 let mut io = for_tool(self);
218 io.wait_for_pattern(
219 b"OK",
220 Duration::from_millis(30_000),
221 &format!("erasing flash at 0x{:08X}", address),
222 )?;
223
224 spinner.finish(ProgressStatus::Success);
225
226 Ok(())
227 }
228
229 pub fn internal_erase_region(&mut self, address: u32, len: u32) -> Result<()> {
231 use ram_command::{Command, RamCommand};
232
233 let progress = self.progress();
234 let spinner = progress.create_spinner(ProgressOperation::EraseRegion {
235 address,
236 len,
237 style: EraseRegionStyle::HexLength,
238 });
239
240 let _ = self.command(Command::Erase { address, len });
242
243 let mut io = for_tool(self);
244 io.wait_for_pattern(
245 b"OK",
246 Duration::from_millis(30_000),
247 &format!("erasing region at 0x{:08X}", address),
248 )?;
249
250 spinner.finish(ProgressStatus::Success);
251
252 Ok(())
253 }
254
255 pub fn attempt_connect(&mut self) -> Result<()> {
256 use crate::common::sifli_debug::{SifliUartCommand, SifliUartResponse};
257
258 let infinite_attempts = self.base.connect_attempts <= 0;
259 let mut remaining_attempts = if infinite_attempts {
260 None
261 } else {
262 Some(self.base.connect_attempts)
263 };
264 loop {
265 if self.base.before.requires_reset() {
266 let mut io = for_tool(self);
268 io.write_request_to_send(true)?;
269 io.sleep(Duration::from_millis(100))?;
270 io.write_request_to_send(false)?;
271 io.sleep(Duration::from_millis(100))?;
272 }
273 let value: Result<()> = match self.debug_command(SifliUartCommand::Enter) {
274 Ok(SifliUartResponse::Enter) => Ok(()),
275 _ => Err(std::io::Error::other("Failed to enter debug mode").into()),
276 };
277 if let Some(ref mut attempts) = remaining_attempts {
279 if *attempts == 0 {
280 break; }
282 *attempts -= 1;
283 }
284
285 let progress = self.progress();
286 let spinner = progress.create_spinner(ProgressOperation::Connect);
287
288 match value {
290 Ok(_) => {
291 spinner.finish(ProgressStatus::Success);
292 return Ok(());
293 }
294 Err(_) => {
295 spinner.finish(ProgressStatus::Retry);
296 sleep_with_cancel(&self.base.cancel_token, Duration::from_millis(500))?;
297 }
298 }
299 }
300 Err(std::io::Error::other("Failed to connect to the chip").into())
301 }
302
303 pub fn download_stub_impl(&mut self) -> Result<()> {
304 use crate::common::sifli_debug::SifliUartCommand;
305 use crate::ram_stub::load_stub_file;
306 use probe_rs::MemoryMappedRegister;
307 use probe_rs::architecture::arm::core::armv7m::{Aircr, Demcr};
308 use probe_rs::architecture::arm::core::registers::cortex_m::{PC, SP};
309
310 let progress = self.progress();
311 let spinner = progress.create_spinner(ProgressOperation::DownloadStub {
312 stage: StubStage::Start,
313 });
314
315 self.debug_halt()?;
317 let mut data = self.debug_read_word32(0x4004_0028)?;
319 if data & 0x20 != 0 {
320 data = 0xa05f0003;
321 self.debug_write_word32(0x3000_EDF0, data)?;
323 }
324
325 let demcr = self.debug_read_word32(Demcr::get_mmio_address() as u32)?;
328 let mut demcr = Demcr(demcr);
329 demcr.set_vc_corereset(true);
330 self.debug_write_word32(Demcr::get_mmio_address() as u32, demcr.into())?;
331
332 let mut aircr = Aircr(0);
334 aircr.vectkey();
335 aircr.set_sysresetreq(true);
336 let _ = self.debug_write_word32(Aircr::get_mmio_address() as u32, aircr.into()); sleep_with_cancel(
338 &self.base.cancel_token,
339 std::time::Duration::from_millis(10),
340 )?;
341
342 self.debug_command(SifliUartCommand::Enter)?;
344
345 self.debug_halt()?;
347
348 let demcr = self.debug_read_word32(Demcr::get_mmio_address() as u32)?;
350 let mut demcr = Demcr(demcr);
351 demcr.set_vc_corereset(false);
352 self.debug_write_word32(Demcr::get_mmio_address() as u32, demcr.into())?;
353
354 sleep_with_cancel(
355 &self.base.cancel_token,
356 std::time::Duration::from_millis(100),
357 )?;
358 let chip_memory_key = format!("sf32lb56_{}", self.base.memory_type);
360 let stub = match load_stub_file(self.base.external_stub_path.as_deref(), &chip_memory_key) {
361 Ok(s) => s,
362 Err(e) => {
363 spinner.finish(ProgressStatus::NotFound);
364 return Err(e.into());
365 }
366 };
367
368 let packet_size = if self.base.compat { 256 } else { 64 * 1024 };
369
370 let mut addr = 0x2006_7000;
371 let mut data = &stub.data[..];
372 while !data.is_empty() {
373 let chunk = &data[..std::cmp::min(data.len(), packet_size)];
374 self.debug_write_memory(addr, chunk)?;
375 addr += chunk.len() as u32;
376 data = &data[chunk.len()..];
377 }
378
379 let sp = u32::from_le_bytes(
382 stub.data[0..4]
383 .try_into()
384 .expect("slice with exactly 4 bytes"),
385 );
386 let pc = u32::from_le_bytes(
387 stub.data[4..8]
388 .try_into()
389 .expect("slice with exactly 4 bytes"),
390 );
391 self.debug_write_core_reg(PC.id.0, pc)?;
392 self.debug_write_core_reg(SP.id.0, sp)?;
393
394 self.debug_run()?;
396
397 spinner.finish(ProgressStatus::Success);
398
399 Ok(())
400 }
401}
402
403impl SifliTool for SF32LB56Tool {
404 fn create_tool(base: SifliToolBase) -> Box<dyn SifliTool> {
405 let mut port = serialport::new(&base.port_name, 1000000)
406 .timeout(Duration::from_secs(5))
407 .open()
408 .unwrap();
409 port.write_request_to_send(false).unwrap();
410 std::thread::sleep(Duration::from_millis(100));
411
412 let mut tool = Box::new(Self { base, port });
413 if tool.base.before.should_download_stub() {
414 tool.download_stub().expect("Failed to download stub");
415 }
416 tool
417 }
418}
419
420impl SifliToolTrait for SF32LB56Tool {
421 fn port(&mut self) -> &mut Box<dyn SerialPort> {
422 &mut self.port
423 }
424
425 fn base(&self) -> &SifliToolBase {
426 &self.base
427 }
428
429 fn set_speed(&mut self, baud: u32) -> Result<()> {
430 use crate::speed::SpeedTrait;
431 SpeedTrait::set_speed(self, baud)
432 }
433
434 fn soft_reset(&mut self) -> Result<()> {
435 use crate::reset::Reset;
436 Reset::soft_reset(self)
437 }
438}