Skip to content

Commit 0aef16b

Browse files
author
George Cosma
committed
wip: refactor board-conenction
Signed-off-by: George Cosma <george.cosma@wyliodrin.com>
1 parent c010fa0 commit 0aef16b

1 file changed

Lines changed: 107 additions & 61 deletions

File tree

tockloader-lib/src/connection.rs

Lines changed: 107 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use std::time::Duration;
22

33
use probe_rs::probe::DebugProbeInfo;
44
use probe_rs::{Permissions, Session};
5+
use tokio::io::AsyncWriteExt;
56
use tokio_serial::{FlowControl, Parity, SerialPort, SerialStream, StopBits};
67

78
use crate::errors::TockloaderError;
89

9-
pub enum ConnectionInfo {
10-
SerialInfo(String, SerialTargetInfo),
11-
ProbeInfo(DebugProbeInfo, ProbeTargetInfo),
12-
}
10+
// pub enum ConnectionInfo {
11+
// SerialInfo(String, SerialTargetInfo),
12+
// ProbeInfo(DebugProbeInfo, ProbeTargetInfo),
13+
// }
1314

1415
pub struct ProbeTargetInfo {
1516
pub chip: String,
@@ -46,65 +47,110 @@ impl Default for SerialTargetInfo {
4647
}
4748
}
4849

49-
// TODO(george-cosma): trait? and 2 struct ProbeConnection and SerialConection?
50-
#[allow(clippy::large_enum_variant)]
51-
pub enum Connection {
52-
ProbeRS {
53-
session: Session,
54-
info: ProbeTargetInfo,
55-
},
56-
Serial {
57-
stream: SerialStream,
58-
info: SerialTargetInfo,
59-
},
50+
pub trait Connection {
51+
async fn open(&mut self) -> Result<(), TockloaderError>;
52+
/// Closes the connection, if it is open. If it is not open, it does
53+
/// nothing. On error the state of the connection is unknown and calling
54+
/// `open` or any other method is undefined behavior.
55+
async fn close(&mut self) -> Result<(), TockloaderError>;
56+
fn is_open(&self) -> bool;
57+
}
58+
59+
pub struct ProbeRSConnection {
60+
session: Option<Session>,
61+
/// Used both to open new conections but also used during the session to
62+
/// provide information about the target
63+
target_info: ProbeTargetInfo,
64+
/// Only used for opening a new connection
65+
debug_probe: DebugProbeInfo,
6066
}
6167

62-
impl Connection {
63-
pub fn open(info: ConnectionInfo) -> Result<Connection, TockloaderError> {
64-
match info {
65-
ConnectionInfo::SerialInfo(path, target_info) => {
66-
let builder = tokio_serial::new(path, target_info.baud_rate);
67-
match SerialStream::open(&builder) {
68-
Ok(mut stream) => {
69-
stream
70-
.set_parity(target_info.parity)
71-
.map_err(TockloaderError::SerialInitializationError)?;
72-
stream
73-
.set_stop_bits(target_info.stop_bits)
74-
.map_err(TockloaderError::SerialInitializationError)?;
75-
stream
76-
.set_flow_control(target_info.flow_control)
77-
.map_err(TockloaderError::SerialInitializationError)?;
78-
stream
79-
.set_timeout(target_info.timeout)
80-
.map_err(TockloaderError::SerialInitializationError)?;
81-
stream
82-
.write_request_to_send(target_info.request_to_send)
83-
.map_err(TockloaderError::SerialInitializationError)?;
84-
stream
85-
.write_data_terminal_ready(target_info.data_terminal_ready)
86-
.map_err(TockloaderError::SerialInitializationError)?;
87-
Ok(Connection::Serial {
88-
stream,
89-
info: target_info,
90-
})
91-
}
92-
Err(e) => Err(TockloaderError::SerialInitializationError(e)),
93-
}
94-
}
95-
ConnectionInfo::ProbeInfo(probe_info, target_info) => {
96-
let probe = probe_info
97-
.open()
98-
.map_err(TockloaderError::ProbeRsInitializationError)?;
99-
100-
match probe.attach(&target_info.chip, Permissions::default()) {
101-
Ok(session) => Ok(Connection::ProbeRS {
102-
session,
103-
info: target_info,
104-
}),
105-
Err(e) => Err(TockloaderError::ProbeRsCommunicationError(e)),
106-
}
107-
}
68+
impl ProbeRSConnection {
69+
pub fn new(debug_probe: DebugProbeInfo, target_info: ProbeTargetInfo) -> Self {
70+
Self {
71+
session: None,
72+
target_info,
73+
debug_probe,
10874
}
10975
}
11076
}
77+
78+
impl Connection for ProbeRSConnection {
79+
async fn open(&mut self) -> Result<(), TockloaderError> {
80+
let probe = self
81+
.debug_probe
82+
.open()
83+
.map_err(TockloaderError::ProbeRsInitializationError)?;
84+
85+
self.session = Some(
86+
probe
87+
.attach(&self.target_info.chip, Permissions::default())
88+
.map_err(TockloaderError::ProbeRsCommunicationError)?,
89+
);
90+
91+
Ok(())
92+
}
93+
94+
async fn close(&mut self) -> Result<(), TockloaderError> {
95+
// Session implements Drop, so we don't need to explicitly close it.
96+
self.session = None;
97+
Ok(())
98+
}
99+
100+
fn is_open(&self) -> bool {
101+
self.session.is_some()
102+
}
103+
}
104+
105+
pub struct SerialConnection {
106+
stream: Option<SerialStream>,
107+
/// Used both to open new connections but also used during the session to
108+
/// provide information about the target
109+
target_info: SerialTargetInfo,
110+
/// Path to the serial port. This is only used for opening a new connection.
111+
port: String,
112+
}
113+
114+
impl SerialConnection {
115+
pub fn new(port: String, target_info: SerialTargetInfo) -> Self {
116+
Self {
117+
stream: None,
118+
target_info,
119+
port,
120+
}
121+
}
122+
}
123+
124+
impl Connection for SerialConnection {
125+
async fn open(&mut self) -> Result<(), TockloaderError> {
126+
let builder = tokio_serial::new(&self.port, self.target_info.baud_rate)
127+
.parity(self.target_info.parity)
128+
.stop_bits(self.target_info.stop_bits)
129+
.flow_control(self.target_info.flow_control)
130+
.timeout(self.target_info.timeout);
131+
132+
let mut stream =
133+
SerialStream::open(&builder).map_err(TockloaderError::SerialInitializationError)?;
134+
135+
stream
136+
.write_request_to_send(self.target_info.request_to_send)
137+
.map_err(TockloaderError::SerialInitializationError)?;
138+
stream
139+
.write_data_terminal_ready(self.target_info.data_terminal_ready)
140+
.map_err(TockloaderError::SerialInitializationError)?;
141+
142+
self.stream = Some(stream);
143+
Ok(())
144+
}
145+
146+
async fn close(&mut self) -> Result<(), TockloaderError> {
147+
if let Some(mut stream) = self.stream.take() {
148+
stream.shutdown().await;
149+
}
150+
Ok(())
151+
}
152+
153+
fn is_open(&self) -> bool {
154+
self.stream.is_some()
155+
}
156+
}

0 commit comments

Comments
 (0)