st3215/
port_handler.rs

1use serialport::SerialPort;
2use std::time::{Duration, Instant};
3use crate::values::*;
4
5pub struct PortHandler {
6    port: Option<Box<dyn SerialPort>>,
7    port_name: String,
8    baudrate: u32,
9    packet_start_time: Instant,
10    packet_timeout: Duration,
11    tx_time_per_byte: f64,
12    pub is_using: bool,
13}
14
15impl PortHandler {
16    pub fn new(port_name: &str) -> Self {
17        Self {
18            port: None,
19            port_name: port_name.to_string(),
20            baudrate: DEFAULT_BAUDRATE,
21            packet_start_time: Instant::now(),
22            packet_timeout: Duration::from_millis(100), //ms
23            tx_time_per_byte: 0.0,
24            is_using: false,
25        }
26    }
27
28    pub fn open_port(&mut self) -> Result<(), String> {
29        self.setup_port()
30    }
31
32    pub fn close_port(&mut self) {
33        self.port = None;
34    }
35
36    pub fn clear_port(&mut self) -> Result<(), String> {
37        if let Some(ref mut port) = self.port {
38            port.flush().map_err(|e| e.to_string())?;
39        }
40        Ok(())
41    }
42
43    pub fn get_bytes_available(&mut self) -> Result<u32, String> {
44        if let Some(ref mut port) = self.port {
45            port.bytes_to_read().map_err(|e| e.to_string())
46        } else {
47            Ok(0)
48        }
49    }
50
51    pub fn read_port(&mut self, length: usize) -> Result<Vec<u8>, String> {
52        if let Some(ref mut port) = self.port {
53            let mut buffer = vec![0u8; length];
54            let bytes_read = port.read(&mut buffer).map_err(|e| e.to_string())?;
55            buffer.truncate(bytes_read);
56            Ok(buffer)
57        } else {
58            Ok(Vec::new())
59        }
60    }
61
62    pub fn write_port(&mut self, packet: &[u8]) -> Result<usize, String> {
63        if let Some(ref mut port) = self.port {
64            port.write(packet).map_err(|e| e.to_string())
65        } else {
66            Err("Port not open".to_string())
67        }
68    }
69
70    pub fn set_packet_timeout(&mut self, packet_length: usize) {
71        self.packet_start_time = Instant::now();
72        let timeout_ms = (self.tx_time_per_byte * packet_length as f64)
73            + (self.tx_time_per_byte * 3.0)
74            + LATENCY_TIMER;
75        self.packet_timeout = Duration::from_millis(timeout_ms as u64);
76    }
77
78    pub fn set_packet_timeout_millis(&mut self, msec: u64) {
79        self.packet_start_time = Instant::now();
80        self.packet_timeout = Duration::from_millis(msec);
81    }
82
83    pub fn is_packet_timeout(&mut self) -> bool {
84        if self.get_time_since_start() > self.packet_timeout {
85            self.packet_timeout = Duration::from_millis(0);
86            true
87        } else {
88            false
89        }
90    }
91
92    fn get_time_since_start(&self) -> Duration {
93        Instant::now().duration_since(self.packet_start_time)
94    }
95
96    fn setup_port(&mut self) -> Result<(), String> {
97        let mut port = serialport::new(&self.port_name, self.baudrate)
98            .timeout(Duration::from_millis(100))
99            .open()
100            .map_err(|e| format!("Could not open port {}: {}", self.port_name, e))?;
101
102        // Configure data bits, stop bits, parity
103        port.set_data_bits(serialport::DataBits::Eight)
104            .map_err(|e| format!("Failed to set data bits: {}", e))?;
105        
106        port.set_stop_bits(serialport::StopBits::One)
107            .map_err(|e| format!("Failed to set stop bits: {}", e))?;
108        
109        port.set_parity(serialport::Parity::None)
110            .map_err(|e| format!("Failed to set parity: {}", e))?;
111
112        // Disable flow control
113        port.set_flow_control(serialport::FlowControl::None)
114            .map_err(|e| format!("Failed to set flow control: {}", e))?;
115
116        // Clear input buffer
117        port.clear(serialport::ClearBuffer::Input)
118            .map_err(|e| format!("Failed to clear buffer: {}", e))?;
119
120        self.port = Some(port);
121
122        self.tx_time_per_byte = (1000.0 / self.baudrate as f64) * 10.0;
123
124        Ok(())
125    }
126}