Added some stuff for the monitor (can already reboot the target)
This commit is contained in:
45
Cargo.lock
generated
45
Cargo.lock
generated
@@ -65,12 +65,29 @@ version = "0.2.175"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "numtoa"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f"
|
||||
|
||||
[[package]]
|
||||
name = "pbr"
|
||||
version = "1.1.1"
|
||||
@@ -112,6 +129,21 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"
|
||||
|
||||
[[package]]
|
||||
name = "serial2"
|
||||
version = "0.2.32"
|
||||
@@ -134,6 +166,18 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "4.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3669a69de26799d6321a5aa713f55f7e2cd37bd47be044b50f2acafc42c122bb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libredox",
|
||||
"numtoa",
|
||||
"redox_termios",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tulflash"
|
||||
version = "0.1.0"
|
||||
@@ -141,6 +185,7 @@ dependencies = [
|
||||
"argp",
|
||||
"pbr",
|
||||
"serial2",
|
||||
"termion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@@ -7,3 +7,4 @@ edition = "2024"
|
||||
argp = "0.4.0"
|
||||
pbr = "1.1.1"
|
||||
serial2 = "0.2.32"
|
||||
termion = "4.0.5"
|
||||
|
@@ -22,7 +22,8 @@ pub struct Args {
|
||||
pub enum ArgCommand {
|
||||
Read(ArgRead),
|
||||
Write(ArgWrite),
|
||||
Erase(ArgErase)
|
||||
Erase(ArgErase),
|
||||
Monitor(ArgMonitor)
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
@@ -80,6 +81,11 @@ pub struct ArgWrite {
|
||||
#[argp(subcommand, name = "erase")]
|
||||
pub struct ArgErase {}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argp(description = "Opens the serial monitor.")]
|
||||
#[argp(subcommand, name = "monitor")]
|
||||
pub struct ArgMonitor {}
|
||||
|
||||
pub fn parse() -> Args {
|
||||
let args: Args = argp::parse_args_or_exit(argp::DEFAULT);
|
||||
args
|
||||
|
13
src/main.rs
13
src/main.rs
@@ -9,6 +9,9 @@ use args::*;
|
||||
mod ihex;
|
||||
use ihex::{IntelHexWriter, IntelHexReader, DataRecord};
|
||||
|
||||
mod monitor;
|
||||
use monitor::Monitor;
|
||||
|
||||
mod target;
|
||||
use target::{PhysicalTarget, Target};
|
||||
|
||||
@@ -201,6 +204,13 @@ fn erase_chip(_args: ArgErase, target: &mut PhysicalTarget) -> Result<(), Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn monitor_chip(_args: ArgMonitor, target: &mut PhysicalTarget) -> Result<(), Error> {
|
||||
let _ = Monitor::new().run(target.port())?;
|
||||
target.resync_target().unwrap();
|
||||
target.read_info(0x00, 0x00).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = args::parse();
|
||||
|
||||
@@ -211,7 +221,8 @@ fn main() {
|
||||
let res = match args.command {
|
||||
ArgCommand::Read(args) => read_chip(args, &mut target),
|
||||
ArgCommand::Write(args) => write_chip(args, &mut target),
|
||||
ArgCommand::Erase(args) => erase_chip(args, &mut target)
|
||||
ArgCommand::Erase(args) => erase_chip(args, &mut target),
|
||||
ArgCommand::Monitor(args) => monitor_chip(args, &mut target)
|
||||
};
|
||||
|
||||
if let Err(err) = res {
|
||||
|
76
src/monitor.rs
Normal file
76
src/monitor.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::io::Error;
|
||||
use std::time::Duration;
|
||||
|
||||
use serial2::SerialPort;
|
||||
|
||||
use termion::raw::IntoRawMode;
|
||||
use termion::event::Key;
|
||||
use termion::input::TermRead;
|
||||
|
||||
pub struct Monitor {
|
||||
hooks: Vec<(Key, &'static str)>
|
||||
}
|
||||
|
||||
impl Monitor {
|
||||
pub fn new() -> Self {
|
||||
let mut hooks = Vec::new();
|
||||
|
||||
hooks.push((Key::Ctrl('c'), "Exit monitor"));
|
||||
hooks.push((Key::Ctrl('r'), "Reboot target"));
|
||||
|
||||
Self { hooks }
|
||||
}
|
||||
|
||||
pub fn add_hook(&mut self, key: Key, desc: &'static str) {
|
||||
self.hooks.push((key, desc));
|
||||
}
|
||||
|
||||
pub fn run(&mut self, port: &mut SerialPort) -> Result<Key, Error> {
|
||||
port.set_dtr(true)?;
|
||||
port.set_rts(true)?;
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
port.set_dtr(false)?;
|
||||
port.set_rts(false)?;
|
||||
|
||||
println!("Monitor controls:");
|
||||
|
||||
for (key, desc) in &self.hooks {
|
||||
let key = match key {
|
||||
Key::Char(c) => format!("{}", c.to_uppercase()),
|
||||
Key::Ctrl(c) => format!("Ctrl+{}", c.to_uppercase()),
|
||||
key => format!("{:?}", key)
|
||||
};
|
||||
|
||||
println!(" {} - {}", key, desc);
|
||||
}
|
||||
|
||||
println!();
|
||||
|
||||
let mut _stdout = std::io::stdout().into_raw_mode().unwrap();
|
||||
|
||||
let mut stdin = termion::async_stdin().keys();
|
||||
|
||||
'main: loop {
|
||||
if let Some(Ok(key)) = stdin.next() {
|
||||
if let Key::Ctrl('r') = key {
|
||||
port.set_dtr(true)?;
|
||||
port.set_rts(true)?;
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
port.set_dtr(false)?;
|
||||
port.set_rts(false)?;
|
||||
continue
|
||||
}
|
||||
|
||||
for (hook_key, _) in &self.hooks {
|
||||
if hook_key == &key {
|
||||
break 'main Ok(key)
|
||||
}
|
||||
}
|
||||
println!("{:?}\r", key);
|
||||
} else {
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,24 +22,10 @@ impl PhysicalTarget {
|
||||
|
||||
port.set_read_timeout(Duration::from_millis(100))?;
|
||||
|
||||
port.set_dtr(false)?;
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
|
||||
for i in (0..5).rev() {
|
||||
port.write(b"U")?;
|
||||
|
||||
let mut buf = [0u8; 1];
|
||||
port.read(&mut buf)?;
|
||||
|
||||
if buf[0] == b'U' { break }
|
||||
|
||||
if i == 0 {
|
||||
Err(Error::other(format!("Invalid sync response: 0x{:02X}", buf[0])))?
|
||||
}
|
||||
}
|
||||
|
||||
let mut new = Self { port };
|
||||
|
||||
new.resync_target()?;
|
||||
|
||||
let manufacturer = new.read_info(0x00, 0x00).unwrap();
|
||||
let family = new.read_info(0x00, 0x01).unwrap();
|
||||
let name = new.read_info(0x00, 0x02).unwrap();
|
||||
@@ -50,6 +36,29 @@ impl PhysicalTarget {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
pub fn resync_target(&mut self) -> Result<(), Error> {
|
||||
self.port.set_dtr(true)?;
|
||||
self.port.set_rts(true)?;
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
self.port.set_dtr(false)?;
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
|
||||
for i in (0..5).rev() {
|
||||
self.port.write(b"U")?;
|
||||
|
||||
let mut buf = [0u8; 1];
|
||||
self.port.read(&mut buf)?;
|
||||
|
||||
if buf[0] == b'U' { break }
|
||||
|
||||
if i == 0 {
|
||||
Err(Error::other(format!("Invalid sync response: 0x{:02X}", buf[0])))?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_info(&mut self, category: u8, idx: u8) -> Result<u8, Error> {
|
||||
self.send_command(0x05, 0, &[category, idx])?;
|
||||
|
||||
@@ -126,6 +135,10 @@ impl PhysicalTarget {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn port(&mut self) -> &mut SerialPort {
|
||||
&mut self.port
|
||||
}
|
||||
}
|
||||
|
||||
impl Target for PhysicalTarget {
|
||||
@@ -228,7 +241,11 @@ impl Target for PhysicalTarget {
|
||||
|
||||
impl Drop for PhysicalTarget {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.port.set_dtr(true);
|
||||
self.port.set_dtr(true).unwrap();
|
||||
self.port.set_rts(true).unwrap();
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
self.port.set_dtr(false).unwrap();
|
||||
self.port.set_rts(false).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user