Skip to main content

sftool_lib/sf32lb52/
sifli_debug.rs

1use super::SF32LB52Tool;
2use crate::Result;
3use crate::common::serial_io::is_cancelled_io_error;
4use crate::common::sifli_debug::{
5    ChipFrameFormat, RecvError, START_WORD, SifliUartCommand, SifliUartResponse, common_debug,
6};
7use std::io::{BufReader, Read};
8
9// Re-export for the module
10pub use crate::common::sifli_debug::SifliDebug;
11
12// SF32LB52 specific frame format implementation
13pub struct SF32LB52FrameFormat;
14
15impl ChipFrameFormat for SF32LB52FrameFormat {
16    fn create_header(len: u16) -> Vec<u8> {
17        let mut header = vec![];
18        header.extend_from_slice(&START_WORD);
19        // SF32LB52 uses little-endian for data length
20        header.extend_from_slice(&len.to_le_bytes());
21        header.push(0x10);
22        header.push(0x00);
23        header
24    }
25
26    fn parse_frame_header<R: Read>(
27        reader: &mut BufReader<R>,
28    ) -> std::result::Result<usize, RecvError> {
29        // 读取长度 (2字节) - SF32LB52 uses little-endian
30        let mut length_bytes = [0; 2];
31        if let Err(e) = reader.read_exact(&mut length_bytes) {
32            if is_cancelled_io_error(&e) {
33                return Err(RecvError::Cancelled);
34            }
35            tracing::error!("Failed to read length bytes: {}", e);
36            return Err(RecvError::InvalidHeaderLength);
37        }
38
39        let payload_size = u16::from_le_bytes(length_bytes) as usize;
40
41        // 读取通道和CRC (2字节)
42        let mut channel_crc = [0; 2];
43        if let Err(e) = reader.read_exact(&mut channel_crc) {
44            if is_cancelled_io_error(&e) {
45                return Err(RecvError::Cancelled);
46            }
47            tracing::error!("Failed to read channel and CRC bytes: {}", e);
48            return Err(RecvError::InvalidHeaderChannel);
49        }
50
51        Ok(payload_size)
52    }
53
54    fn encode_command_data(command: &SifliUartCommand) -> Vec<u8> {
55        let mut send_data = vec![];
56        match command {
57            SifliUartCommand::Enter => {
58                let temp = [0x41, 0x54, 0x53, 0x46, 0x33, 0x32, 0x05, 0x21];
59                send_data.extend_from_slice(&temp);
60            }
61            SifliUartCommand::Exit => {
62                let temp = [0x41, 0x54, 0x53, 0x46, 0x33, 0x32, 0x18, 0x21];
63                send_data.extend_from_slice(&temp);
64            }
65            SifliUartCommand::MEMRead { addr, len } => {
66                send_data.push(0x40);
67                send_data.push(0x72);
68                // SF32LB52 uses little-endian for address and length
69                send_data.extend_from_slice(&addr.to_le_bytes());
70                send_data.extend_from_slice(&len.to_le_bytes());
71            }
72            SifliUartCommand::MEMWrite { addr, data } => {
73                send_data.push(0x40);
74                send_data.push(0x77);
75                // SF32LB52 uses little-endian for address and data length
76                send_data.extend_from_slice(&addr.to_le_bytes());
77                send_data.extend_from_slice(&(data.len() as u16).to_le_bytes());
78                for d in data.iter() {
79                    send_data.extend_from_slice(&d.to_le_bytes());
80                }
81            }
82        }
83        send_data
84    }
85
86    fn decode_response_data(data: &[u8]) -> u32 {
87        // SF32LB52 uses little-endian
88        u32::from_le_bytes([data[0], data[1], data[2], data[3]])
89    }
90
91    // SF32LB52 uses no address mapping
92    fn map_address(addr: u32) -> u32 {
93        addr
94    }
95}
96
97impl crate::common::sifli_debug::SifliDebug for SF32LB52Tool {
98    fn debug_command(&mut self, command: SifliUartCommand) -> Result<SifliUartResponse> {
99        common_debug::debug_command_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self, command)
100    }
101
102    fn debug_read_word32(&mut self, addr: u32) -> Result<u32> {
103        common_debug::debug_read_word32_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self, addr)
104    }
105
106    fn debug_write_word32(&mut self, addr: u32, data: u32) -> Result<()> {
107        common_debug::debug_write_word32_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self, addr, data)
108    }
109
110    fn debug_write_memory(&mut self, addr: u32, data: &[u8]) -> Result<()> {
111        common_debug::debug_write_memory_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self, addr, data)
112    }
113
114    fn debug_write_core_reg(&mut self, reg: u16, data: u32) -> Result<()> {
115        common_debug::debug_write_core_reg_impl::<SF32LB52Tool, SF32LB52FrameFormat>(
116            self, reg, data,
117        )
118    }
119
120    fn debug_step(&mut self) -> Result<()> {
121        common_debug::debug_step_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self)
122    }
123
124    fn debug_run(&mut self) -> Result<()> {
125        common_debug::debug_run_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self)
126    }
127
128    fn debug_halt(&mut self) -> Result<()> {
129        common_debug::debug_halt_impl::<SF32LB52Tool, SF32LB52FrameFormat>(self)
130    }
131}