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