1use std::rc::Rc;
2use std::cell::RefCell;
3use std::num::ParseIntError;
4
5use clap::Parser;
6
7use jtag_taps::cable;
8use jtag_taps::statemachine::JtagSM;
9use jtag_taps::taps::Taps;
10
11use jtag_adi::{ArmDebugInterface, MemAP};
12
13#[derive(Parser, Debug)]
14#[command(author, version, about, long_about = None)]
15struct Args {
16 #[arg(short, long)]
17 cable: String,
18 #[arg(short, long)]
19 baud: u32,
20 #[arg(short, long, default_value_t = 0)]
21 tap_index: usize,
23 #[arg(short, long, default_value_t = 0)]
24 ap_num: u32,
26 addr: String,
27 #[arg(long)]
28 write: Option<String>,
29}
30
31fn parse_int(x: &str) -> Result<u32, ParseIntError> {
32 if x.starts_with("0x") {
33 let len = x.len();
34 u32::from_str_radix(&x[2..len], 16)
35 } else {
36 str::parse(&x)
37 }
38}
39
40fn main() {
41 let args = Args::parse();
42 let cable = cable::new_from_string(&args.cable, args.baud).expect("cable");
43 let jtag = JtagSM::new(cable);
44 let mut taps = Taps::new(jtag);
45 taps.detect();
46
47 let ir = vec![14];
49 taps.select_tap(args.tap_index, &ir);
50 let dr = taps.read_dr(32);
51 let idcode = u32::from_le_bytes(dr.try_into().unwrap());
52
53 if idcode != 0x4ba00477 {
55 eprintln!("Warning: unexpected idcode {:x}", idcode);
56 }
57
58 let adi = Rc::new(RefCell::new(ArmDebugInterface::new(taps)));
59 let mut mem = MemAP::new(adi.clone(), args.ap_num);
60
61 let addr = parse_int(&args.addr).expect("failed to parse address");
62
63 if let Some(value) = args.write {
64 let value = parse_int(&value).expect("failed to parse value");
65 mem.write(addr, value).expect("write");
66 println!("Success");
67 } else {
68 let val = mem.read(addr).expect("read");
69 println!("0x{:x} = 0x{:x}", addr, val);
70 }
71}