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::transport::{
22 Capability, MaintainConnection, ProgressIndicator, ProxyOps, Transport, TransportError,
23 TransportInterfaceType, ioexpander,
24};
25
26use anyhow::{Result, bail, ensure};
27use indicatif::{ProgressBar, ProgressStyle};
28use serde_annotate::Annotate;
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 openocd_adapter_config: Option<PathBuf>,
208 provides_list: Vec<(String, String)>,
209 requires_list: Vec<(String, String)>,
210 pin_alias_map: HashMap<String, String>,
211 pin_on_io_expander_map: HashMap<String, config::IoExpanderPin>,
212 pin_conf_list: Vec<(String, PinConfiguration)>,
213 uart_conf_map: HashMap<String, config::UartConfiguration>,
214 spi_conf_map: HashMap<String, config::SpiConfiguration>,
215 i2c_conf_map: HashMap<String, config::I2cConfiguration>,
216 strapping_conf_map: HashMap<String, Vec<(String, PinConfiguration)>>,
217 io_expander_conf_map: HashMap<String, config::IoExpander>,
218 gpio_conf: HashSet<String>,
219}
220
221pub struct TransportWrapper {
225 transport: Rc<dyn Transport>,
226 disable_dft_on_reset: Cell<bool>,
227 openocd_adapter_config: Option<PathBuf>,
228 provides_map: HashMap<String, String>,
229 pin_map: HashMap<String, String>,
230 artificial_pin_map: HashMap<String, Rc<dyn GpioPin>>,
231 pin_conf_map: HashMap<String, PinConfiguration>,
232 uart_conf_map: HashMap<String, UartConfiguration>,
233 spi_conf_map: HashMap<String, SpiConfiguration>,
234 i2c_conf_map: HashMap<String, I2cConfiguration>,
235 strapping_conf_map: HashMap<String, HashMap<String, PinConfiguration>>,
236 gpio_conf: HashSet<String>,
237 pin_instance_map: RefCell<HashMap<String, Rc<gpio::GpioPinWrapper>>>,
246 spi_physical_map: RefCell<HashMap<String, Rc<spi::PhysicalSpiWrapper>>>,
247 spi_logical_map: RefCell<HashMap<String, Rc<spi::LogicalSpiWrapper>>>,
248 i2c_physical_map: RefCell<HashMap<String, Rc<i2c::PhysicalI2cWrapper>>>,
249 i2c_logical_map: RefCell<HashMap<String, Rc<i2c::LogicalI2cWrapper>>>,
250}
251
252impl TransportWrapperBuilder {
253 pub fn new(interface: String, disable_dft_on_reset: bool) -> Self {
254 Self {
255 interface,
256 disable_dft_on_reset,
257 openocd_adapter_config: None,
258 provides_list: Vec::new(),
259 requires_list: Vec::new(),
260 pin_alias_map: HashMap::new(),
261 pin_on_io_expander_map: HashMap::new(),
262 pin_conf_list: Vec::new(),
263 uart_conf_map: HashMap::new(),
264 spi_conf_map: HashMap::new(),
265 i2c_conf_map: HashMap::new(),
266 strapping_conf_map: HashMap::new(),
267 io_expander_conf_map: HashMap::new(),
268 gpio_conf: HashSet::new(),
269 }
270 }
271
272 fn record_pin_conf(
273 pin_conf_list: &mut Vec<(String, PinConfiguration)>,
274 pin_conf: &config::PinConfiguration,
275 ) {
276 if (None, None, None, None, None)
277 == (
278 pin_conf.mode,
279 pin_conf.pull_mode,
280 pin_conf.level,
281 pin_conf.volts,
282 pin_conf.invert,
283 )
284 {
285 return;
286 }
287 let mut conf_entry: PinConfiguration = PinConfiguration::default();
288 if let Some(pin_mode) = pin_conf.mode {
289 conf_entry.mode = Some(pin_mode);
290 }
291 if let Some(pull_mode) = pin_conf.pull_mode {
292 conf_entry.pull_mode = Some(pull_mode);
293 }
294 if let Some(level) = pin_conf.level {
295 conf_entry.level = Some(level);
296 }
297 if let Some(volts) = pin_conf.volts {
298 conf_entry.volts = Some(volts);
299 }
300 if let Some(invert) = pin_conf.invert {
301 conf_entry.invert = Some(invert);
302 }
303 pin_conf_list.push((pin_conf.name.to_string(), conf_entry))
304 }
305
306 fn record_uart_conf(
307 uart_conf_map: &mut HashMap<String, config::UartConfiguration>,
308 uart_conf: &config::UartConfiguration,
309 ) -> Result<(), ()> {
310 let entry = uart_conf_map
311 .entry(uart_conf.name.to_uppercase().to_string())
312 .or_insert_with(|| config::UartConfiguration {
313 name: uart_conf.name.clone(),
314 ..Default::default()
315 });
316 merge_field(&mut entry.baudrate, &uart_conf.baudrate)?;
317 merge_field(&mut entry.parity, &uart_conf.parity)?;
318 merge_field(&mut entry.stopbits, &uart_conf.stopbits)?;
319 merge_field(&mut entry.alias_of, &uart_conf.alias_of)?;
320 Ok(())
321 }
322
323 fn record_spi_conf(
324 spi_conf_map: &mut HashMap<String, config::SpiConfiguration>,
325 spi_conf: &config::SpiConfiguration,
326 ) -> Result<(), ()> {
327 let entry = spi_conf_map
328 .entry(spi_conf.name.to_string())
329 .or_insert_with(|| config::SpiConfiguration {
330 name: spi_conf.name.clone(),
331 ..Default::default()
332 });
333 merge_field(&mut entry.mode, &spi_conf.mode)?;
334 merge_field(&mut entry.bits_per_word, &spi_conf.bits_per_word)?;
335 merge_field(&mut entry.bits_per_sec, &spi_conf.bits_per_sec)?;
336 merge_field(&mut entry.serial_clock, &spi_conf.serial_clock)?;
337 merge_field(&mut entry.host_out_device_in, &spi_conf.host_out_device_in)?;
338 merge_field(&mut entry.host_in_device_out, &spi_conf.host_in_device_out)?;
339 merge_field(&mut entry.chip_select, &spi_conf.chip_select)?;
340 merge_field(&mut entry.alias_of, &spi_conf.alias_of)?;
341 Ok(())
342 }
343
344 fn record_i2c_conf(
345 i2c_conf_map: &mut HashMap<String, config::I2cConfiguration>,
346 i2c_conf: &config::I2cConfiguration,
347 ) -> Result<(), ()> {
348 let entry = i2c_conf_map
349 .entry(i2c_conf.name.to_string())
350 .or_insert_with(|| config::I2cConfiguration {
351 name: i2c_conf.name.clone(),
352 ..Default::default()
353 });
354 merge_field(&mut entry.address, &i2c_conf.address)?;
355 merge_field(&mut entry.bits_per_sec, &i2c_conf.bits_per_sec)?;
356 merge_field(&mut entry.alias_of, &i2c_conf.alias_of)?;
357 Ok(())
358 }
359
360 pub fn add_configuration_file(&mut self, file: config::ConfigurationFile) -> Result<()> {
361 if let Some(interface) = file.interface {
362 if self.interface.is_empty() {
363 self.interface = interface;
364 } else if self.interface == interface {
365 } else {
368 bail!(TransportError::InconsistentInterfaceConf(
369 self.interface.to_string(),
370 interface,
371 ))
372 }
373 }
374 for (key, value) in file.provides {
375 self.provides_list.push((key, value));
376 }
377 for (key, value) in file.requires {
378 self.requires_list.push((key, value));
379 }
380 for pin_conf in file.pins {
382 if let Some(alias_of) = &pin_conf.alias_of {
383 self.pin_alias_map
384 .insert(pin_conf.name.to_uppercase(), alias_of.clone());
385 } else if let Some(on_io_expander) = &pin_conf.on_io_expander {
386 ensure!(
387 &pin_conf.alias_of.is_none(),
388 TransportError::InconsistentConf(
389 TransportInterfaceType::Gpio,
390 pin_conf.name.to_string()
391 )
392 );
393 let uppercase_name = pin_conf.name.to_uppercase();
394 ensure!(
395 !self.pin_on_io_expander_map.contains_key(&uppercase_name),
396 TransportError::InconsistentConf(
397 TransportInterfaceType::Gpio,
398 pin_conf.name.to_string()
399 )
400 );
401 self.pin_on_io_expander_map
402 .insert(uppercase_name, on_io_expander.clone());
403 }
404 Self::record_pin_conf(&mut self.pin_conf_list, &pin_conf);
406 }
407 for strapping_conf in file.strappings {
408 let strapping_pin_map = self
409 .strapping_conf_map
410 .entry(strapping_conf.name.to_uppercase())
411 .or_default();
412 for pin_conf in strapping_conf.pins {
413 ensure!(
414 pin_conf.invert.is_none(),
415 TransportError::InvalidConfStrapInvert(
416 strapping_conf.name.to_string(),
417 pin_conf.name.to_string()
418 )
419 );
420 ensure!(
421 pin_conf.alias_of.is_none(),
422 TransportError::InvalidConfStrapAlias(
423 strapping_conf.name.to_string(),
424 pin_conf.name.to_string()
425 )
426 );
427 Self::record_pin_conf(strapping_pin_map, &pin_conf);
428 }
429 }
430 for spi_conf in file.spi {
431 Self::record_spi_conf(&mut self.spi_conf_map, &spi_conf).map_err(|_| {
432 TransportError::InconsistentConf(
433 TransportInterfaceType::Spi,
434 spi_conf.name.to_string(),
435 )
436 })?;
437 }
438 for i2c_conf in file.i2c {
439 Self::record_i2c_conf(&mut self.i2c_conf_map, &i2c_conf).map_err(|_| {
440 TransportError::InconsistentConf(
441 TransportInterfaceType::I2c,
442 i2c_conf.name.to_string(),
443 )
444 })?;
445 }
446 for uart_conf in file.uarts {
447 Self::record_uart_conf(&mut self.uart_conf_map, &uart_conf).map_err(|_| {
448 TransportError::InconsistentConf(
449 TransportInterfaceType::Uart,
450 uart_conf.name.to_string(),
451 )
452 })?;
453 }
454 for io_expander_conf in file.io_expanders {
455 match self
456 .io_expander_conf_map
457 .entry(io_expander_conf.name.to_string())
458 {
459 Entry::Vacant(v) => {
460 v.insert(io_expander_conf);
461 }
462 Entry::Occupied(_) => bail!(TransportError::InconsistentConf(
463 TransportInterfaceType::IoExpander,
464 io_expander_conf.name
465 )),
466 }
467 }
468 for pin in file.gpios {
469 self.gpio_conf.insert(pin);
470 }
471 Ok(())
472 }
473
474 fn consolidate_provides_map(
475 result_provides_map: &mut HashMap<String, String>,
476 provides_list: Vec<(String, String)>,
477 ) -> Result<()> {
478 for (key, value) in provides_list {
479 match result_provides_map.entry(key.clone()) {
480 Entry::Vacant(v) => {
481 v.insert(value);
482 }
483 Entry::Occupied(v) => {
484 if v.get() != &value {
485 bail!(TransportError::InconsistentConf(
486 TransportInterfaceType::Provides,
487 key
488 ))
489 }
490 }
491 }
492 }
493 Ok(())
494 }
495
496 fn verify_requires_list(
497 provides_map: &HashMap<String, String>,
498 requires_list: &Vec<(String, String)>,
499 ) -> Result<()> {
500 for (key, required_value) in requires_list {
501 match provides_map.get(key) {
502 Some(actual_value) if actual_value == required_value => (),
503 Some(actual_value) => bail!(TransportError::RequiresUnequal(
504 key.to_string(),
505 required_value.to_string(),
506 actual_value.to_string()
507 )),
508 None => bail!(TransportError::RequiresMissing(
509 key.to_string(),
510 required_value.to_string()
511 )),
512 }
513 }
514 Ok(())
515 }
516
517 fn consolidate_pin_conf_map(
518 pin_alias_map: &HashMap<String, String>,
519 pin_conf_list: &Vec<(String, PinConfiguration)>,
520 ) -> Result<HashMap<String, PinConfiguration>> {
521 let mut result_pin_conf_map: HashMap<String, PinConfiguration> = HashMap::new();
522 for (name, conf) in pin_conf_list {
523 result_pin_conf_map
524 .entry(map_name(pin_alias_map, name))
525 .or_default()
526 .merge(conf)
527 .map_err(|_| {
528 TransportError::InconsistentConf(TransportInterfaceType::Gpio, name.to_string())
529 })?;
530 }
531 Ok(result_pin_conf_map)
532 }
533
534 fn resolve_uart_conf(
535 name: &str,
536 uart_conf_map: &HashMap<String, config::UartConfiguration>,
537 ) -> Result<UartConfiguration> {
538 if let Some(entry) = uart_conf_map.get(name.to_uppercase().as_str()) {
539 let mut conf = if let Some(ref alias_of) = entry.alias_of {
540 Self::resolve_uart_conf(alias_of.as_str(), uart_conf_map)?
541 } else {
542 UartConfiguration {
543 underlying_instance: name.to_uppercase().to_string(),
544 ..Default::default()
545 }
546 };
547 if let Some(baud_rate) = entry.baudrate {
549 conf.baud_rate = Some(baud_rate);
550 }
551 if let Some(parity) = entry.parity {
552 conf.parity = Some(parity);
553 }
554 if let Some(stop_bits) = entry.stopbits {
555 conf.stop_bits = Some(stop_bits);
556 }
557 Ok(conf)
558 } else {
559 Ok(UartConfiguration {
560 underlying_instance: name.to_string(),
561 ..Default::default()
562 })
563 }
564 }
565
566 fn consolidate_uart_conf_map(
567 uart_conf_map: &HashMap<String, config::UartConfiguration>,
568 ) -> Result<HashMap<String, UartConfiguration>> {
569 let mut resolved_uart_conf_map = HashMap::new();
570 for name in uart_conf_map.keys() {
571 resolved_uart_conf_map
572 .insert(name.clone(), Self::resolve_uart_conf(name, uart_conf_map)?);
573 }
574 Ok(resolved_uart_conf_map)
575 }
576
577 fn resolve_spi_conf(
578 name: &str,
579 spi_conf_map: &HashMap<String, config::SpiConfiguration>,
580 pin_alias_map: &HashMap<String, String>,
581 ) -> SpiConfiguration {
582 if let Some(entry) = spi_conf_map.get(name) {
583 let mut conf = if let Some(ref alias_of) = entry.alias_of {
584 Self::resolve_spi_conf(alias_of.as_str(), spi_conf_map, pin_alias_map)
585 } else {
586 SpiConfiguration {
587 underlying_instance: name.to_string(),
588 ..Default::default()
589 }
590 };
591 if let Some(serial_clock) = entry.serial_clock.as_ref() {
593 conf.serial_clock = Some(map_name(pin_alias_map, serial_clock));
594 }
595 if let Some(host_out_device_in) = entry.host_out_device_in.as_ref() {
596 conf.host_out_device_in = Some(map_name(pin_alias_map, host_out_device_in));
597 }
598 if let Some(host_in_device_out) = entry.host_in_device_out.as_ref() {
599 conf.host_in_device_out = Some(map_name(pin_alias_map, host_in_device_out));
600 }
601 if let Some(chip_select) = entry.chip_select.as_ref() {
602 conf.chip_select = Some(map_name(pin_alias_map, chip_select));
603 }
604 if let Some(mode) = entry.mode {
605 conf.mode = Some(mode);
606 }
607 if let Some(bits_per_sec) = entry.bits_per_sec {
608 conf.bits_per_sec = Some(bits_per_sec);
609 }
610 if let Some(bits_per_word) = entry.bits_per_word {
611 conf.bits_per_word = Some(bits_per_word);
612 }
613 conf
614 } else {
615 SpiConfiguration {
616 underlying_instance: name.to_string(),
617 ..Default::default()
618 }
619 }
620 }
621
622 fn consolidate_spi_conf_map(
623 spi_conf_map: &HashMap<String, config::SpiConfiguration>,
624 pin_alias_map: &HashMap<String, String>,
625 ) -> Result<HashMap<String, SpiConfiguration>> {
626 let mut resolved_spi_conf_map = HashMap::new();
627 for name in spi_conf_map.keys() {
628 resolved_spi_conf_map.insert(
629 name.clone(),
630 Self::resolve_spi_conf(name, spi_conf_map, pin_alias_map),
631 );
632 }
633 Ok(resolved_spi_conf_map)
634 }
635
636 fn resolve_i2c_conf(
637 name: &str,
638 i2c_conf_map: &HashMap<String, config::I2cConfiguration>,
639 ) -> I2cConfiguration {
640 if let Some(entry) = i2c_conf_map.get(name) {
641 let mut conf = if let Some(ref alias_of) = entry.alias_of {
642 Self::resolve_i2c_conf(alias_of.as_str(), i2c_conf_map)
643 } else {
644 I2cConfiguration {
645 underlying_instance: name.to_string(),
646 ..Default::default()
647 }
648 };
649 if let Some(addr) = entry.address {
651 conf.default_addr = Some(addr);
652 }
653 if let Some(bits_per_sec) = entry.bits_per_sec {
654 conf.bits_per_sec = Some(bits_per_sec);
655 }
656 conf
657 } else {
658 I2cConfiguration {
659 underlying_instance: name.to_string(),
660 ..Default::default()
661 }
662 }
663 }
664
665 fn consolidate_i2c_conf_map(
666 i2c_conf_map: &HashMap<String, config::I2cConfiguration>,
667 ) -> Result<HashMap<String, I2cConfiguration>> {
668 let mut resolved_i2c_conf_map = HashMap::new();
669 for name in i2c_conf_map.keys() {
670 resolved_i2c_conf_map.insert(name.clone(), Self::resolve_i2c_conf(name, i2c_conf_map));
671 }
672 Ok(resolved_i2c_conf_map)
673 }
674
675 pub fn get_interface(&self) -> &str {
676 &self.interface
677 }
678
679 pub fn set_openocd_adapter_config(&mut self, openocd_adapter_config: &Option<PathBuf>) {
680 self.openocd_adapter_config = openocd_adapter_config.clone();
681 }
682
683 pub fn build(
684 self,
685 transport: Box<dyn crate::transport::Transport>,
686 ) -> Result<TransportWrapper> {
687 let mut provides_map = if transport
688 .capabilities()?
689 .request(Capability::PROXY)
690 .ok()
691 .is_ok()
692 {
693 transport.proxy_ops()?.provides_map()?
694 } else {
695 HashMap::new()
696 };
697 Self::consolidate_provides_map(&mut provides_map, self.provides_list)?;
698 Self::verify_requires_list(&provides_map, &self.requires_list)?;
699
700 let pin_conf_map =
701 Self::consolidate_pin_conf_map(&self.pin_alias_map, &self.pin_conf_list)?;
702 let mut strapping_conf_map: HashMap<String, HashMap<String, PinConfiguration>> =
703 HashMap::new();
704 for (strapping_name, pin_conf_map) in self.strapping_conf_map {
705 strapping_conf_map.insert(
706 strapping_name,
707 Self::consolidate_pin_conf_map(&self.pin_alias_map, &pin_conf_map)?,
708 );
709 }
710 let uart_conf_map = Self::consolidate_uart_conf_map(&self.uart_conf_map)?;
711 let spi_conf_map = Self::consolidate_spi_conf_map(&self.spi_conf_map, &self.pin_alias_map)?;
712 let i2c_conf_map = Self::consolidate_i2c_conf_map(&self.i2c_conf_map)?;
713 let mut transport_wrapper = TransportWrapper {
714 transport: Rc::from(transport),
715 disable_dft_on_reset: Cell::new(self.disable_dft_on_reset),
716 openocd_adapter_config: self.openocd_adapter_config,
717 provides_map,
718 pin_map: self.pin_alias_map,
719 artificial_pin_map: HashMap::new(),
720 uart_conf_map,
721 pin_conf_map,
722 spi_conf_map,
723 i2c_conf_map,
724 strapping_conf_map,
725 gpio_conf: self.gpio_conf,
726 pin_instance_map: RefCell::new(HashMap::new()),
727 spi_physical_map: RefCell::new(HashMap::new()),
728 spi_logical_map: RefCell::new(HashMap::new()),
729 i2c_physical_map: RefCell::new(HashMap::new()),
730 i2c_logical_map: RefCell::new(HashMap::new()),
731 };
732 let mut io_expanders: HashMap<String, IoExpander> = HashMap::new();
733 for (name, conf) in self.io_expander_conf_map {
734 io_expanders.insert(
735 name.to_string(),
736 ioexpander::create(&conf, &transport_wrapper)?,
737 );
738 }
739 transport_wrapper
740 .artificial_pin_map
741 .insert("NULL".to_string(), Rc::new(NullPin::new()));
742 for (pinname, v) in self.pin_on_io_expander_map {
743 if let Some(io) = io_expanders.get(&v.io_expander) {
744 ensure!(
745 (v.pin_no as usize) < io.pins.len(),
746 TransportError::InvalidIoExpanderPinNo(v.io_expander.to_string(), v.pin_no)
747 );
748 transport_wrapper
749 .artificial_pin_map
750 .insert(pinname, Rc::clone(&io.pins[v.pin_no as usize]));
751 } else {
752 bail!(TransportError::InvalidIoExpanderName(
753 v.io_expander.to_string()
754 ));
755 }
756 }
757 Ok(transport_wrapper)
758 }
759}
760
761impl TransportWrapper {
762 pub fn ignore_dft_straps_on_reset(&self) -> Result<()> {
763 self.disable_dft_on_reset.set(false);
764 Ok(())
765 }
766
767 pub fn capabilities(&self) -> Result<crate::transport::Capabilities> {
770 let capabilities = self.transport.capabilities()?;
771 if self.openocd_adapter_config.is_some() {
772 Ok(capabilities.add(Capability::JTAG))
773 } else {
774 Ok(capabilities)
775 }
776 }
777
778 pub fn provides_map(&self) -> Result<&HashMap<String, String>> {
782 Ok(&self.provides_map)
783 }
784
785 pub fn query_provides(&self, key: &str) -> Result<&str> {
786 self.provides_map
787 .get(key)
788 .map(String::as_str)
789 .ok_or_else(|| {
790 TransportError::InvalidInstance(TransportInterfaceType::Provides, key.to_string())
791 .into()
792 })
793 }
794
795 pub fn jtag(&self, opts: &JtagParams) -> Result<Box<dyn JtagChain + '_>> {
797 if let Some(ref path) = self.openocd_adapter_config {
798 return Ok(Box::new(OpenOcdJtagChain::new(
800 &std::fs::read_to_string(path)?,
801 opts,
802 )?));
803 }
804 self.transport.jtag(opts)
807 }
808
809 pub fn spi(&self, name: &str) -> Result<Rc<dyn Target>> {
811 let name = name.to_uppercase();
812 let mut spi_logical_map = self.spi_logical_map.borrow_mut();
813 if let Some(instance) = spi_logical_map.get(&name) {
814 return Ok(Rc::clone(instance) as Rc<dyn Target>);
815 }
816 if let Some(spi_conf) = self.spi_conf_map.get(&name) {
817 let mut spi_physical_map = self.spi_physical_map.borrow_mut();
818 let physical_wrapper = if let Some(instance) =
821 spi_physical_map.get(&spi_conf.underlying_instance)
822 {
823 Rc::clone(instance)
824 } else {
825 let instance = Rc::new(spi::PhysicalSpiWrapper::new(
826 self.transport.spi(spi_conf.underlying_instance.as_str())?,
827 ));
828 spi_physical_map.insert(spi_conf.underlying_instance.clone(), Rc::clone(&instance));
829 instance
830 };
831
832 let new_wrapper = Rc::new(spi::LogicalSpiWrapper::new(
835 &*self.transport,
836 spi_conf,
837 physical_wrapper,
838 )?);
839 spi_logical_map.insert(name, Rc::clone(&new_wrapper));
840 Ok(new_wrapper)
841 } else {
842 self.transport.spi(name.as_str())
843 }
844 }
845
846 pub fn i2c(&self, name: &str) -> Result<Rc<dyn Bus>> {
848 let name = name.to_uppercase();
849 let mut i2c_logical_map = self.i2c_logical_map.borrow_mut();
850 if let Some(instance) = i2c_logical_map.get(&name) {
851 return Ok(Rc::clone(instance) as Rc<dyn Bus>);
852 }
853 if let Some(i2c_conf) = self.i2c_conf_map.get(&name) {
854 let mut i2c_physical_map = self.i2c_physical_map.borrow_mut();
855 let physical_wrapper = if let Some(instance) =
858 i2c_physical_map.get(&i2c_conf.underlying_instance)
859 {
860 Rc::clone(instance)
861 } else {
862 let instance = Rc::new(i2c::PhysicalI2cWrapper::new(
863 self.transport.i2c(i2c_conf.underlying_instance.as_str())?,
864 ));
865 i2c_physical_map.insert(i2c_conf.underlying_instance.clone(), Rc::clone(&instance));
866 instance
867 };
868
869 let new_wrapper = Rc::new(i2c::LogicalI2cWrapper::new(
872 &*self.transport,
873 i2c_conf,
874 physical_wrapper,
875 )?);
876 i2c_logical_map.insert(name, Rc::clone(&new_wrapper));
877 Ok(new_wrapper)
878 } else {
879 self.transport.i2c(name.as_str())
880 }
881 }
882
883 pub fn uart(&self, name: &str) -> Result<Rc<dyn Uart>> {
885 let uart_conf = self.uart_conf_map.get(name.to_uppercase().as_str());
886 let uart_name = uart_conf
887 .map(|uart_conf| uart_conf.underlying_instance.as_str())
888 .unwrap_or(name);
889 let uart = self.transport.uart(uart_name)?;
890 if let Some(conf) = uart_conf {
891 if let Some(baud_rate) = conf.baud_rate {
895 if let Ok(current_baud_rate) = uart.get_baudrate() {
896 if current_baud_rate != baud_rate {
897 uart.set_baudrate(baud_rate)?;
898 }
899 } else {
900 log::warn!("Could not read UART baud rate to check it is {}", baud_rate);
901 }
902 }
903 if let Some(parity) = conf.parity {
904 let new_parity = match parity {
905 config::UartParity::None => Parity::None,
906 config::UartParity::Even => Parity::Even,
907 config::UartParity::Odd => Parity::Odd,
908 config::UartParity::Mark | config::UartParity::Space => {
909 log::warn!("Mark & Space parities not yet supported");
910 Parity::None
911 }
912 };
913 if let Ok(current_parity) = uart.get_parity() {
914 if current_parity != new_parity {
915 uart.set_parity(new_parity)?;
916 }
917 } else {
918 log::warn!("Could not read UART parity to check it is {}", new_parity);
919 }
920 }
921 }
923 Ok(uart)
924 }
925
926 pub fn gpio_pin(&self, name: &str) -> Result<Rc<dyn GpioPin>> {
928 let resolved_pin_name = map_name(&self.pin_map, name);
929 let mut pin_instance_map = self.pin_instance_map.borrow_mut();
930 if let Some(instance) = pin_instance_map.get(&resolved_pin_name) {
933 Ok(Rc::clone(instance) as Rc<dyn GpioPin>)
934 } else {
935 let instance = if let Some(pin) = self.artificial_pin_map.get(&resolved_pin_name) {
936 pin.clone()
937 } else {
938 self.transport.gpio_pin(resolved_pin_name.as_str())?
939 };
940 let invert = self
941 .pin_conf_map
942 .get(&resolved_pin_name)
943 .and_then(|conf| conf.invert)
944 .unwrap_or(false);
945 let wrapper = Rc::new(gpio::GpioPinWrapper::new(instance, invert));
946 pin_instance_map.insert(resolved_pin_name, Rc::clone(&wrapper));
947 Ok(wrapper as Rc<dyn GpioPin>)
948 }
949 }
950
951 pub fn gpio_pins(&self, names: &[String]) -> Result<Vec<Rc<dyn GpioPin>>> {
953 let mut result = Vec::new();
954 for name in names {
955 result.push(self.gpio_pin(name)?);
956 }
957 Ok(result)
958 }
959
960 pub fn gpios(&self) -> &HashSet<String> {
961 &self.gpio_conf
962 }
963
964 pub fn gpio_monitoring(&self) -> Result<Rc<dyn GpioMonitoring>> {
966 self.transport.gpio_monitoring()
967 }
968
969 pub fn gpio_bitbanging(&self) -> Result<Rc<dyn GpioBitbanging>> {
971 self.transport.gpio_bitbanging()
972 }
973
974 pub fn pin_strapping(&self, name: &str) -> Result<PinStrapping> {
975 let proxy = if self.capabilities()?.request(Capability::PROXY).ok().is_ok() {
976 Some(self.proxy_ops()?)
977 } else {
978 None
979 };
980 let mut pins = Vec::new();
981 if let Some(strapping_conf_map) = self.strapping_conf_map.get(name) {
982 for (pin_name, conf) in strapping_conf_map {
983 pins.push(StrappedPin {
984 pin: self.gpio_pin(pin_name)?,
985 strapped: *conf,
986 original: self.pin_conf_map.get(pin_name).copied(),
987 });
988 }
989 } else if proxy.is_none() {
990 bail!(TransportError::InvalidStrappingName(name.to_string()));
991 }
992 Ok(PinStrapping {
993 proxy,
994 name: name.to_string(),
995 pins,
996 })
997 }
998
999 pub fn emulator(&self) -> Result<Rc<dyn Emulator>> {
1001 self.transport.emulator()
1002 }
1003
1004 pub fn proxy_ops(&self) -> Result<Rc<dyn ProxyOps>> {
1006 self.transport.proxy_ops()
1007 }
1008
1009 pub fn dispatch(&self, action: &dyn Any) -> Result<Option<Box<dyn Annotate>>> {
1011 self.transport.dispatch(action)
1012 }
1013
1014 fn apply_pin_configuration(&self, name: &str, conf: &PinConfiguration) -> Result<()> {
1016 let pin = self.gpio_pin(name)?;
1017 pin.set(conf.mode, conf.level, conf.pull_mode, conf.volts)
1018 }
1019
1020 fn apply_pin_configurations(
1022 &self,
1023 conf_map: &HashMap<String, PinConfiguration>,
1024 overrides: Option<&HashMap<String, PinConfiguration>>,
1025 ) -> Result<()> {
1026 let update_pin = |name, conf: &PinConfiguration| {
1028 self.apply_pin_configuration(
1029 name,
1030 &conf.override_with(overrides.and_then(|o| o.get(name))),
1031 )
1032 };
1033 for (name, conf) in conf_map {
1040 if !self.artificial_pin_map.contains_key(name) {
1041 update_pin(name, conf)?;
1042 }
1043 }
1044 for (name, conf) in conf_map {
1045 if self.artificial_pin_map.contains_key(name) {
1046 update_pin(name, conf)?;
1047 }
1048 }
1049 Ok(())
1050 }
1051
1052 pub fn apply_default_configuration(&self, strapping_name: Option<&str>) -> Result<()> {
1055 let _maintain_connection = self.transport.maintain_connection()?;
1060 if let Some(strapping_name) = strapping_name {
1061 if self.capabilities()?.request(Capability::PROXY).ok().is_ok() {
1062 self.proxy_ops()?
1063 .apply_default_configuration_with_strap(strapping_name)?;
1064 } else if let Some(strapping_conf_map) = self.strapping_conf_map.get(strapping_name) {
1065 self.transport.apply_default_configuration()?;
1067 self.apply_pin_configurations(&self.pin_conf_map, Some(strapping_conf_map))?;
1072 } else {
1073 bail!(TransportError::InvalidStrappingName(
1074 strapping_name.to_string(),
1075 ));
1076 }
1077 } else {
1078 self.transport.apply_default_configuration()?;
1079 self.apply_pin_configurations(&self.pin_conf_map, None)?;
1080 }
1081 self.pin_instance_map.borrow_mut().clear();
1084 self.spi_physical_map.borrow_mut().clear();
1085 self.spi_logical_map.borrow_mut().clear();
1086 self.i2c_physical_map.borrow_mut().clear();
1087 self.i2c_logical_map.borrow_mut().clear();
1088 Ok(())
1089 }
1090
1091 pub fn reset_target(&self, reset_delay: Duration, clear_uart_rx: bool) -> Result<()> {
1092 let _maintain_connection = self.transport.maintain_connection()?;
1097 log::info!("Asserting the reset signal");
1098 if self.disable_dft_on_reset.get() {
1099 self.pin_strapping("PRERESET_DFT_DISABLE")?.apply()?;
1100 }
1101 self.pin_strapping("RESET")?.apply()?;
1102 std::thread::sleep(reset_delay);
1103 if clear_uart_rx {
1104 log::info!("Clearing the UART RX buffer");
1105 self.uart("console")?.clear_rx_buffer()?;
1106 }
1107 log::info!("Deasserting the reset signal");
1108 self.pin_strapping("RESET")?.remove()?;
1109 if self.disable_dft_on_reset.get() {
1110 std::thread::sleep(Duration::from_millis(10));
1111 self.pin_strapping("PRERESET_DFT_DISABLE")?.remove()?;
1114 }
1115 std::thread::sleep(reset_delay);
1116 Ok(())
1117 }
1118
1119 pub fn maintain_connection(&self) -> Result<Rc<dyn MaintainConnection>> {
1123 self.transport.maintain_connection()
1124 }
1125}
1126
1127fn map_name(map: &HashMap<String, String>, name: &str) -> String {
1130 let name = name.to_uppercase();
1131 match map.get(&name) {
1132 Some(v) => {
1133 if v.eq(&name) {
1134 name
1135 } else {
1136 map_name(map, v)
1137 }
1138 }
1139 None => name,
1140 }
1141}
1142
1143struct NullPin {
1148 has_warned: Cell<bool>,
1149}
1150
1151impl NullPin {
1152 fn new() -> Self {
1153 Self {
1154 has_warned: Cell::new(false),
1155 }
1156 }
1157
1158 fn warn(&self) {
1160 if !self.has_warned.get() {
1161 log::warn!("Accessed NULL pin");
1162 self.has_warned.set(true);
1163 }
1164 }
1165}
1166
1167impl GpioPin for NullPin {
1168 fn read(&self) -> Result<bool> {
1169 self.warn();
1170 Ok(false)
1171 }
1172
1173 fn write(&self, _value: bool) -> Result<()> {
1174 self.warn();
1175 Ok(())
1176 }
1177
1178 fn set_mode(&self, _mode: PinMode) -> Result<()> {
1179 self.warn();
1180 Ok(())
1181 }
1182
1183 fn set_pull_mode(&self, _mode: PullMode) -> Result<()> {
1184 self.warn();
1185 Ok(())
1186 }
1187}
1188
1189pub struct PinStrapping {
1192 name: String,
1193 proxy: Option<Rc<dyn ProxyOps>>,
1194 pins: Vec<StrappedPin>,
1195}
1196
1197struct StrappedPin {
1198 pin: Rc<dyn GpioPin>,
1199 strapped: PinConfiguration,
1200 original: Option<PinConfiguration>,
1201}
1202
1203impl PinStrapping {
1204 pub fn apply(&self) -> Result<()> {
1207 if let Some(ref proxy_ops) = self.proxy {
1208 if let Err(e) = proxy_ops.apply_pin_strapping(&self.name) {
1211 match e.downcast_ref::<TransportError>() {
1212 Some(TransportError::InvalidStrappingName(_)) => {
1213 if self.pins.is_empty() {
1214 return Err(e);
1215 }
1216 }
1217 _ => return Err(e),
1218 }
1219 }
1220 }
1221 for StrappedPin {
1222 pin,
1223 strapped: conf,
1224 original: _,
1225 } in &self.pins
1226 {
1227 pin.set(conf.mode, conf.level, conf.pull_mode, conf.volts)?
1228 }
1229 Ok(())
1230 }
1231
1232 pub fn remove(&self) -> Result<()> {
1236 if let Some(ref proxy_ops) = self.proxy {
1237 if let Err(e) = proxy_ops.remove_pin_strapping(&self.name) {
1240 match e.downcast_ref::<TransportError>() {
1241 Some(TransportError::InvalidStrappingName(_)) => {
1242 if self.pins.is_empty() {
1243 return Err(e);
1244 }
1245 }
1246 _ => return Err(e),
1247 }
1248 }
1249 }
1250 for StrappedPin {
1251 pin,
1252 strapped: _,
1253 original,
1254 } in &self.pins
1255 {
1256 if let Some(conf) = original {
1257 pin.set(conf.mode, conf.level, conf.pull_mode, conf.volts)?
1258 }
1259 }
1260 Ok(())
1261 }
1262}