1pub mod command;
7pub mod config;
8
9mod gpio;
10mod i2c;
11mod spi;
12
13use crate::debug::openocd::OpenOcdJtagChain;
14use crate::io::emu::Emulator;
15use crate::io::gpio::{GpioBitbanging, GpioMonitoring, GpioPin, PinMode, PullMode};
16use crate::io::i2c::Bus;
17use crate::io::ioexpander::IoExpander;
18use crate::io::jtag::{JtagChain, JtagParams};
19use crate::io::spi::{Target, TransferMode};
20use crate::io::uart::Uart;
21use crate::io::usb::UsbContext;
22use crate::transport::{
23 Capability, FpgaOps, ProgressIndicator, ProxyOps, Transport, TransportError,
24 TransportInterfaceType, ioexpander,
25};
26
27use anyhow::{Result, bail, ensure};
28use indicatif::{ProgressBar, ProgressStyle};
29use serialport::Parity;
30use std::any::Any;
31use std::cell::{Cell, RefCell};
32use std::collections::hash_map::Entry;
33use std::collections::{HashMap, HashSet};
34use std::path::PathBuf;
35use std::rc::Rc;
36use std::time::Duration;
37use std::vec::Vec;
38
39pub struct NoProgressBar;
40
41impl ProgressIndicator for NoProgressBar {
42 fn new_stage(&self, _name: &str, _total: usize) {}
43 fn progress(&self, _absolute: usize) {}
44}
45
46pub struct StagedProgressBar {
50 pub current_progress_bar: Rc<RefCell<Option<indicatif::ProgressBar>>>,
51}
52
53impl Default for StagedProgressBar {
54 fn default() -> Self {
55 Self::new()
56 }
57}
58
59impl StagedProgressBar {
60 const DEFAULT_TEMPLATE: &str = "[{elapsed_precise}] [{wide_bar}] {bytes}/{total_bytes} ({eta})";
61 const STAGE_TEMPLATE: &str =
62 "{msg}: [{elapsed_precise}] [{wide_bar}] {bytes}/{total_bytes} ({eta})";
63
64 pub fn new() -> Self {
65 Self {
66 current_progress_bar: Rc::new(RefCell::new(None)),
67 }
68 }
69
70 pub fn enable_steady_tick(&self, duration: Duration) {
71 let bar = self.current_progress_bar.borrow();
72 let bar = bar.as_ref().unwrap();
73 bar.enable_steady_tick(duration);
74 }
75
76 pub fn bytes_per_second(&self) -> f64 {
79 let bar = self.current_progress_bar.borrow();
80 let bar = bar.as_ref().unwrap();
81 bar.length().unwrap() as f64 / bar.elapsed().as_secs_f64()
82 }
83}
84
85impl ProgressIndicator for StagedProgressBar {
86 fn new_stage(&self, name: &str, total: usize) {
87 let progress = ProgressBar::new(total as u64);
88 if name.is_empty() {
89 progress.set_style(
90 ProgressStyle::default_bar()
91 .template(Self::DEFAULT_TEMPLATE)
92 .unwrap(),
93 );
94 } else {
95 progress.set_style(
96 ProgressStyle::default_bar()
97 .template(Self::STAGE_TEMPLATE)
98 .unwrap(),
99 );
100 }
101 self.current_progress_bar
102 .borrow_mut()
103 .replace(progress.with_message(name.to_string()));
104 }
105
106 fn progress(&self, pos: usize) {
107 let bar = self.current_progress_bar.borrow();
108 let bar = bar.as_ref().unwrap();
109 if pos as u64 == bar.length().unwrap() {
110 bar.finish();
111 return;
112 }
113 bar.set_position(pos as u64);
114 }
115}
116
117#[derive(Clone, Copy, Default, Debug)]
118pub struct PinConfiguration {
119 pub mode: Option<PinMode>,
121 pub level: Option<bool>,
124 pub pull_mode: Option<PullMode>,
126 pub volts: Option<f32>,
129 pub invert: Option<bool>,
130}
131
132fn merge_field<T>(f1: &mut Option<T>, f2: &Option<T>) -> Result<(), ()>
133where
134 T: PartialEq<T> + Clone,
135{
136 match (&*f1, f2) {
137 (Some(v1), Some(v2)) if *v1 != *v2 => return Err(()),
138 (None, _) => *f1 = f2.clone(),
139 _ => (),
140 }
141 Ok(())
142}
143
144impl PinConfiguration {
145 fn merge(&mut self, other: &PinConfiguration) -> Result<(), ()> {
150 merge_field(&mut self.mode, &other.mode)?;
151 merge_field(&mut self.level, &other.level)?;
152 merge_field(&mut self.pull_mode, &other.pull_mode)?;
153 merge_field(&mut self.volts, &other.volts)?;
154 merge_field(&mut self.invert, &other.invert)?;
155 Ok(())
156 }
157
158 #[must_use]
161 fn override_with(&self, overrides: Option<&Self>) -> Self {
162 let Some(overrides) = overrides else {
163 return *self;
164 };
165 let mut result = *self;
166 overrides.mode.map(|v| result.mode.replace(v));
167 overrides.level.map(|v| result.level.replace(v));
168 overrides.pull_mode.map(|v| result.pull_mode.replace(v));
169 overrides.volts.map(|v| result.volts.replace(v));
170 overrides.invert.map(|v| result.invert.replace(v));
171 result
172 }
173}
174
175#[derive(Default, Debug)]
176pub struct UartConfiguration {
177 pub underlying_instance: String,
178 pub baud_rate: Option<u32>,
179 pub parity: Option<config::UartParity>,
180 pub stop_bits: Option<config::UartStopBits>,
181 pub alias_of: Option<String>,
182}
183
184#[derive(Default, Debug)]
185pub struct SpiConfiguration {
186 pub underlying_instance: String,
187 pub mode: Option<TransferMode>,
188 pub serial_clock: Option<String>,
189 pub host_out_device_in: Option<String>,
190 pub host_in_device_out: Option<String>,
191 pub chip_select: Option<String>,
192 pub gsc_ready: Option<String>,
193 pub bits_per_word: Option<u32>,
194 pub bits_per_sec: Option<u32>,
195}
196
197#[derive(Default, Debug)]
198pub struct I2cConfiguration {
199 pub underlying_instance: String,
200 pub default_addr: Option<u8>,
201 pub bits_per_sec: Option<u32>,
202}
203
204pub struct TransportWrapperBuilder {
205 interface: String,
206 disable_dft_on_reset: bool,
207 reset_delay: Duration,
208 openocd_adapter_config: Option<PathBuf>,
209 provides_list: Vec<(String, String)>,
210 requires_list: Vec<(String, String)>,
211 pin_alias_map: HashMap<String, String>,
212 pin_on_io_expander_map: HashMap<String, config::IoExpanderPin>,
213 pin_conf_list: Vec<(String, PinConfiguration)>,
214 uart_conf_map: HashMap<String, config::UartConfiguration>,
215 spi_conf_map: HashMap<String, config::SpiConfiguration>,
216 i2c_conf_map: HashMap<String, config::I2cConfiguration>,
217 strapping_conf_map: HashMap<String, Vec<(String, PinConfiguration)>>,
218 io_expander_conf_map: HashMap<String, config::IoExpander>,
219 gpio_conf: HashSet<String>,
220 clock_freq_conf: HashMap<String, u64>,
221}
222
223pub struct TransportWrapper {
227 transport: Rc<dyn Transport>,
228 disable_dft_on_reset: Cell<bool>,
229 reset_delay: Cell<Duration>,
230 openocd_adapter_config: Option<PathBuf>,
231 provides_map: HashMap<String, String>,
232 pin_map: HashMap<String, String>,
233 artificial_pin_map: HashMap<String, Rc<dyn GpioPin>>,
234 pin_conf_map: HashMap<String, PinConfiguration>,
235 uart_conf_map: HashMap<String, UartConfiguration>,
236 spi_conf_map: HashMap<String, SpiConfiguration>,
237 i2c_conf_map: HashMap<String, I2cConfiguration>,
238 strapping_conf_map: HashMap<String, HashMap<String, PinConfiguration>>,
239 gpio_conf: HashSet<String>,
240 clock_freq_conf: HashMap<String, u64>,
241 pin_instance_map: RefCell<HashMap<String, Rc<gpio::GpioPinWrapper>>>,
250 spi_physical_map: RefCell<HashMap<String, Rc<spi::PhysicalSpiWrapper>>>,
251 spi_logical_map: RefCell<HashMap<String, Rc<spi::LogicalSpiWrapper>>>,
252 i2c_physical_map: RefCell<HashMap<String, Rc<i2c::PhysicalI2cWrapper>>>,
253 i2c_logical_map: RefCell<HashMap<String, Rc<i2c::LogicalI2cWrapper>>>,
254}
255
256impl TransportWrapperBuilder {
257 pub fn new(interface: String, disable_dft_on_reset: bool) -> Self {
258 Self {
259 interface,
260 disable_dft_on_reset,
261 reset_delay: Duration::from_millis(100),
262 openocd_adapter_config: None,
263 provides_list: Vec::new(),
264 requires_list: Vec::new(),
265 pin_alias_map: HashMap::new(),
266 pin_on_io_expander_map: HashMap::new(),
267 pin_conf_list: Vec::new(),
268 uart_conf_map: HashMap::new(),
269 spi_conf_map: HashMap::new(),
270 i2c_conf_map: HashMap::new(),
271 strapping_conf_map: HashMap::new(),
272 io_expander_conf_map: HashMap::new(),
273 gpio_conf: HashSet::new(),
274 clock_freq_conf: HashMap::new(),
275 }
276 }
277
278 fn record_pin_conf(
279 pin_conf_list: &mut Vec<(String, PinConfiguration)>,
280 pin_conf: &config::PinConfiguration,
281 ) {
282 if (None, None, None, None, None)
283 == (
284 pin_conf.mode,
285 pin_conf.pull_mode,
286 pin_conf.level,
287 pin_conf.volts,
288 pin_conf.invert,
289 )
290 {
291 return;
292 }
293 let mut conf_entry: PinConfiguration = PinConfiguration::default();
294 if let Some(pin_mode) = pin_conf.mode {
295 conf_entry.mode = Some(pin_mode);
296 }
297 if let Some(pull_mode) = pin_conf.pull_mode {
298 conf_entry.pull_mode = Some(pull_mode);
299 }
300 if let Some(level) = pin_conf.level {
301 conf_entry.level = Some(level);
302 }
303 if let Some(volts) = pin_conf.volts {
304 conf_entry.volts = Some(volts);
305 }
306 if let Some(invert) = pin_conf.invert {
307 conf_entry.invert = Some(invert);
308 }
309 pin_conf_list.push((pin_conf.name.to_string(), conf_entry))
310 }
311
312 fn record_uart_conf(
313 uart_conf_map: &mut HashMap<String, config::UartConfiguration>,
314 uart_conf: &config::UartConfiguration,
315 ) -> Result<(), ()> {
316 let entry = uart_conf_map
317 .entry(uart_conf.name.to_uppercase().to_string())
318 .or_insert_with(|| config::UartConfiguration {
319 name: uart_conf.name.clone(),
320 ..Default::default()
321 });
322 merge_field(&mut entry.baudrate, &uart_conf.baudrate)?;
323 merge_field(&mut entry.parity, &uart_conf.parity)?;
324 merge_field(&mut entry.stopbits, &uart_conf.stopbits)?;
325 merge_field(&mut entry.alias_of, &uart_conf.alias_of)?;
326 Ok(())
327 }
328
329 fn record_spi_conf(
330 spi_conf_map: &mut HashMap<String, config::SpiConfiguration>,
331 spi_conf: &config::SpiConfiguration,
332 ) -> Result<(), ()> {
333 let entry = spi_conf_map
334 .entry(spi_conf.name.to_string())
335 .or_insert_with(|| config::SpiConfiguration {
336 name: spi_conf.name.clone(),
337 ..Default::default()
338 });
339 merge_field(&mut entry.mode, &spi_conf.mode)?;
340 merge_field(&mut entry.bits_per_word, &spi_conf.bits_per_word)?;
341 merge_field(&mut entry.bits_per_sec, &spi_conf.bits_per_sec)?;
342 merge_field(&mut entry.serial_clock, &spi_conf.serial_clock)?;
343 merge_field(&mut entry.host_out_device_in, &spi_conf.host_out_device_in)?;
344 merge_field(&mut entry.host_in_device_out, &spi_conf.host_in_device_out)?;
345 merge_field(&mut entry.chip_select, &spi_conf.chip_select)?;
346 merge_field(&mut entry.alias_of, &spi_conf.alias_of)?;
347 Ok(())
348 }
349
350 fn record_i2c_conf(
351 i2c_conf_map: &mut HashMap<String, config::I2cConfiguration>,
352 i2c_conf: &config::I2cConfiguration,
353 ) -> Result<(), ()> {
354 let entry = i2c_conf_map
355 .entry(i2c_conf.name.to_string())
356 .or_insert_with(|| config::I2cConfiguration {
357 name: i2c_conf.name.clone(),
358 ..Default::default()
359 });
360 merge_field(&mut entry.address, &i2c_conf.address)?;
361 merge_field(&mut entry.bits_per_sec, &i2c_conf.bits_per_sec)?;
362 merge_field(&mut entry.alias_of, &i2c_conf.alias_of)?;
363 Ok(())
364 }
365
366 fn record_clock_freq_conf(
367 clock_freq_conf: &mut HashMap<String, u64>,
368 clock_domain: &str,
369 clock_frequency: u64,
370 ) -> Result<(), ()> {
371 let mut entry = clock_freq_conf.get(clock_domain).copied();
372 merge_field(&mut entry, &Some(clock_frequency))?;
373 if let Some(e) = entry {
374 clock_freq_conf.insert(clock_domain.to_owned(), e);
375 }
376 Ok(())
377 }
378
379 pub fn add_configuration_file(&mut self, file: config::ConfigurationFile) -> Result<()> {
380 if let Some(interface) = file.interface {
381 if self.interface.is_empty() {
382 self.interface = interface;
383 } else if self.interface == interface {
384 } else {
387 bail!(TransportError::InconsistentInterfaceConf(
388 self.interface.to_string(),
389 interface,
390 ))
391 }
392 }
393 for (key, value) in file.provides {
394 self.provides_list.push((key, value));
395 }
396 for (key, value) in file.requires {
397 self.requires_list.push((key, value));
398 }
399
400 if let Some(reset_delay) = file.reset_delay {
401 self.reset_delay = reset_delay;
402 }
403
404 for pin_conf in file.pins {
406 if let Some(alias_of) = &pin_conf.alias_of {
407 self.pin_alias_map
408 .insert(pin_conf.name.to_uppercase(), alias_of.clone());
409 } else if let Some(on_io_expander) = &pin_conf.on_io_expander {
410 ensure!(
411 &pin_conf.alias_of.is_none(),
412 TransportError::InconsistentConf(
413 TransportInterfaceType::Gpio,
414 pin_conf.name.to_string()
415 )
416 );
417 let uppercase_name = pin_conf.name.to_uppercase();
418 ensure!(
419 !self.pin_on_io_expander_map.contains_key(&uppercase_name),
420 TransportError::InconsistentConf(
421 TransportInterfaceType::Gpio,
422 pin_conf.name.to_string()
423 )
424 );
425 self.pin_on_io_expander_map
426 .insert(uppercase_name, on_io_expander.clone());
427 }
428 Self::record_pin_conf(&mut self.pin_conf_list, &pin_conf);
430 }
431 for strapping_conf in file.strappings {
432 let strapping_pin_map = self
433 .strapping_conf_map
434 .entry(strapping_conf.name.to_uppercase())
435 .or_default();
436 for pin_conf in strapping_conf.pins {
437 ensure!(
438 pin_conf.invert.is_none(),
439 TransportError::InvalidConfStrapInvert(
440 strapping_conf.name.to_string(),
441 pin_conf.name.to_string()
442 )
443 );
444 ensure!(
445 pin_conf.alias_of.is_none(),
446 TransportError::InvalidConfStrapAlias(
447 strapping_conf.name.to_string(),
448 pin_conf.name.to_string()
449 )
450 );
451 Self::record_pin_conf(strapping_pin_map, &pin_conf);
452 }
453 }
454 for spi_conf in file.spi {
455 Self::record_spi_conf(&mut self.spi_conf_map, &spi_conf).map_err(|_| {
456 TransportError::InconsistentConf(
457 TransportInterfaceType::Spi,
458 spi_conf.name.to_string(),
459 )
460 })?;
461 }
462 for i2c_conf in file.i2c {
463 Self::record_i2c_conf(&mut self.i2c_conf_map, &i2c_conf).map_err(|_| {
464 TransportError::InconsistentConf(
465 TransportInterfaceType::I2c,
466 i2c_conf.name.to_string(),
467 )
468 })?;
469 }
470 for uart_conf in file.uarts {
471 Self::record_uart_conf(&mut self.uart_conf_map, &uart_conf).map_err(|_| {
472 TransportError::InconsistentConf(
473 TransportInterfaceType::Uart,
474 uart_conf.name.to_string(),
475 )
476 })?;
477 }
478 for io_expander_conf in file.io_expanders {
479 match self
480 .io_expander_conf_map
481 .entry(io_expander_conf.name.to_string())
482 {
483 Entry::Vacant(v) => {
484 v.insert(io_expander_conf);
485 }
486 Entry::Occupied(_) => bail!(TransportError::InconsistentConf(
487 TransportInterfaceType::IoExpander,
488 io_expander_conf.name
489 )),
490 }
491 }
492 for pin in file.gpios {
493 self.gpio_conf.insert(pin);
494 }
495 for (domain, frequency) in file.clock_freqs {
496 Self::record_clock_freq_conf(&mut self.clock_freq_conf, &domain, frequency).map_err(
497 |_| TransportError::InconsistentConf(TransportInterfaceType::ClockFreq, domain),
498 )?;
499 }
500 Ok(())
501 }
502
503 fn consolidate_provides_map(
504 result_provides_map: &mut HashMap<String, String>,
505 provides_list: Vec<(String, String)>,
506 ) -> Result<()> {
507 for (key, value) in provides_list {
508 match result_provides_map.entry(key.clone()) {
509 Entry::Vacant(v) => {
510 v.insert(value);
511 }
512 Entry::Occupied(v) => {
513 if v.get() != &value {
514 bail!(TransportError::InconsistentConf(
515 TransportInterfaceType::Provides,
516 key
517 ))
518 }
519 }
520 }
521 }
522 Ok(())
523 }
524
525 fn verify_requires_list(
526 provides_map: &HashMap<String, String>,
527 requires_list: &Vec<(String, String)>,
528 ) -> Result<()> {
529 for (key, required_value) in requires_list {
530 match provides_map.get(key) {
531 Some(actual_value) if actual_value == required_value => (),
532 Some(actual_value) => bail!(TransportError::RequiresUnequal(
533 key.to_string(),
534 required_value.to_string(),
535 actual_value.to_string()
536 )),
537 None => bail!(TransportError::RequiresMissing(
538 key.to_string(),
539 required_value.to_string()
540 )),
541 }
542 }
543 Ok(())
544 }
545
546 fn consolidate_pin_conf_map(
547 pin_alias_map: &HashMap<String, String>,
548 pin_conf_list: &Vec<(String, PinConfiguration)>,
549 ) -> Result<HashMap<String, PinConfiguration>> {
550 let mut result_pin_conf_map: HashMap<String, PinConfiguration> = HashMap::new();
551 for (name, conf) in pin_conf_list {
552 result_pin_conf_map
553 .entry(map_name(pin_alias_map, name))
554 .or_default()
555 .merge(conf)
556 .map_err(|_| {
557 TransportError::InconsistentConf(TransportInterfaceType::Gpio, name.to_string())
558 })?;
559 }
560 Ok(result_pin_conf_map)
561 }
562
563 fn resolve_uart_conf(
564 name: &str,
565 uart_conf_map: &HashMap<String, config::UartConfiguration>,
566 ) -> Result<UartConfiguration> {
567 if let Some(entry) = uart_conf_map.get(name.to_uppercase().as_str()) {
568 let mut conf = if let Some(ref alias_of) = entry.alias_of {
569 Self::resolve_uart_conf(alias_of.as_str(), uart_conf_map)?
570 } else {
571 UartConfiguration {
572 underlying_instance: name.to_uppercase().to_string(),
573 ..Default::default()
574 }
575 };
576 if let Some(baud_rate) = entry.baudrate {
578 conf.baud_rate = Some(baud_rate);
579 }
580 if let Some(parity) = entry.parity {
581 conf.parity = Some(parity);
582 }
583 if let Some(stop_bits) = entry.stopbits {
584 conf.stop_bits = Some(stop_bits);
585 }
586 Ok(conf)
587 } else {
588 Ok(UartConfiguration {
589 underlying_instance: name.to_string(),
590 ..Default::default()
591 })
592 }
593 }
594
595 fn consolidate_uart_conf_map(
596 uart_conf_map: &HashMap<String, config::UartConfiguration>,
597 ) -> Result<HashMap<String, UartConfiguration>> {
598 let mut resolved_uart_conf_map = HashMap::new();
599 for name in uart_conf_map.keys() {
600 resolved_uart_conf_map
601 .insert(name.clone(), Self::resolve_uart_conf(name, uart_conf_map)?);
602 }
603 Ok(resolved_uart_conf_map)
604 }
605
606 fn resolve_spi_conf(
607 name: &str,
608 spi_conf_map: &HashMap<String, config::SpiConfiguration>,
609 pin_alias_map: &HashMap<String, String>,
610 ) -> SpiConfiguration {
611 if let Some(entry) = spi_conf_map.get(name) {
612 let mut conf = if let Some(ref alias_of) = entry.alias_of {
613 Self::resolve_spi_conf(alias_of.as_str(), spi_conf_map, pin_alias_map)
614 } else {
615 SpiConfiguration {
616 underlying_instance: name.to_string(),
617 ..Default::default()
618 }
619 };
620 if let Some(serial_clock) = entry.serial_clock.as_ref() {
622 conf.serial_clock = Some(map_name(pin_alias_map, serial_clock));
623 }
624 if let Some(host_out_device_in) = entry.host_out_device_in.as_ref() {
625 conf.host_out_device_in = Some(map_name(pin_alias_map, host_out_device_in));
626 }
627 if let Some(host_in_device_out) = entry.host_in_device_out.as_ref() {
628 conf.host_in_device_out = Some(map_name(pin_alias_map, host_in_device_out));
629 }
630 if let Some(chip_select) = entry.chip_select.as_ref() {
631 conf.chip_select = Some(map_name(pin_alias_map, chip_select));
632 }
633 if let Some(mode) = entry.mode {
634 conf.mode = Some(mode);
635 }
636 if let Some(bits_per_sec) = entry.bits_per_sec {
637 conf.bits_per_sec = Some(bits_per_sec);
638 }
639 if let Some(bits_per_word) = entry.bits_per_word {
640 conf.bits_per_word = Some(bits_per_word);
641 }
642 conf
643 } else {
644 SpiConfiguration {
645 underlying_instance: name.to_string(),
646 ..Default::default()
647 }
648 }
649 }
650
651 fn consolidate_spi_conf_map(
652 spi_conf_map: &HashMap<String, config::SpiConfiguration>,
653 pin_alias_map: &HashMap<String, String>,
654 ) -> Result<HashMap<String, SpiConfiguration>> {
655 let mut resolved_spi_conf_map = HashMap::new();
656 for name in spi_conf_map.keys() {
657 resolved_spi_conf_map.insert(
658 name.clone(),
659 Self::resolve_spi_conf(name, spi_conf_map, pin_alias_map),
660 );
661 }
662 Ok(resolved_spi_conf_map)
663 }
664
665 fn resolve_i2c_conf(
666 name: &str,
667 i2c_conf_map: &HashMap<String, config::I2cConfiguration>,
668 ) -> I2cConfiguration {
669 if let Some(entry) = i2c_conf_map.get(name) {
670 let mut conf = if let Some(ref alias_of) = entry.alias_of {
671 Self::resolve_i2c_conf(alias_of.as_str(), i2c_conf_map)
672 } else {
673 I2cConfiguration {
674 underlying_instance: name.to_string(),
675 ..Default::default()
676 }
677 };
678 if let Some(addr) = entry.address {
680 conf.default_addr = Some(addr);
681 }
682 if let Some(bits_per_sec) = entry.bits_per_sec {
683 conf.bits_per_sec = Some(bits_per_sec);
684 }
685 conf
686 } else {
687 I2cConfiguration {
688 underlying_instance: name.to_string(),
689 ..Default::default()
690 }
691 }
692 }
693
694 fn consolidate_i2c_conf_map(
695 i2c_conf_map: &HashMap<String, config::I2cConfiguration>,
696 ) -> Result<HashMap<String, I2cConfiguration>> {
697 let mut resolved_i2c_conf_map = HashMap::new();
698 for name in i2c_conf_map.keys() {
699 resolved_i2c_conf_map.insert(name.clone(), Self::resolve_i2c_conf(name, i2c_conf_map));
700 }
701 Ok(resolved_i2c_conf_map)
702 }
703
704 pub fn get_interface(&self) -> &str {
705 &self.interface
706 }
707
708 pub fn set_openocd_adapter_config(&mut self, openocd_adapter_config: &Option<PathBuf>) {
709 self.openocd_adapter_config = openocd_adapter_config.clone();
710 }
711
712 pub fn build(
713 self,
714 transport: Box<dyn crate::transport::Transport>,
715 ) -> Result<TransportWrapper> {
716 let mut provides_map = if transport
717 .capabilities()?
718 .request(Capability::PROXY)
719 .ok()
720 .is_ok()
721 {
722 transport.proxy_ops()?.provides_map()?
723 } else {
724 HashMap::new()
725 };
726 Self::consolidate_provides_map(&mut provides_map, self.provides_list)?;
727 Self::verify_requires_list(&provides_map, &self.requires_list)?;
728
729 let pin_conf_map =
730 Self::consolidate_pin_conf_map(&self.pin_alias_map, &self.pin_conf_list)?;
731 let mut strapping_conf_map: HashMap<String, HashMap<String, PinConfiguration>> =
732 HashMap::new();
733 for (strapping_name, pin_conf_map) in self.strapping_conf_map {
734 strapping_conf_map.insert(
735 strapping_name,
736 Self::consolidate_pin_conf_map(&self.pin_alias_map, &pin_conf_map)?,
737 );
738 }
739 let uart_conf_map = Self::consolidate_uart_conf_map(&self.uart_conf_map)?;
740 let spi_conf_map = Self::consolidate_spi_conf_map(&self.spi_conf_map, &self.pin_alias_map)?;
741 let i2c_conf_map = Self::consolidate_i2c_conf_map(&self.i2c_conf_map)?;
742 let mut transport_wrapper = TransportWrapper {
743 transport: Rc::from(transport),
744 disable_dft_on_reset: Cell::new(self.disable_dft_on_reset),
745 reset_delay: Cell::new(self.reset_delay),
746 openocd_adapter_config: self.openocd_adapter_config,
747 provides_map,
748 pin_map: self.pin_alias_map,
749 artificial_pin_map: HashMap::new(),
750 uart_conf_map,
751 pin_conf_map,
752 spi_conf_map,
753 i2c_conf_map,
754 strapping_conf_map,
755 gpio_conf: self.gpio_conf,
756 clock_freq_conf: self.clock_freq_conf,
757 pin_instance_map: RefCell::new(HashMap::new()),
758 spi_physical_map: RefCell::new(HashMap::new()),
759 spi_logical_map: RefCell::new(HashMap::new()),
760 i2c_physical_map: RefCell::new(HashMap::new()),
761 i2c_logical_map: RefCell::new(HashMap::new()),
762 };
763 let mut io_expanders: HashMap<String, IoExpander> = HashMap::new();
764 for (name, conf) in self.io_expander_conf_map {
765 io_expanders.insert(
766 name.to_string(),
767 ioexpander::create(&conf, &transport_wrapper)?,
768 );
769 }
770 transport_wrapper
771 .artificial_pin_map
772 .insert("NULL".to_string(), Rc::new(NullPin::new()));
773 for (pinname, v) in self.pin_on_io_expander_map {
774 if let Some(io) = io_expanders.get(&v.io_expander) {
775 ensure!(
776 (v.pin_no as usize) < io.pins.len(),
777 TransportError::InvalidIoExpanderPinNo(v.io_expander.to_string(), v.pin_no)
778 );
779 transport_wrapper
780 .artificial_pin_map
781 .insert(pinname, io.pins[v.pin_no as usize].clone());
782 } else {
783 bail!(TransportError::InvalidIoExpanderName(
784 v.io_expander.to_string()
785 ));
786 }
787 }
788 Ok(transport_wrapper)
789 }
790}
791
792impl TransportWrapper {
793 pub fn ignore_dft_straps_on_reset(&self) -> Result<()> {
794 self.disable_dft_on_reset.set(false);
795 Ok(())
796 }
797
798 pub fn capabilities(&self) -> Result<crate::transport::Capabilities> {
801 let capabilities = self.transport.capabilities()?;
802 if self.openocd_adapter_config.is_some() {
803 Ok(capabilities.add(Capability::JTAG))
804 } else {
805 Ok(capabilities)
806 }
807 }
808
809 pub fn provides_map(&self) -> Result<&HashMap<String, String>> {
813 Ok(&self.provides_map)
814 }
815
816 pub fn query_provides(&self, key: &str) -> Result<&str> {
817 self.provides_map
818 .get(key)
819 .map(String::as_str)
820 .ok_or_else(|| {
821 TransportError::InvalidInstance(TransportInterfaceType::Provides, key.to_string())
822 .into()
823 })
824 }
825
826 pub fn jtag(&self, opts: &JtagParams) -> Result<Box<dyn JtagChain + '_>> {
828 if let Some(ref path) = self.openocd_adapter_config {
829 return Ok(Box::new(OpenOcdJtagChain::new(
831 &std::fs::read_to_string(path)?,
832 opts,
833 )?));
834 }
835 self.transport.jtag(opts)
838 }
839
840 pub fn spi(&self, name: &str) -> Result<Rc<dyn Target>> {
842 let name = name.to_uppercase();
843 let mut spi_logical_map = self.spi_logical_map.borrow_mut();
844 if let Some(instance) = spi_logical_map.get(&name) {
845 return Ok(instance.clone());
846 }
847 if let Some(spi_conf) = self.spi_conf_map.get(&name) {
848 let mut spi_physical_map = self.spi_physical_map.borrow_mut();
849 let physical_wrapper =
852 if let Some(instance) = spi_physical_map.get(&spi_conf.underlying_instance) {
853 instance.clone()
854 } else {
855 let instance = Rc::new(spi::PhysicalSpiWrapper::new(
856 self.transport.spi(spi_conf.underlying_instance.as_str())?,
857 ));
858 spi_physical_map.insert(spi_conf.underlying_instance.clone(), instance.clone());
859 instance
860 };
861
862 let new_wrapper = Rc::new(spi::LogicalSpiWrapper::new(
865 &*self.transport,
866 spi_conf,
867 physical_wrapper,
868 )?);
869 spi_logical_map.insert(name, new_wrapper.clone());
870 Ok(new_wrapper)
871 } else {
872 self.transport.spi(name.as_str())
873 }
874 }
875
876 pub fn i2c(&self, name: &str) -> Result<Rc<dyn Bus>> {
878 let name = name.to_uppercase();
879 let mut i2c_logical_map = self.i2c_logical_map.borrow_mut();
880 if let Some(instance) = i2c_logical_map.get(&name) {
881 return Ok(instance.clone());
882 }
883 if let Some(i2c_conf) = self.i2c_conf_map.get(&name) {
884 let mut i2c_physical_map = self.i2c_physical_map.borrow_mut();
885 let physical_wrapper =
888 if let Some(instance) = i2c_physical_map.get(&i2c_conf.underlying_instance) {
889 instance.clone()
890 } else {
891 let instance = Rc::new(i2c::PhysicalI2cWrapper::new(
892 self.transport.i2c(i2c_conf.underlying_instance.as_str())?,
893 ));
894 i2c_physical_map.insert(i2c_conf.underlying_instance.clone(), instance.clone());
895 instance
896 };
897
898 let new_wrapper = Rc::new(i2c::LogicalI2cWrapper::new(
901 &*self.transport,
902 i2c_conf,
903 physical_wrapper,
904 )?);
905 i2c_logical_map.insert(name, new_wrapper.clone());
906 Ok(new_wrapper)
907 } else {
908 self.transport.i2c(name.as_str())
909 }
910 }
911
912 pub fn uart(&self, name: &str) -> Result<Rc<dyn Uart>> {
914 let uart_conf = self.uart_conf_map.get(name.to_uppercase().as_str());
915 let uart_name = uart_conf
916 .map(|uart_conf| uart_conf.underlying_instance.as_str())
917 .unwrap_or(name);
918 let uart = self.transport.uart(uart_name)?;
919 if let Some(conf) = uart_conf {
920 if let Some(baud_rate) = conf.baud_rate {
924 if let Ok(current_baud_rate) = uart.get_baudrate() {
925 if current_baud_rate != baud_rate {
926 uart.set_baudrate(baud_rate)?;
927 }
928 } else {
929 log::warn!("Could not read UART baud rate to check it is {}", baud_rate);
930 }
931 }
932 if let Some(parity) = conf.parity {
933 let new_parity = match parity {
934 config::UartParity::None => Parity::None,
935 config::UartParity::Even => Parity::Even,
936 config::UartParity::Odd => Parity::Odd,
937 config::UartParity::Mark | config::UartParity::Space => {
938 log::warn!("Mark & Space parities not yet supported");
939 Parity::None
940 }
941 };
942 if let Ok(current_parity) = uart.get_parity() {
943 if current_parity != new_parity {
944 uart.set_parity(new_parity)?;
945 }
946 } else {
947 log::warn!("Could not read UART parity to check it is {}", new_parity);
948 }
949 }
950 }
952 Ok(uart)
953 }
954
955 pub fn usb(&self) -> Result<Rc<dyn UsbContext>> {
957 self.transport.usb()
958 }
959
960 pub fn gpio_pin(&self, name: &str) -> Result<Rc<dyn GpioPin>> {
962 let resolved_pin_name = map_name(&self.pin_map, name);
963 let mut pin_instance_map = self.pin_instance_map.borrow_mut();
964 if let Some(instance) = pin_instance_map.get(&resolved_pin_name) {
967 Ok(instance.clone())
968 } else {
969 let instance = if let Some(pin) = self.artificial_pin_map.get(&resolved_pin_name) {
970 pin.clone()
971 } else {
972 self.transport.gpio_pin(resolved_pin_name.as_str())?
973 };
974 let invert = self
975 .pin_conf_map
976 .get(&resolved_pin_name)
977 .and_then(|conf| conf.invert)
978 .unwrap_or(false);
979 let wrapper = Rc::new(gpio::GpioPinWrapper::new(instance, invert));
980 pin_instance_map.insert(resolved_pin_name, wrapper.clone());
981 Ok(wrapper)
982 }
983 }
984
985 pub fn gpio_pins(&self, names: &[String]) -> Result<Vec<Rc<dyn GpioPin>>> {
987 let mut result = Vec::new();
988 for name in names {
989 result.push(self.gpio_pin(name)?);
990 }
991 Ok(result)
992 }
993
994 pub fn gpios(&self) -> &HashSet<String> {
995 &self.gpio_conf
996 }
997
998 pub fn gpio_monitoring(&self) -> Result<Rc<dyn GpioMonitoring>> {
1000 self.transport.gpio_monitoring()
1001 }
1002
1003 pub fn gpio_bitbanging(&self) -> Result<Rc<dyn GpioBitbanging>> {
1005 self.transport.gpio_bitbanging()
1006 }
1007
1008 pub fn clock_frequency(&self, domain: &str) -> Option<u64> {
1010 self.clock_freq_conf.get(domain).copied()
1011 }
1012
1013 pub fn optional_pin_strapping(&self, name: &str) -> Result<Option<PinStrapping>> {
1016 self.build_pin_strapping(name, true)
1017 }
1018
1019 pub fn pin_strapping(&self, name: &str) -> Result<PinStrapping> {
1020 self.build_pin_strapping(name, false)?
1021 .ok_or_else(|| TransportError::InvalidStrappingName(name.to_string()).into())
1022 }
1023
1024 fn build_pin_strapping(&self, name: &str, optional: bool) -> Result<Option<PinStrapping>> {
1028 let proxy = if self.capabilities()?.request(Capability::PROXY).ok().is_ok() {
1029 Some(self.transport.clone())
1030 } else {
1031 None
1032 };
1033 let mut pins = Vec::new();
1034 if let Some(strapping_conf_map) = self.strapping_conf_map.get(name) {
1035 for (pin_name, conf) in strapping_conf_map {
1036 pins.push(StrappedPin {
1037 pin: self.gpio_pin(pin_name)?,
1038 strapped: *conf,
1039 original: self.pin_conf_map.get(pin_name).copied(),
1040 });
1041 }
1042 } else if proxy.is_none() {
1043 return Ok(None);
1044 }
1045 Ok(Some(PinStrapping {
1046 proxy,
1047 name: name.to_string(),
1048 pins,
1049 optional,
1050 }))
1051 }
1052
1053 pub fn emulator(&self) -> Result<&dyn Emulator> {
1055 self.transport.emulator()
1056 }
1057
1058 pub fn fpga_ops(&self) -> Result<&dyn FpgaOps> {
1060 self.transport.fpga_ops()
1061 }
1062
1063 pub fn proxy_ops(&self) -> Result<&dyn ProxyOps> {
1065 self.transport.proxy_ops()
1066 }
1067
1068 pub fn dispatch(&self, action: &dyn Any) -> Result<Option<Box<dyn erased_serde::Serialize>>> {
1070 self.transport.dispatch(action)
1071 }
1072
1073 fn apply_pin_configuration(&self, name: &str, conf: &PinConfiguration) -> Result<()> {
1075 let pin = self.gpio_pin(name)?;
1076 pin.set(conf.mode, conf.level, conf.pull_mode, conf.volts)
1077 }
1078
1079 fn apply_pin_configurations(
1081 &self,
1082 conf_map: &HashMap<String, PinConfiguration>,
1083 overrides: Option<&HashMap<String, PinConfiguration>>,
1084 ) -> Result<()> {
1085 let update_pin = |name, conf: &PinConfiguration| {
1087 self.apply_pin_configuration(
1088 name,
1089 &conf.override_with(overrides.and_then(|o| o.get(name))),
1090 )
1091 };
1092 for (name, conf) in conf_map {
1099 if !self.artificial_pin_map.contains_key(name) {
1100 update_pin(name, conf)?;
1101 }
1102 }
1103 for (name, conf) in conf_map {
1104 if self.artificial_pin_map.contains_key(name) {
1105 update_pin(name, conf)?;
1106 }
1107 }
1108 Ok(())
1109 }
1110
1111 pub fn apply_default_configuration(&self, strapping_name: Option<&str>) -> Result<()> {
1114 if let Some(strapping_name) = strapping_name {
1115 if self.capabilities()?.request(Capability::PROXY).ok().is_ok() {
1116 self.proxy_ops()?
1117 .apply_default_configuration_with_strap(strapping_name)?;
1118 } else if let Some(strapping_conf_map) = self.strapping_conf_map.get(strapping_name) {
1119 self.transport.apply_default_configuration()?;
1121 self.apply_pin_configurations(&self.pin_conf_map, Some(strapping_conf_map))?;
1126 } else {
1127 bail!(TransportError::InvalidStrappingName(
1128 strapping_name.to_string(),
1129 ));
1130 }
1131 } else {
1132 self.transport.apply_default_configuration()?;
1133 self.apply_pin_configurations(&self.pin_conf_map, None)?;
1134 }
1135 self.pin_instance_map.borrow_mut().clear();
1138 self.spi_physical_map.borrow_mut().clear();
1139 self.spi_logical_map.borrow_mut().clear();
1140 self.i2c_physical_map.borrow_mut().clear();
1141 self.i2c_logical_map.borrow_mut().clear();
1142 Ok(())
1143 }
1144
1145 #[deprecated = "use [`reset`] or [`reset_with_delay`]"]
1146 pub fn reset_target(&self, reset_delay: Duration, clear_uart_rx: bool) -> Result<()> {
1147 let uart_rx = match clear_uart_rx {
1148 true => UartRx::Clear,
1149 false => UartRx::Keep,
1150 };
1151 self.reset_with_delay(uart_rx, reset_delay)
1152 }
1153
1154 pub fn reset(&self, uart_rx: UartRx) -> Result<()> {
1156 self.reset_with_delay(uart_rx, self.reset_delay.get())
1157 }
1158
1159 pub fn reset_with_delay(&self, uart_rx: UartRx, delay: Duration) -> Result<()> {
1161 log::info!("Asserting the reset signal");
1162
1163 if self.disable_dft_on_reset.get() {
1164 self.pin_strapping("PRERESET_DFT_DISABLE")?.apply()?;
1165 }
1166
1167 let trst = self.optional_pin_strapping("TRST")?;
1171 if let Some(trst) = &trst {
1172 log::info!("Asserting TRST strapping");
1173 trst.apply()?;
1174 }
1175 self.pin_strapping("RESET")?.apply()?;
1176 std::thread::sleep(delay);
1177
1178 if uart_rx == UartRx::Clear {
1179 log::info!("Clearing the UART RX buffer");
1180 self.uart("console")?.clear_rx_buffer()?;
1181 }
1182
1183 log::info!("Deasserting the reset signal");
1184 self.pin_strapping("RESET")?.remove()?;
1187 if let Some(trst) = &trst {
1188 log::info!("Deasserting TRST strapping");
1189 trst.remove()?;
1190 }
1191
1192 if self.disable_dft_on_reset.get() {
1193 std::thread::sleep(Duration::from_millis(10));
1194 self.pin_strapping("PRERESET_DFT_DISABLE")?.remove()?;
1197 }
1198
1199 std::thread::sleep(delay);
1200
1201 Ok(())
1202 }
1203
1204 pub fn relinquish_exclusive_access<T>(&self, callback: impl FnOnce() -> T) -> Result<T> {
1213 let mut ret = None;
1214 self.transport.relinquish_exclusive_access(Box::new(|| {
1215 ret = Some(callback());
1216 }))?;
1217 Ok(ret.unwrap())
1218 }
1219}
1220
1221#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1222pub enum UartRx {
1223 Clear,
1224 Keep,
1225}
1226
1227fn map_name(map: &HashMap<String, String>, name: &str) -> String {
1230 let name = name.to_uppercase();
1231 match map.get(&name) {
1232 Some(v) => {
1233 if v.eq(&name) {
1234 name
1235 } else {
1236 map_name(map, v)
1237 }
1238 }
1239 None => name,
1240 }
1241}
1242
1243struct NullPin {
1248 has_warned: Cell<bool>,
1249}
1250
1251impl NullPin {
1252 fn new() -> Self {
1253 Self {
1254 has_warned: Cell::new(false),
1255 }
1256 }
1257
1258 fn warn(&self) {
1260 if !self.has_warned.get() {
1261 log::warn!("Accessed NULL pin");
1262 self.has_warned.set(true);
1263 }
1264 }
1265}
1266
1267impl GpioPin for NullPin {
1268 fn read(&self) -> Result<bool> {
1269 self.warn();
1270 Ok(false)
1271 }
1272
1273 fn write(&self, _value: bool) -> Result<()> {
1274 self.warn();
1275 Ok(())
1276 }
1277
1278 fn set_mode(&self, _mode: PinMode) -> Result<()> {
1279 self.warn();
1280 Ok(())
1281 }
1282
1283 fn set_pull_mode(&self, _mode: PullMode) -> Result<()> {
1284 self.warn();
1285 Ok(())
1286 }
1287}
1288
1289pub struct PinStrapping {
1292 name: String,
1293 proxy: Option<Rc<dyn Transport>>,
1294 pins: Vec<StrappedPin>,
1295 optional: bool,
1298}
1299
1300struct StrappedPin {
1301 pin: Rc<dyn GpioPin>,
1302 strapped: PinConfiguration,
1303 original: Option<PinConfiguration>,
1304}
1305
1306impl PinStrapping {
1307 pub fn apply(&self) -> Result<()> {
1310 if let Some(ref transport) = self.proxy {
1311 if let Err(e) = transport.proxy_ops()?.apply_pin_strapping(&self.name) {
1314 match e.downcast_ref::<TransportError>() {
1315 Some(TransportError::InvalidStrappingName(_)) => {
1316 if self.pins.is_empty() && !self.optional {
1317 return Err(e);
1318 }
1319 }
1320 _ => return Err(e),
1321 }
1322 }
1323 }
1324 for StrappedPin {
1325 pin,
1326 strapped: conf,
1327 original: _,
1328 } in &self.pins
1329 {
1330 pin.set(conf.mode, conf.level, conf.pull_mode, conf.volts)?
1331 }
1332 Ok(())
1333 }
1334
1335 pub fn remove(&self) -> Result<()> {
1339 if let Some(ref transport) = self.proxy {
1340 if let Err(e) = transport.proxy_ops()?.remove_pin_strapping(&self.name) {
1343 match e.downcast_ref::<TransportError>() {
1344 Some(TransportError::InvalidStrappingName(_)) => {
1345 if self.pins.is_empty() && !self.optional {
1346 return Err(e);
1347 }
1348 }
1349 _ => return Err(e),
1350 }
1351 }
1352 }
1353 for StrappedPin {
1354 pin,
1355 strapped: _,
1356 original,
1357 } in &self.pins
1358 {
1359 if let Some(conf) = original {
1360 pin.set(conf.mode, conf.level, conf.pull_mode, conf.volts)?
1361 }
1362 }
1363 Ok(())
1364 }
1365}