use std::io::{self, Read};
pub enum OperatingMode {
SingleChip,
Boot,
UserBoot,
}
pub trait Target: io::Read + io::Write {
fn clear_buffers(&mut self) -> io::Result<()>;
fn set_baud_rate(&mut self, baud_rate: u32) -> io::Result<()>;
fn bytes_to_read(&mut self) -> io::Result<u32>;
fn reset_into(&mut self, operating_mode: OperatingMode);
}
pub struct SerialTarget {
p: Box<dyn serialport::SerialPort>,
}
impl SerialTarget {
pub fn new(p: Box<dyn serialport::SerialPort>) -> SerialTarget {
SerialTarget { p }
}
}
impl Target for SerialTarget {
fn clear_buffers(&mut self) -> io::Result<()> {
Ok(self.p.clear(serialport::ClearBuffer::All)?)
}
fn set_baud_rate(&mut self, baud_rate: u32) -> io::Result<()> {
Ok(self.p.set_baud_rate(baud_rate)?)
}
fn bytes_to_read(&mut self) -> io::Result<u32> {
Ok(self.p.bytes_to_read()?)
}
fn reset_into(&mut self, operating_mode: OperatingMode) {
let operating_mode_str = match operating_mode {
OperatingMode::SingleChip => "single-chip",
OperatingMode::Boot => "boot",
OperatingMode::UserBoot => "user boot",
};
println!("The selected debug adapter does not support automatic reset. Please reset the target into {} mode and press ENTER.", operating_mode_str);
io::stdin().read_exact(&mut [0u8]).unwrap();
println!("Continuing...");
}
}
impl io::Read for SerialTarget {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.p.read(buf)
}
}
impl io::Write for SerialTarget {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.p.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.p.flush()
}
}