probe_rs/
probe.rs

1//! Probe drivers
2pub(crate) mod common;
3pub(crate) mod usb_util;
4
5pub mod blackmagic;
6pub mod ch347usbjtag;
7pub mod cmsisdap;
8pub mod espusbjtag;
9pub mod fake_probe;
10pub mod ftdi;
11pub mod glasgow;
12pub mod jlink;
13pub mod list;
14pub mod sifliuart;
15pub mod stlink;
16pub mod wlink;
17
18use crate::architecture::arm::sequences::{ArmDebugSequence, DefaultArmSequence};
19use crate::architecture::arm::{ArmDebugInterface, ArmError, DapError};
20use crate::architecture::arm::{RegisterAddress, SwoAccess, communication_interface::DapProbe};
21use crate::architecture::riscv::communication_interface::{RiscvError, RiscvInterfaceBuilder};
22use crate::architecture::xtensa::communication_interface::{
23    XtensaCommunicationInterface, XtensaDebugInterfaceState, XtensaError,
24};
25use crate::config::TargetSelector;
26use crate::config::registry::Registry;
27use crate::probe::common::JtagState;
28use crate::{Error, Permissions, Session};
29use bitvec::slice::BitSlice;
30use bitvec::vec::BitVec;
31use common::ScanChainError;
32use nusb::DeviceInfo;
33use probe_rs_target::ScanChainElement;
34use serde::{Deserialize, Deserializer, Serialize, Serializer};
35use std::any::Any;
36use std::collections::HashMap;
37use std::fmt;
38use std::sync::Arc;
39
40/// Used to log warnings when the measured target voltage is
41/// lower than 1.4V, if at all measurable.
42const LOW_TARGET_VOLTAGE_WARNING_THRESHOLD: f32 = 1.4;
43
44/// The protocol that is to be used by the probe when communicating with the target.
45///
46/// For ARM select `Swd` or `Jtag`, for RISC-V select `Jtag`.
47#[derive(Copy, Clone, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
48pub enum WireProtocol {
49    /// Serial Wire Debug is ARMs proprietary standard for communicating with ARM cores.
50    /// You can find specifics in the [`ARM Debug Interface v5.2`](https://developer.arm.com/documentation/ihi0031/f/?lang=en) specification.
51    Swd,
52    /// JTAG is a standard which is supported by many chips independent of architecture.
53    /// See [`Wikipedia`](https://en.wikipedia.org/wiki/JTAG) for more info.
54    Jtag,
55}
56
57impl fmt::Display for WireProtocol {
58    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59        match self {
60            WireProtocol::Swd => f.write_str("SWD"),
61            WireProtocol::Jtag => f.write_str("JTAG"),
62        }
63    }
64}
65
66impl std::str::FromStr for WireProtocol {
67    type Err = String;
68
69    fn from_str(s: &str) -> Result<Self, Self::Err> {
70        match &s.to_ascii_lowercase()[..] {
71            "swd" => Ok(WireProtocol::Swd),
72            "jtag" => Ok(WireProtocol::Jtag),
73            _ => Err(format!(
74                "'{s}' is not a valid protocol. Choose either 'swd' or 'jtag'."
75            )),
76        }
77    }
78}
79
80/// A command queued in a batch for later execution
81///
82/// Mostly used internally but returned in DebugProbeError to indicate
83/// which batched command actually encountered the error.
84#[derive(Clone, Debug)]
85pub enum BatchCommand {
86    /// Read from a port
87    Read(RegisterAddress),
88
89    /// Write to a port
90    Write(RegisterAddress, u32),
91}
92
93impl fmt::Display for BatchCommand {
94    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95        match self {
96            BatchCommand::Read(port) => {
97                write!(f, "Read(port={port:?})")
98            }
99            BatchCommand::Write(port, data) => {
100                write!(f, "Write(port={port:?}, data={data:#010x})")
101            }
102        }
103    }
104}
105
106/// Marker trait for all probe errors.
107pub trait ProbeError: std::error::Error + Send + Sync + std::any::Any {}
108
109impl std::error::Error for Box<dyn ProbeError> {
110    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
111        self.as_ref().source()
112    }
113}
114
115/// A probe-specific error.
116#[derive(Debug, thiserror::Error)]
117#[error(transparent)]
118pub struct BoxedProbeError(#[from] Box<dyn ProbeError>);
119
120impl BoxedProbeError {
121    fn as_any(&self) -> &dyn std::any::Any {
122        self.0.as_ref()
123    }
124
125    /// Returns true if the underlying error is of type `T`.
126    pub fn is<T: ProbeError>(&self) -> bool {
127        self.as_any().is::<T>()
128    }
129
130    /// Attempts to downcast the error to a specific error type.
131    pub fn downcast_ref<T: ProbeError>(&self) -> Option<&T> {
132        self.as_any().downcast_ref()
133    }
134
135    /// Attempts to downcast the error to a specific error type.
136    pub fn downcast_mut<T: ProbeError>(&mut self) -> Option<&mut T> {
137        let any: &mut dyn std::any::Any = self.0.as_mut();
138        any.downcast_mut()
139    }
140}
141
142impl<T> From<T> for BoxedProbeError
143where
144    T: ProbeError,
145{
146    fn from(e: T) -> Self {
147        BoxedProbeError(Box::new(e))
148    }
149}
150
151/// This error occurs whenever the debug probe logic encounters an error while operating the relevant debug probe.
152#[derive(thiserror::Error, Debug, docsplay::Display)]
153pub enum DebugProbeError {
154    /// USB Communication Error
155    Usb(#[source] std::io::Error),
156
157    /// An error which is specific to the debug probe in use occurred.
158    ProbeSpecific(#[source] BoxedProbeError),
159
160    /// The debug probe could not be created.
161    ProbeCouldNotBeCreated(#[from] ProbeCreationError),
162
163    /// The probe does not support the {0} protocol.
164    UnsupportedProtocol(WireProtocol),
165
166    /// The selected probe does not support the '{interface_name}' interface.
167    ///
168    /// This happens if a probe does not support certain functionality, such as:
169    /// - ARM debugging
170    /// - RISC-V debugging
171    /// - SWO
172    #[ignore_extra_doc_attributes]
173    InterfaceNotAvailable {
174        /// The name of the unsupported interface.
175        interface_name: &'static str,
176    },
177
178    /// The probe does not support the requested speed setting ({0} kHz).
179    UnsupportedSpeed(u32),
180
181    /// You need to be attached to the target to perform this action.
182    ///
183    /// The debug probe did not yet perform the init sequence.
184    /// Try calling [`DebugProbe::attach`] before trying again.
185    #[ignore_extra_doc_attributes]
186    NotAttached,
187
188    /// You need to be detached from the target to perform this action.
189    ///
190    /// The debug probe already performed the init sequence.
191    /// Try running the failing command before [`DebugProbe::attach`].
192    #[ignore_extra_doc_attributes]
193    Attached,
194
195    /// Failed to find or attach to the target. Please check the wiring before retrying.
196    TargetNotFound,
197
198    /// Error in previous batched command.
199    BatchError(BatchCommand),
200
201    /// The '{function_name}' functionality is not implemented yet.
202    ///
203    /// The variant of the function you called is not yet implemented.
204    /// This can happen if some debug probe has some unimplemented functionality for a specific protocol or architecture.
205    #[ignore_extra_doc_attributes]
206    NotImplemented {
207        /// The name of the unsupported functionality.
208        function_name: &'static str,
209    },
210
211    /// The '{command_name}' functionality is not supported by the selected probe.
212    /// This can happen when a probe does not allow for setting speed manually for example.
213    CommandNotSupportedByProbe {
214        /// The name of the unsupported command.
215        command_name: &'static str,
216    },
217
218    /// An error occurred handling the JTAG scan chain.
219    JtagScanChain(#[from] ScanChainError),
220
221    /// Some other error occurred
222    #[display("{0}")]
223    Other(String),
224
225    /// A timeout occurred during probe operation.
226    Timeout,
227}
228
229impl<T: ProbeError> From<T> for DebugProbeError {
230    fn from(e: T) -> Self {
231        Self::ProbeSpecific(BoxedProbeError::from(e))
232    }
233}
234
235/// An error during probe creation occurred.
236/// This is almost always a sign of a bad USB setup.
237/// Check UDEV rules if you are on Linux and try installing Zadig
238/// (This will disable vendor specific drivers for your probe!) if you are on Windows.
239#[derive(thiserror::Error, Debug, docsplay::Display)]
240pub enum ProbeCreationError {
241    /// The selected debug probe was not found.
242    /// This can be due to permissions.
243    NotFound,
244
245    /// The selected USB device could not be opened.
246    CouldNotOpen,
247
248    /// An HID API occurred.
249    #[cfg(feature = "cmsisdap_v1")]
250    HidApi(#[from] hidapi::HidError),
251
252    /// A USB error occurred.
253    Usb(#[source] std::io::Error),
254
255    /// An error specific with the selected probe occurred.
256    ProbeSpecific(#[source] BoxedProbeError),
257
258    /// Something else happened.
259    #[display("{0}")]
260    Other(&'static str),
261}
262
263impl<T: ProbeError> From<T> for ProbeCreationError {
264    fn from(e: T) -> Self {
265        Self::ProbeSpecific(BoxedProbeError::from(e))
266    }
267}
268
269/// The Probe struct is a generic wrapper over the different
270/// probes supported.
271///
272/// # Examples
273///
274/// ## Open the first probe found
275///
276/// The `list_all` and `from_probe_info` functions can be used
277/// to create a new `Probe`:
278///
279/// ```no_run
280/// use probe_rs::probe::{Probe, list::Lister};
281///
282/// let lister = Lister::new();
283///
284/// let probe_list = lister.list_all();
285/// let probe = probe_list[0].open();
286/// ```
287#[derive(Debug)]
288pub struct Probe {
289    inner: Box<dyn DebugProbe>,
290    attached: bool,
291}
292
293impl Probe {
294    /// Create a new probe from a more specific probe driver.
295    pub fn new(probe: impl DebugProbe + 'static) -> Self {
296        Self {
297            inner: Box::new(probe),
298            attached: false,
299        }
300    }
301
302    pub(crate) fn from_attached_probe(probe: Box<dyn DebugProbe>) -> Self {
303        Self {
304            inner: probe,
305            attached: true,
306        }
307    }
308
309    /// Same as [`Probe::new`] but without automatic boxing in case you already have a box.
310    pub fn from_specific_probe(probe: Box<dyn DebugProbe>) -> Self {
311        Probe {
312            inner: probe,
313            attached: false,
314        }
315    }
316
317    /// Get the human readable name for the probe.
318    pub fn get_name(&self) -> String {
319        self.inner.get_name().to_string()
320    }
321
322    /// Attach to the chip.
323    ///
324    /// This runs all the necessary protocol init routines.
325    ///
326    /// The target is loaded from the builtin list of targets.
327    /// If this doesn't work, you might want to try [`Probe::attach_under_reset`].
328    pub fn attach(
329        self,
330        target: impl Into<TargetSelector>,
331        permissions: Permissions,
332    ) -> Result<Session, Error> {
333        let registry = Registry::from_builtin_families();
334        self.attach_with_registry(target, permissions, &registry)
335    }
336
337    /// Attach to the chip.
338    ///
339    /// This runs all the necessary protocol init routines.
340    ///
341    /// The target is loaded from a custom registry.
342    /// If this doesn't work, you might want to try [`Probe::attach_under_reset`].
343    pub fn attach_with_registry(
344        self,
345        target: impl Into<TargetSelector>,
346        permissions: Permissions,
347        registry: &Registry,
348    ) -> Result<Session, Error> {
349        Session::new(
350            self,
351            target.into(),
352            AttachMethod::Normal,
353            permissions,
354            registry,
355        )
356    }
357
358    /// Attach to a target without knowing what target you have at hand.
359    /// This can be used for automatic device discovery or performing operations on an unspecified target.
360    pub fn attach_to_unspecified(&mut self) -> Result<(), Error> {
361        self.inner.attach()?;
362        self.attached = true;
363        Ok(())
364    }
365
366    /// A combination of [`Probe::attach_to_unspecified`] and [`Probe::attach_under_reset`].
367    pub fn attach_to_unspecified_under_reset(&mut self) -> Result<(), Error> {
368        if let Some(dap_probe) = self.try_as_dap_probe() {
369            DefaultArmSequence(()).reset_hardware_assert(dap_probe)?;
370        } else {
371            tracing::info!(
372                "Custom reset sequences are not supported on {}.",
373                self.get_name()
374            );
375            tracing::info!("Falling back to standard probe reset.");
376            self.target_reset_assert()?;
377        }
378        self.attach_to_unspecified()?;
379        Ok(())
380    }
381
382    /// Attach to the chip under hard-reset.
383    ///
384    /// This asserts the reset pin via the probe, plays the protocol init routines and deasserts the pin.
385    /// This is necessary if the chip is not responding to the SWD reset sequence.
386    /// For example this can happen if the chip has the SWDIO pin remapped.
387    ///
388    /// The target is loaded from the builtin list of targets.
389    pub fn attach_under_reset(
390        self,
391        target: impl Into<TargetSelector>,
392        permissions: Permissions,
393    ) -> Result<Session, Error> {
394        let registry = Registry::from_builtin_families();
395        self.attach_under_reset_with_registry(target, permissions, &registry)
396    }
397
398    /// Attach to the chip under hard-reset.
399    ///
400    /// This asserts the reset pin via the probe, plays the protocol init routines and deasserts the pin.
401    /// This is necessary if the chip is not responding to the SWD reset sequence.
402    /// For example this can happen if the chip has the SWDIO pin remapped.
403    ///
404    /// The target is loaded from a custom registry.
405    pub fn attach_under_reset_with_registry(
406        self,
407        target: impl Into<TargetSelector>,
408        permissions: Permissions,
409        registry: &Registry,
410    ) -> Result<Session, Error> {
411        // The session will de-assert reset after connecting to the debug interface.
412        Session::new(
413            self,
414            target.into(),
415            AttachMethod::UnderReset,
416            permissions,
417            registry,
418        )
419        .map_err(|e| match e {
420            Error::Arm(ArmError::Timeout)
421            | Error::Riscv(RiscvError::Timeout)
422            | Error::Xtensa(XtensaError::Timeout) => Error::Other(
423                "Timeout while attaching to target under reset. \
424                    This can happen if the target is not responding to the reset sequence. \
425                    Ensure the chip's reset pin is connected, or try attaching without reset \
426                    (`connectUnderReset = false` for DAP Clients, or remove `connect-under-reset` \
427                        option from CLI options.)."
428                    .to_string(),
429            ),
430            e => e,
431        })
432    }
433
434    /// Selects the transport protocol to be used by the debug probe.
435    pub fn select_protocol(&mut self, protocol: WireProtocol) -> Result<(), DebugProbeError> {
436        if !self.attached {
437            self.inner.select_protocol(protocol)
438        } else {
439            Err(DebugProbeError::Attached)
440        }
441    }
442
443    /// Get the currently selected protocol
444    ///
445    /// Depending on the probe, this might not be available.
446    pub fn protocol(&self) -> Option<WireProtocol> {
447        self.inner.active_protocol()
448    }
449
450    /// Leave debug mode
451    pub fn detach(&mut self) -> Result<(), crate::Error> {
452        self.attached = false;
453        self.inner.detach()?;
454        Ok(())
455    }
456
457    /// Resets the target device.
458    pub fn target_reset(&mut self) -> Result<(), DebugProbeError> {
459        self.inner.target_reset()
460    }
461
462    /// Asserts the reset of the target.
463    /// This is always the hard reset which means the reset wire has to be connected to work.
464    ///
465    /// This is not supported on all probes.
466    pub fn target_reset_assert(&mut self) -> Result<(), DebugProbeError> {
467        tracing::debug!("Asserting target reset");
468        self.inner.target_reset_assert()
469    }
470
471    /// Deasserts the reset of the target.
472    /// This is always the hard reset which means the reset wire has to be connected to work.
473    ///
474    /// This is not supported on all probes.
475    pub fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError> {
476        tracing::debug!("Deasserting target reset");
477        self.inner.target_reset_deassert()
478    }
479
480    /// Configure protocol speed to use in kHz
481    pub fn set_speed(&mut self, speed_khz: u32) -> Result<u32, DebugProbeError> {
482        if !self.attached {
483            self.inner.set_speed(speed_khz)
484        } else {
485            Err(DebugProbeError::Attached)
486        }
487    }
488
489    /// Get the currently used maximum speed for the debug protocol in kHz.
490    ///
491    /// Not all probes report which speed is used, meaning this value is not
492    /// always the actual speed used. However, the speed should not be any
493    /// higher than this value.
494    pub fn speed_khz(&self) -> u32 {
495        self.inner.speed_khz()
496    }
497
498    /// Check if the probe has an interface to
499    /// debug Xtensa chips.
500    pub fn has_xtensa_interface(&self) -> bool {
501        self.inner.has_xtensa_interface()
502    }
503
504    /// Try to get a [`XtensaCommunicationInterface`], which can
505    /// can be used to communicate with chips using the Xtensa
506    /// architecture.
507    ///
508    /// The user is responsible for creating and managing the [`XtensaDebugInterfaceState`] state
509    /// object.
510    ///
511    /// If an error occurs while trying to connect, the probe is returned.
512    pub fn try_get_xtensa_interface<'probe>(
513        &'probe mut self,
514        state: &'probe mut XtensaDebugInterfaceState,
515    ) -> Result<XtensaCommunicationInterface<'probe>, XtensaError> {
516        if !self.attached {
517            Err(DebugProbeError::NotAttached.into())
518        } else {
519            Ok(self.inner.try_get_xtensa_interface(state)?)
520        }
521    }
522
523    /// Checks if the probe supports connecting to chips
524    /// using the Arm Debug Interface.
525    pub fn has_arm_debug_interface(&self) -> bool {
526        self.inner.has_arm_interface()
527    }
528
529    /// Try to get a trait object implementing [`ArmDebugInterface`], which can
530    /// can be used to communicate with chips using the ARM debug interface.
531    ///
532    /// If an error occurs while trying to connect, the probe is returned.
533    pub fn try_into_arm_debug_interface<'probe>(
534        self,
535        sequence: Arc<dyn ArmDebugSequence>,
536    ) -> Result<Box<dyn ArmDebugInterface + 'probe>, (Self, ArmError)> {
537        if !self.attached {
538            Err((self, DebugProbeError::NotAttached.into()))
539        } else {
540            self.inner
541                .try_get_arm_debug_interface(sequence)
542                .map_err(|(probe, err)| (Probe::from_attached_probe(probe), err))
543        }
544    }
545
546    /// Check if the probe has an interface to debug RISC-V chips.
547    pub fn has_riscv_interface(&self) -> bool {
548        self.inner.has_riscv_interface()
549    }
550
551    /// Try to get a [`RiscvInterfaceBuilder`] object, which can be used to set up a communication
552    /// interface with chips using the RISC-V architecture.
553    ///
554    /// The returned object can be used to create the interface state, which is required to
555    /// attach to the RISC-V target. The user is responsible for managing this state object.
556    ///
557    /// If an error occurs while trying to connect, the probe is returned.
558    pub fn try_get_riscv_interface_builder<'probe>(
559        &'probe mut self,
560    ) -> Result<Box<dyn RiscvInterfaceBuilder<'probe> + 'probe>, RiscvError> {
561        if !self.attached {
562            Err(DebugProbeError::NotAttached.into())
563        } else {
564            self.inner.try_get_riscv_interface_builder()
565        }
566    }
567
568    /// Returns a [`JtagAccess`] from the debug probe, if implemented.
569    pub fn try_as_jtag_probe(&mut self) -> Option<&mut dyn JtagAccess> {
570        self.inner.try_as_jtag_probe()
571    }
572
573    /// Gets a SWO interface from the debug probe.
574    ///
575    /// This does not work on all probes.
576    pub fn get_swo_interface(&self) -> Option<&dyn SwoAccess> {
577        self.inner.get_swo_interface()
578    }
579
580    /// Gets a mutable SWO interface from the debug probe.
581    ///
582    /// This does not work on all probes.
583    pub fn get_swo_interface_mut(&mut self) -> Option<&mut dyn SwoAccess> {
584        self.inner.get_swo_interface_mut()
585    }
586
587    /// Gets a DAP interface from the debug probe.
588    ///
589    /// This does not work on all probes.
590    pub fn try_as_dap_probe(&mut self) -> Option<&mut dyn DapProbe> {
591        self.inner.try_as_dap_probe()
592    }
593
594    /// Try reading the target voltage of via the connected voltage pin.
595    ///
596    /// This does not work on all probes.
597    pub fn get_target_voltage(&mut self) -> Result<Option<f32>, DebugProbeError> {
598        self.inner.get_target_voltage()
599    }
600
601    /// Try to convert the probe into a concrete probe type.
602    pub fn try_into<P: DebugProbe>(&mut self) -> Option<&mut P> {
603        (self.inner.as_mut() as &mut dyn Any).downcast_mut::<P>()
604    }
605}
606
607/// An abstraction over a probe driver type.
608///
609/// This trait has to be implemented by ever debug probe driver.
610///
611/// The `std::fmt::Display` implementation will be used to display the probe in the list of available probes,
612/// and should return a human-readable name for the probe type.
613pub trait ProbeFactory: std::any::Any + std::fmt::Display + std::fmt::Debug + Sync {
614    /// Creates a new boxed [`DebugProbe`] from a given [`DebugProbeSelector`].
615    /// This will be called for all available debug drivers when discovering probes.
616    /// When opening, it will open the first probe which succeeds during this call.
617    fn open(&self, selector: &DebugProbeSelector) -> Result<Box<dyn DebugProbe>, DebugProbeError>;
618
619    /// Returns a list of all available debug probes of the current type.
620    fn list_probes(&self) -> Vec<DebugProbeInfo>;
621
622    /// Returns a list of probes that match the optional selector.
623    ///
624    /// If the selector is `None`, all available probes are returned.
625    fn list_probes_filtered(&self, selector: Option<&DebugProbeSelector>) -> Vec<DebugProbeInfo> {
626        // The default implementation falls back to listing all probes so that drivers don't need
627        // to deal with the common filtering logic.
628        self.list_probes()
629            .into_iter()
630            .filter(|probe| selector.as_ref().is_none_or(|s| s.matches_probe(probe)))
631            .collect()
632    }
633}
634
635/// An abstraction over a general debug probe.
636///
637/// This trait has to be implemented by ever debug probe driver.
638pub trait DebugProbe: Any + Send + fmt::Debug {
639    /// Get human readable name for the probe.
640    fn get_name(&self) -> &str;
641
642    /// Get the currently used maximum speed for the debug protocol in kHz.
643    ///
644    /// Not all probes report which speed is used, meaning this value is not
645    /// always the actual speed used. However, the speed should not be any
646    /// higher than this value.
647    fn speed_khz(&self) -> u32;
648
649    /// Set the speed in kHz used for communication with the target device.
650    ///
651    /// The desired speed might not be supported by the probe. If the desired
652    /// speed is not directly supported, a lower speed will be selected if possible.
653    ///
654    /// If possible, the actual speed used is returned by the function. Some probes
655    /// cannot report this, so the value may be inaccurate.
656    ///
657    /// If the requested speed is not supported,
658    /// `DebugProbeError::UnsupportedSpeed` will be returned.
659    ///
660    fn set_speed(&mut self, speed_khz: u32) -> Result<u32, DebugProbeError>;
661
662    /// Attach to the chip.
663    ///
664    /// This should run all the necessary protocol init routines.
665    fn attach(&mut self) -> Result<(), DebugProbeError>;
666
667    /// Detach from the chip.
668    ///
669    /// This should run all the necessary protocol deinit routines.
670    ///
671    /// If the probe uses batched commands, this will also cause all
672    /// remaining commands to be executed. If an error occurs during
673    /// this execution, the probe might remain in the attached state.
674    fn detach(&mut self) -> Result<(), crate::Error>;
675
676    /// This should hard reset the target device.
677    fn target_reset(&mut self) -> Result<(), DebugProbeError>;
678
679    /// This should assert the reset pin of the target via debug probe.
680    fn target_reset_assert(&mut self) -> Result<(), DebugProbeError>;
681
682    /// This should deassert the reset pin of the target via debug probe.
683    fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError>;
684
685    /// Selects the transport protocol to be used by the debug probe.
686    fn select_protocol(&mut self, protocol: WireProtocol) -> Result<(), DebugProbeError>;
687
688    /// Get the transport protocol currently in active use by the debug probe.
689    fn active_protocol(&self) -> Option<WireProtocol>;
690
691    /// Check if the probe offers an interface to debug ARM chips.
692    fn has_arm_interface(&self) -> bool {
693        false
694    }
695
696    /// Returns a [`JtagAccess`] from the debug probe, if implemented.
697    fn try_as_jtag_probe(&mut self) -> Option<&mut dyn JtagAccess> {
698        None
699    }
700
701    /// Get the dedicated interface to debug ARM chips. To check that the
702    /// probe actually supports this, call [DebugProbe::has_arm_interface] first.
703    fn try_get_arm_debug_interface<'probe>(
704        self: Box<Self>,
705        _sequence: Arc<dyn ArmDebugSequence>,
706    ) -> Result<Box<dyn ArmDebugInterface + 'probe>, (Box<dyn DebugProbe>, ArmError)> {
707        Err((
708            self.into_probe(),
709            DebugProbeError::InterfaceNotAvailable {
710                interface_name: "ARM",
711            }
712            .into(),
713        ))
714    }
715
716    /// Try to get a [`RiscvInterfaceBuilder`] object, which can be used to set up a communication
717    /// interface with chips using the RISC-V architecture.
718    ///
719    /// Ensure that the probe actually supports this by calling
720    /// [DebugProbe::has_riscv_interface] first.
721    fn try_get_riscv_interface_builder<'probe>(
722        &'probe mut self,
723    ) -> Result<Box<dyn RiscvInterfaceBuilder<'probe> + 'probe>, RiscvError> {
724        Err(DebugProbeError::InterfaceNotAvailable {
725            interface_name: "RISC-V",
726        }
727        .into())
728    }
729
730    /// Check if the probe offers an interface to debug RISC-V chips.
731    fn has_riscv_interface(&self) -> bool {
732        false
733    }
734
735    /// Get the dedicated interface to debug Xtensa chips. Ensure that the
736    /// probe actually supports this by calling [DebugProbe::has_xtensa_interface] first.
737    fn try_get_xtensa_interface<'probe>(
738        &'probe mut self,
739        _state: &'probe mut XtensaDebugInterfaceState,
740    ) -> Result<XtensaCommunicationInterface<'probe>, XtensaError> {
741        Err(DebugProbeError::InterfaceNotAvailable {
742            interface_name: "Xtensa",
743        }
744        .into())
745    }
746
747    /// Check if the probe offers an interface to debug Xtensa chips.
748    fn has_xtensa_interface(&self) -> bool {
749        false
750    }
751
752    /// Get a SWO interface from the debug probe.
753    ///
754    /// This is not available on all debug probes.
755    fn get_swo_interface(&self) -> Option<&dyn SwoAccess> {
756        None
757    }
758
759    /// Get a mutable SWO interface from the debug probe.
760    ///
761    /// This is not available on all debug probes.
762    fn get_swo_interface_mut(&mut self) -> Option<&mut dyn SwoAccess> {
763        None
764    }
765
766    /// Boxes itself.
767    fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe>;
768
769    /// Try creating a DAP interface for the given probe.
770    ///
771    /// This is not available on all probes.
772    fn try_as_dap_probe(&mut self) -> Option<&mut dyn DapProbe> {
773        None
774    }
775
776    /// Reads the target voltage in Volts, if possible. Returns `Ok(None)`
777    /// if the probe doesn’t support reading the target voltage.
778    fn get_target_voltage(&mut self) -> Result<Option<f32>, DebugProbeError> {
779        Ok(None)
780    }
781}
782
783impl PartialEq for dyn ProbeFactory {
784    fn eq(&self, other: &Self) -> bool {
785        // Consider ProbeFactory objects equal when their types and data pointers are equal.
786        // Pointer equality is insufficient, because ZST objects may have the same dangling pointer
787        // as their address.
788        self.type_id() == other.type_id()
789            && std::ptr::eq(
790                self as *const _ as *const (),
791                other as *const _ as *const (),
792            )
793    }
794}
795
796/// Gathers some information about a debug probe which was found during a scan.
797#[derive(Debug, Clone, PartialEq)]
798pub struct DebugProbeInfo {
799    /// The name of the debug probe.
800    pub identifier: String,
801    /// The USB vendor ID of the debug probe.
802    pub vendor_id: u16,
803    /// The USB product ID of the debug probe.
804    pub product_id: u16,
805    /// The serial number of the debug probe.
806    pub serial_number: Option<String>,
807    /// The interface index of the debug probe
808    pub interface: Option<u8>,
809
810    /// This is a composite HID device.
811    pub is_hid_interface: bool,
812
813    /// A reference to the [`ProbeFactory`] that created this info object.
814    probe_factory: &'static dyn ProbeFactory,
815}
816
817impl std::fmt::Display for DebugProbeInfo {
818    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
819        write!(
820            f,
821            "{} -- {:04x}:{:04x}",
822            self.identifier, self.vendor_id, self.product_id,
823        )?;
824
825        if let Some(interface) = self.interface {
826            write!(f, "-{}", interface)?;
827        }
828
829        write!(
830            f,
831            ":{} ({})",
832            self.serial_number.as_deref().unwrap_or(""),
833            self.probe_factory
834        )
835    }
836}
837
838impl DebugProbeInfo {
839    /// Creates a new info struct that uniquely identifies a probe.
840    pub fn new<S: Into<String>>(
841        identifier: S,
842        vendor_id: u16,
843        product_id: u16,
844        serial_number: Option<String>,
845        probe_factory: &'static dyn ProbeFactory,
846        interface: Option<u8>,
847        is_hid_interface: bool,
848    ) -> Self {
849        Self {
850            identifier: identifier.into(),
851            vendor_id,
852            product_id,
853            serial_number,
854            probe_factory,
855            interface,
856            is_hid_interface,
857        }
858    }
859
860    /// Open the probe described by this `DebugProbeInfo`.
861    pub fn open(&self) -> Result<Probe, DebugProbeError> {
862        let selector = DebugProbeSelector::from(self);
863        self.probe_factory
864            .open(&selector)
865            .map(Probe::from_specific_probe)
866    }
867
868    /// Returns whether this info was returned by a particular probe factory.
869    pub fn is_probe_type<F: ProbeFactory>(&self) -> bool {
870        self.probe_factory.type_id() == std::any::TypeId::of::<F>()
871    }
872
873    /// Returns a human-readable string describing the probe type.
874    ///
875    /// The exact contents of the string are unstable, this is intended for human consumption only.
876    pub fn probe_type(&self) -> String {
877        self.probe_factory.to_string()
878    }
879}
880
881/// An error which can occur while parsing a [`DebugProbeSelector`].
882#[derive(thiserror::Error, Debug, docsplay::Display)]
883pub enum DebugProbeSelectorParseError {
884    /// Could not parse VID or PID: {0}
885    ParseInt(#[from] std::num::ParseIntError),
886
887    /// The format of the selector is invalid. Please use a string in the form `VID:PID:<Serial>`, where Serial is optional.
888    Format,
889}
890
891/// A struct to describe the way a probe should be selected.
892///
893/// Construct this from a set of info or from a string. The
894/// string has to be in the format "VID:PID:SERIALNUMBER",
895/// where the serial number is optional, and VID and PID are
896/// parsed as hexadecimal numbers.
897///
898/// If SERIALNUMBER exists (i.e. the selector contains a second color) and is empty,
899/// probe-rs will select probes that have no serial number, or where the serial number is empty.
900///
901/// ## Example:
902///
903/// ```
904/// use std::convert::TryInto;
905/// let selector: probe_rs::probe::DebugProbeSelector = "1942:1337:SERIAL".try_into().unwrap();
906///
907/// assert_eq!(selector.vendor_id, 0x1942);
908/// assert_eq!(selector.product_id, 0x1337);
909/// ```
910#[derive(Debug, Clone, PartialEq, Eq, Hash)]
911pub struct DebugProbeSelector {
912    /// The the USB vendor id of the debug probe to be used.
913    pub vendor_id: u16,
914    /// The the USB product id of the debug probe to be used.
915    pub product_id: u16,
916    /// The the USB interface of the debug probe to be used.
917    pub interface: Option<u8>,
918    /// The the serial number of the debug probe to be used.
919    pub serial_number: Option<String>,
920}
921
922impl DebugProbeSelector {
923    pub(crate) fn matches(&self, info: &DeviceInfo) -> bool {
924        if self.interface.is_some() {
925            info.interfaces().any(|iface| {
926                self.match_probe_selector(
927                    info.vendor_id(),
928                    info.product_id(),
929                    Some(iface.interface_number()),
930                    info.serial_number(),
931                )
932            })
933        } else {
934            self.match_probe_selector(
935                info.vendor_id(),
936                info.product_id(),
937                None,
938                info.serial_number(),
939            )
940        }
941    }
942
943    /// Check if the given probe info matches this selector.
944    pub fn matches_probe(&self, info: &DebugProbeInfo) -> bool {
945        self.match_probe_selector(
946            info.vendor_id,
947            info.product_id,
948            info.interface,
949            info.serial_number.as_deref(),
950        )
951    }
952
953    fn match_probe_selector(
954        &self,
955        vendor_id: u16,
956        product_id: u16,
957        interface: Option<u8>,
958        serial_number: Option<&str>,
959    ) -> bool {
960        tracing::trace!(
961            "Matching probe selector:\nVendor ID: {vendor_id:04x} == {:04x}\nProduct ID: {product_id:04x} = {:04x}\nInterface: {interface:?} == {:?}\nSerial Number: {serial_number:?} == {:?}",
962            self.vendor_id,
963            self.product_id,
964            self.interface,
965            self.serial_number
966        );
967
968        vendor_id == self.vendor_id
969            && product_id == self.product_id
970            && self
971                .interface
972                .map(|iface| interface == Some(iface))
973                .unwrap_or(true) // USB interface not specified by user
974            && self
975                .serial_number
976                .as_ref()
977                .map(|s| {
978                    if let Some(serial_number) = serial_number {
979                        serial_number == s
980                    } else {
981                        // Match probes without serial number when the
982                        // selector has a third, empty part ("VID:PID:")
983                        s.is_empty()
984                    }
985                })
986                .unwrap_or(true)
987    }
988}
989
990impl TryFrom<&str> for DebugProbeSelector {
991    type Error = DebugProbeSelectorParseError;
992    fn try_from(value: &str) -> Result<Self, Self::Error> {
993        // Split into at most 3 parts: VID, PID, Serial.
994        // We limit the number of splits to allow for colons in the
995        // serial number (EspJtag uses MAC address)
996        let mut split = value.splitn(3, ':');
997
998        let vendor_id = split.next().unwrap(); // First split is always successful
999        let mut product_id = split.next().ok_or(DebugProbeSelectorParseError::Format)?;
1000        let interface = if let Some((id, iface)) = product_id.split_once("-") {
1001            product_id = id;
1002            // Matches probes without interface where the selector has minus but no interface number ("VID:PID-")
1003            if iface.is_empty() {
1004                Ok(None)
1005            } else {
1006                iface.parse::<u8>().map(Some)
1007            }
1008        } else {
1009            Ok(None)
1010        }?;
1011        let serial_number = split.next().map(|s| s.to_string());
1012
1013        Ok(DebugProbeSelector {
1014            vendor_id: u16::from_str_radix(vendor_id, 16)?,
1015            product_id: u16::from_str_radix(product_id, 16)?,
1016            serial_number,
1017            interface,
1018        })
1019    }
1020}
1021
1022impl TryFrom<String> for DebugProbeSelector {
1023    type Error = DebugProbeSelectorParseError;
1024    fn try_from(value: String) -> Result<Self, Self::Error> {
1025        TryFrom::<&str>::try_from(&value)
1026    }
1027}
1028
1029impl std::str::FromStr for DebugProbeSelector {
1030    type Err = DebugProbeSelectorParseError;
1031    fn from_str(s: &str) -> Result<Self, Self::Err> {
1032        Self::try_from(s)
1033    }
1034}
1035
1036impl From<DebugProbeInfo> for DebugProbeSelector {
1037    fn from(selector: DebugProbeInfo) -> Self {
1038        DebugProbeSelector {
1039            vendor_id: selector.vendor_id,
1040            product_id: selector.product_id,
1041            serial_number: selector.serial_number,
1042            interface: selector.interface,
1043        }
1044    }
1045}
1046
1047impl From<&DebugProbeInfo> for DebugProbeSelector {
1048    fn from(selector: &DebugProbeInfo) -> Self {
1049        DebugProbeSelector {
1050            vendor_id: selector.vendor_id,
1051            product_id: selector.product_id,
1052            serial_number: selector.serial_number.clone(),
1053            interface: selector.interface,
1054        }
1055    }
1056}
1057
1058impl From<&DebugProbeSelector> for DebugProbeSelector {
1059    fn from(selector: &DebugProbeSelector) -> Self {
1060        selector.clone()
1061    }
1062}
1063
1064impl fmt::Display for DebugProbeSelector {
1065    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1066        write!(f, "{:04x}:{:04x}", self.vendor_id, self.product_id)?;
1067        if let Some(ref sn) = self.serial_number {
1068            write!(f, ":{sn}")?;
1069        }
1070        Ok(())
1071    }
1072}
1073
1074impl From<DebugProbeSelector> for String {
1075    fn from(value: DebugProbeSelector) -> String {
1076        value.to_string()
1077    }
1078}
1079
1080impl Serialize for DebugProbeSelector {
1081    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1082    where
1083        S: Serializer,
1084    {
1085        serializer.serialize_str(&self.to_string())
1086    }
1087}
1088
1089impl<'a> Deserialize<'a> for DebugProbeSelector {
1090    fn deserialize<D>(deserializer: D) -> Result<DebugProbeSelector, D::Error>
1091    where
1092        D: Deserializer<'a>,
1093    {
1094        let s = String::deserialize(deserializer)?;
1095        s.parse().map_err(serde::de::Error::custom)
1096    }
1097}
1098
1099/// Bit-banging interface, ARM edition.
1100///
1101/// This trait (and [RawJtagIo], [JtagAccess]) should not be used by architecture implementations
1102/// directly. Architectures should implement their own protocol interfaces, and use the raw probe
1103/// interfaces (like [RawSwdIo]) to perform the low-level operations AS A FALLBACK. Probes like
1104/// [CmsisDap] should prefer directly implementing the architecture protocols, if they have the
1105/// capability.
1106///
1107/// Currently ARM implements this idea via [crate::architecture::arm::RawDapAccess], which
1108/// is then implemented by [CmsisDap] or a fallback is provided by for
1109/// any [RawSwdIo + JtagAccess](crate::architecture::arm::polyfill) probes.
1110///
1111/// RISC-V is close with its [crate::architecture::riscv::dtm::dtm_access::DtmAccess] trait.
1112///
1113/// [CmsisDap]: crate::probe::cmsisdap::CmsisDap
1114pub(crate) trait RawSwdIo: DebugProbe {
1115    fn swd_io<S>(&mut self, swdio: S) -> Result<Vec<bool>, DebugProbeError>
1116    where
1117        S: IntoIterator<Item = IoSequenceItem>;
1118
1119    fn swj_pins(
1120        &mut self,
1121        pin_out: u32,
1122        pin_select: u32,
1123        pin_wait: u32,
1124    ) -> Result<u32, DebugProbeError>;
1125
1126    fn swd_settings(&self) -> &SwdSettings;
1127
1128    fn probe_statistics(&mut self) -> &mut ProbeStatistics;
1129}
1130
1131/// A trait for implementing low-level JTAG interface operations.
1132pub(crate) trait RawJtagIo: DebugProbe {
1133    /// Returns a mutable reference to the current state.
1134    fn state_mut(&mut self) -> &mut JtagDriverState;
1135
1136    /// Returns the current state.
1137    fn state(&self) -> &JtagDriverState;
1138
1139    /// Shifts a number of bits through the TAP.
1140    fn shift_bits(
1141        &mut self,
1142        tms: impl IntoIterator<Item = bool>,
1143        tdi: impl IntoIterator<Item = bool>,
1144        cap: impl IntoIterator<Item = bool>,
1145    ) -> Result<(), DebugProbeError> {
1146        for ((tms, tdi), cap) in tms.into_iter().zip(tdi.into_iter()).zip(cap.into_iter()) {
1147            self.shift_bit(tms, tdi, cap)?;
1148        }
1149
1150        Ok(())
1151    }
1152
1153    /// Shifts a single bit through the TAP.
1154    ///
1155    /// Drivers may choose, and are encouraged, to buffer bits and flush them
1156    /// in batches for performance reasons.
1157    fn shift_bit(&mut self, tms: bool, tdi: bool, capture: bool) -> Result<(), DebugProbeError>;
1158
1159    /// Returns the bits captured from TDO and clears the capture buffer.
1160    fn read_captured_bits(&mut self) -> Result<BitVec, DebugProbeError>;
1161
1162    /// Resets the JTAG state machine by shifting out a number of high TMS bits.
1163    fn reset_jtag_state_machine(&mut self) -> Result<(), DebugProbeError> {
1164        tracing::debug!("Resetting JTAG chain by setting tms high for 5 bits");
1165
1166        // Reset JTAG chain (5 times TMS high), and enter idle state afterwards
1167        let tms = [true, true, true, true, true, false];
1168        let tdi = std::iter::repeat(true);
1169
1170        self.shift_bits(tms, tdi, std::iter::repeat(false))?;
1171        let response = self.read_captured_bits()?;
1172
1173        tracing::debug!("Response to reset: {response}");
1174
1175        Ok(())
1176    }
1177}
1178
1179#[derive(Debug, Clone, Copy, PartialEq)]
1180pub(crate) enum IoSequenceItem {
1181    Output(bool),
1182    Input,
1183}
1184
1185#[derive(Debug)]
1186pub(crate) struct SwdSettings {
1187    /// Initial number of idle cycles between consecutive writes.
1188    ///
1189    /// When a WAIT response is received, the number of idle cycles
1190    /// will be increased automatically, so this number can be quite
1191    /// low.
1192    pub num_idle_cycles_between_writes: usize,
1193
1194    /// How often a SWD transfer is retried when a WAIT response
1195    /// is received.
1196    pub num_retries_after_wait: usize,
1197
1198    /// When a SWD transfer is retried due to a WAIT response, the idle
1199    /// cycle amount is doubled every time as a backoff. This sets a maximum
1200    /// cap to the cycle amount.
1201    pub max_retry_idle_cycles_after_wait: usize,
1202
1203    /// Number of idle cycles inserted before the result
1204    /// of a write is checked.
1205    ///
1206    /// When performing a write operation, the write can
1207    /// be buffered, meaning that completing the transfer
1208    /// does not mean that the write was performed successfully.
1209    ///
1210    /// To check that all writes have been executed, the
1211    /// `RDBUFF` register can be read from the DP.
1212    ///
1213    /// If any writes are still pending, this read will result in a WAIT response.
1214    /// By adding idle cycles before performing this read, the chance of a
1215    /// WAIT response is smaller.
1216    pub idle_cycles_before_write_verify: usize,
1217
1218    /// Number of idle cycles to insert after a transfer
1219    ///
1220    /// It is recommended that at least 8 idle cycles are
1221    /// inserted.
1222    pub idle_cycles_after_transfer: usize,
1223}
1224
1225impl Default for SwdSettings {
1226    fn default() -> Self {
1227        Self {
1228            num_idle_cycles_between_writes: 2,
1229            num_retries_after_wait: 1000,
1230            max_retry_idle_cycles_after_wait: 128,
1231            idle_cycles_before_write_verify: 8,
1232            idle_cycles_after_transfer: 8,
1233        }
1234    }
1235}
1236
1237/// The state of a bitbanging JTAG driver.
1238///
1239/// This struct tracks the state of the JTAG state machine,  which TAP is currently selected, and
1240/// contains information about the system (like scan chain).
1241#[derive(Debug)]
1242pub(crate) struct JtagDriverState {
1243    pub state: JtagState,
1244    pub expected_scan_chain: Option<Vec<ScanChainElement>>,
1245    pub scan_chain: Vec<ScanChainElement>,
1246    pub chain_params: ChainParams,
1247    /// Idle cycles necessary between consecutive
1248    /// accesses to the DMI register
1249    pub jtag_idle_cycles: usize,
1250}
1251impl JtagDriverState {
1252    fn max_ir_address(&self) -> u32 {
1253        (1 << self.chain_params.irlen) - 1
1254    }
1255}
1256
1257impl Default for JtagDriverState {
1258    fn default() -> Self {
1259        Self {
1260            state: JtagState::Reset,
1261            expected_scan_chain: None,
1262            scan_chain: Vec::new(),
1263            chain_params: ChainParams::default(),
1264            jtag_idle_cycles: 0,
1265        }
1266    }
1267}
1268
1269#[derive(Default, Debug)]
1270pub(crate) struct ProbeStatistics {
1271    /// Number of protocol transfers performed.
1272    ///
1273    /// This includes repeated transfers, and transfers
1274    /// which are automatically added to fulfill
1275    /// protocol requirements, e.g. a read from a
1276    /// DP register will result in two transfers,
1277    /// because the read value is returned in the
1278    /// second transfer
1279    num_transfers: usize,
1280
1281    /// Number of extra transfers added to fullfil protocol
1282    /// requirements. Ideally as low as possible.
1283    num_extra_transfers: usize,
1284
1285    /// Number of calls to the probe IO function.
1286    ///
1287    /// A single call can perform multiple SWD transfers,
1288    /// so this number is ideally a lot lower than then
1289    /// number of SWD transfers.
1290    num_io_calls: usize,
1291
1292    /// Number of SWD wait responses encountered.
1293    num_wait_resp: usize,
1294
1295    /// Number of SWD FAULT responses encountered.
1296    num_faults: usize,
1297}
1298
1299impl ProbeStatistics {
1300    pub fn record_extra_transfer(&mut self) {
1301        self.num_extra_transfers += 1;
1302    }
1303
1304    pub fn record_transfers(&mut self, num_transfers: usize) {
1305        self.num_transfers += num_transfers;
1306    }
1307
1308    pub fn report_io(&mut self) {
1309        self.num_io_calls += 1;
1310    }
1311
1312    pub fn report_swd_response<T>(&mut self, response: &Result<T, DapError>) {
1313        match response {
1314            Err(DapError::FaultResponse) => self.num_faults += 1,
1315            Err(DapError::WaitResponse) => self.num_wait_resp += 1,
1316            // Other errors are not counted right now.
1317            _ => (),
1318        }
1319    }
1320}
1321
1322/// Marker trait for bitbanging JTAG probes.
1323///
1324/// This trait exists to control which probes implement [`JtagAccess`]. In some cases,
1325/// a probe may implement [`RawJtagIo`] but does not want an auto-implemented [JtagAccess].
1326pub(crate) trait AutoImplementJtagAccess: RawJtagIo + 'static {}
1327
1328/// Low-Level access to the JTAG protocol
1329///
1330/// This trait should be implemented by all probes which offer low-level access to
1331/// the JTAG protocol, i.e. direct control over the bytes sent and received.
1332pub trait JtagAccess: DebugProbe {
1333    /// Set the JTAG scan chain information for the target under debug.
1334    ///
1335    /// This allows the probe to know which TAPs are in the scan chain and their
1336    /// position and IR lengths.
1337    ///
1338    /// If the scan chain is provided, and the selected protocol is JTAG, the
1339    /// probe will automatically configure the JTAG interface to match the
1340    /// scan chain configuration without trying to determine the chain at
1341    /// runtime.
1342    ///
1343    /// This is called by the `Session` when attaching to a target.
1344    /// So this does not need to be called manually, unless you want to
1345    /// modify the scan chain. You must be attached to a target to set the
1346    /// scan_chain since the scan chain only applies to the attached target.
1347    fn set_scan_chain(&mut self, scan_chain: &[ScanChainElement]) -> Result<(), DebugProbeError>;
1348
1349    /// Scans `IDCODE` and `IR` length information about the devices on the JTAG chain.
1350    ///
1351    /// If configured, this will use the data from [`Self::set_scan_chain`]. Otherwise, it
1352    /// will try to measure and extract `IR` lengths by driving the JTAG interface.
1353    ///
1354    /// The measured scan chain will be stored in the probe's internal state.
1355    fn scan_chain(&mut self) -> Result<&[ScanChainElement], DebugProbeError>;
1356
1357    /// Shifts a number of bits through the TAP.
1358    fn shift_raw_sequence(&mut self, sequence: JtagSequence) -> Result<BitVec, DebugProbeError>;
1359
1360    /// Executes a TAP reset.
1361    fn tap_reset(&mut self) -> Result<(), DebugProbeError>;
1362
1363    /// For RISC-V, and possibly other interfaces, the JTAG interface has to remain in
1364    /// the idle state for several cycles between consecutive accesses to the DR register.
1365    ///
1366    /// This function configures the number of idle cycles which are inserted after each access.
1367    fn set_idle_cycles(&mut self, idle_cycles: u8) -> Result<(), DebugProbeError>;
1368
1369    /// Return the currently configured idle cycles.
1370    fn idle_cycles(&self) -> u8;
1371
1372    /// Selects the JTAG TAP to be used for communication.
1373    ///
1374    /// The index is the position of the TAP in the scan chain, which can
1375    /// be configured using [`set_scan_chain()`](JtagAccess::set_scan_chain()).
1376    fn select_target(&mut self, index: usize) -> Result<(), DebugProbeError> {
1377        if index != 0 {
1378            return Err(DebugProbeError::NotImplemented {
1379                function_name: "select_jtag_tap",
1380            });
1381        }
1382
1383        Ok(())
1384    }
1385
1386    /// Read a JTAG register.
1387    ///
1388    /// This function emulates a read by performing a write with all zeros to the DR.
1389    fn read_register(&mut self, address: u32, len: u32) -> Result<BitVec, DebugProbeError> {
1390        let data = vec![0u8; len.div_ceil(8) as usize];
1391
1392        self.write_register(address, &data, len)
1393    }
1394
1395    /// Write to a JTAG register
1396    ///
1397    /// This function will perform a write to the IR register, if necessary,
1398    /// to select the correct register, and then to the DR register, to transmit the
1399    /// data. The data shifted out of the DR register will be returned.
1400    fn write_register(
1401        &mut self,
1402        address: u32,
1403        data: &[u8],
1404        len: u32,
1405    ) -> Result<BitVec, DebugProbeError>;
1406
1407    /// Shift a value into the DR JTAG register
1408    ///
1409    /// The data shifted out of the DR register will be returned.
1410    fn write_dr(&mut self, data: &[u8], len: u32) -> Result<BitVec, DebugProbeError>;
1411
1412    /// Executes a sequence of JTAG commands.
1413    fn write_register_batch(
1414        &mut self,
1415        writes: &CommandQueue<JtagCommand>,
1416    ) -> Result<DeferredResultSet<CommandResult>, BatchExecutionError> {
1417        tracing::debug!(
1418            "Using default `JtagAccess::write_register_batch` hurts performance. Please implement proper batching for this probe."
1419        );
1420        let mut results = DeferredResultSet::new();
1421
1422        for (idx, write) in writes.iter() {
1423            match write {
1424                JtagCommand::WriteRegister(write) => {
1425                    match self
1426                        .write_register(write.address, &write.data, write.len)
1427                        .map_err(crate::Error::Probe)
1428                        .and_then(|response| (write.transform)(write, &response))
1429                    {
1430                        Ok(res) => results.push(idx, res),
1431                        Err(e) => return Err(BatchExecutionError::new(e, results)),
1432                    }
1433                }
1434
1435                JtagCommand::ShiftDr(write) => {
1436                    match self
1437                        .write_dr(&write.data, write.len)
1438                        .map_err(crate::Error::Probe)
1439                        .and_then(|response| (write.transform)(write, &response))
1440                    {
1441                        Ok(res) => results.push(idx, res),
1442                        Err(e) => return Err(BatchExecutionError::new(e, results)),
1443                    }
1444                }
1445            }
1446        }
1447
1448        Ok(results)
1449    }
1450}
1451
1452/// A raw JTAG bit sequence.
1453pub struct JtagSequence {
1454    /// TDO capture
1455    pub tdo_capture: bool,
1456
1457    /// TMS value
1458    pub tms: bool,
1459
1460    /// Data to generate on TDI
1461    pub data: BitVec,
1462}
1463
1464/// A low-level JTAG register write command.
1465#[derive(Debug, Clone)]
1466pub struct JtagWriteCommand {
1467    /// The IR register to write to.
1468    pub address: u32,
1469
1470    /// The data to be written to DR.
1471    pub data: Vec<u8>,
1472
1473    /// The number of bits in `data`
1474    pub len: u32,
1475
1476    /// A function to transform the raw response into a [`CommandResult`]
1477    pub transform: fn(&JtagWriteCommand, &BitSlice) -> Result<CommandResult, crate::Error>,
1478}
1479
1480/// A low-level JTAG register write command.
1481#[derive(Debug, Clone)]
1482pub struct ShiftDrCommand {
1483    /// The data to be written to DR.
1484    pub data: Vec<u8>,
1485
1486    /// The number of bits in `data`
1487    pub len: u32,
1488
1489    /// A function to transform the raw response into a [`CommandResult`]
1490    pub transform: fn(&ShiftDrCommand, &BitSlice) -> Result<CommandResult, crate::Error>,
1491}
1492
1493/// A low-level JTAG command.
1494#[derive(Debug, Clone)]
1495pub enum JtagCommand {
1496    /// Write a register.
1497    WriteRegister(JtagWriteCommand),
1498    /// Shift a value into the DR register.
1499    ShiftDr(ShiftDrCommand),
1500}
1501
1502impl From<JtagWriteCommand> for JtagCommand {
1503    fn from(cmd: JtagWriteCommand) -> Self {
1504        JtagCommand::WriteRegister(cmd)
1505    }
1506}
1507
1508impl From<ShiftDrCommand> for JtagCommand {
1509    fn from(cmd: ShiftDrCommand) -> Self {
1510        JtagCommand::ShiftDr(cmd)
1511    }
1512}
1513
1514/// Chain parameters to select a target tap within the chain.
1515#[derive(Clone, Copy, Debug, Default)]
1516pub(crate) struct ChainParams {
1517    pub index: usize,
1518    pub irpre: usize,
1519    pub irpost: usize,
1520    pub drpre: usize,
1521    pub drpost: usize,
1522    pub irlen: usize,
1523}
1524
1525impl ChainParams {
1526    fn from_jtag_chain(chain: &[ScanChainElement], selected: usize) -> Option<Self> {
1527        let mut params = Self {
1528            index: selected,
1529            ..Default::default()
1530        };
1531        let mut found = false;
1532        for (index, tap) in chain.iter().enumerate() {
1533            let ir_len = tap.ir_len() as usize;
1534            if index == selected {
1535                params.irlen = ir_len;
1536                found = true;
1537            } else if found {
1538                params.irpost += ir_len;
1539                params.drpost += 1;
1540            } else {
1541                params.irpre += ir_len;
1542                params.drpre += 1;
1543            }
1544        }
1545
1546        found.then_some(params)
1547    }
1548}
1549
1550/// An error that occurred during batched command execution of JTAG commands.
1551#[derive(thiserror::Error, Debug)]
1552pub struct BatchExecutionError {
1553    /// The error that occurred during execution.
1554    #[source]
1555    pub error: crate::Error,
1556
1557    /// The results of the commands that were executed before the error occurred.
1558    pub results: DeferredResultSet<CommandResult>,
1559}
1560
1561impl BatchExecutionError {
1562    pub(crate) fn new(
1563        error: crate::Error,
1564        results: DeferredResultSet<CommandResult>,
1565    ) -> BatchExecutionError {
1566        BatchExecutionError { error, results }
1567    }
1568}
1569
1570impl std::fmt::Display for BatchExecutionError {
1571    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1572        write!(
1573            f,
1574            "Error cause was {}. Successful command count {}",
1575            self.error,
1576            self.results.len()
1577        )
1578    }
1579}
1580
1581/// Results generated by `JtagCommand`s
1582#[derive(Debug, Clone)]
1583pub enum CommandResult {
1584    /// No result
1585    None,
1586
1587    /// A single byte
1588    U8(u8),
1589
1590    /// A single 16-bit word
1591    U16(u16),
1592
1593    /// A single 32-bit word
1594    U32(u32),
1595
1596    /// Multiple bytes
1597    VecU8(Vec<u8>),
1598}
1599
1600impl CommandResult {
1601    /// Returns the result as a `u32` if possible.
1602    ///
1603    /// # Panics
1604    ///
1605    /// Panics if the result is not a `u32`.
1606    pub fn into_u32(self) -> u32 {
1607        match self {
1608            CommandResult::U32(val) => val,
1609            _ => panic!("CommandResult is not a u32"),
1610        }
1611    }
1612
1613    /// Returns the result as a `u8` if possible.
1614    ///
1615    /// # Panics
1616    ///
1617    /// Panics if the result is not a `u8`.
1618    pub fn into_u8(self) -> u8 {
1619        match self {
1620            CommandResult::U8(val) => val,
1621            _ => panic!("CommandResult is not a u8"),
1622        }
1623    }
1624}
1625
1626/// A set of batched commands that will be executed all at once.
1627///
1628/// This list maintains which commands' results can be read by the issuing code, which then
1629/// can be used to skip capturing or processing certain parts of the response.
1630pub struct CommandQueue<T> {
1631    commands: Vec<(DeferredResultIndex, T)>,
1632    cursor: usize,
1633}
1634
1635impl<T: std::fmt::Debug> std::fmt::Debug for CommandQueue<T> {
1636    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1637        f.debug_struct("CommandQueue")
1638            .field("commands", &self.len())
1639            .finish()
1640    }
1641}
1642
1643impl<T> Default for CommandQueue<T> {
1644    fn default() -> Self {
1645        Self {
1646            commands: Vec::new(),
1647            cursor: 0,
1648        }
1649    }
1650}
1651
1652impl<T> CommandQueue<T> {
1653    /// Creates a new empty queue.
1654    pub fn new() -> Self {
1655        Self::default()
1656    }
1657
1658    /// Schedules a command for later execution.
1659    ///
1660    /// Returns a token value that can be used to retrieve the result of the command.
1661    pub fn schedule(&mut self, command: impl Into<T>) -> DeferredResultIndex {
1662        let index = DeferredResultIndex::new();
1663        self.commands.push((index.clone(), command.into()));
1664        index
1665    }
1666
1667    /// Returns the number of commands in the queue.
1668    pub fn len(&self) -> usize {
1669        self.commands[self.cursor..].len()
1670    }
1671
1672    /// Returns whether the queue is empty.
1673    pub fn is_empty(&self) -> bool {
1674        self.len() == 0
1675    }
1676
1677    pub(crate) fn iter(&self) -> impl Iterator<Item = &(DeferredResultIndex, T)> {
1678        self.commands[self.cursor..].iter()
1679    }
1680
1681    /// Rewinds the cursor by the specified number of commands.
1682    ///
1683    /// Returns `true` if the cursor was successfully rewound, `false` if more commands were requested than available.
1684    pub(crate) fn rewind(&mut self, by: usize) -> bool {
1685        if self.cursor >= by {
1686            self.cursor -= by;
1687            true
1688        } else {
1689            false
1690        }
1691    }
1692
1693    /// Removes the first `len` number of commands from the batch.
1694    pub(crate) fn consume(&mut self, len: usize) {
1695        debug_assert!(self.len() >= len);
1696        self.cursor += len;
1697    }
1698}
1699
1700/// The set of results returned by executing a batched command.
1701pub struct DeferredResultSet<T>(HashMap<DeferredResultIndex, T>);
1702
1703impl<T: std::fmt::Debug> std::fmt::Debug for DeferredResultSet<T> {
1704    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1705        f.debug_tuple("DeferredResultSet").field(&self.0).finish()
1706    }
1707}
1708
1709impl<T> Default for DeferredResultSet<T> {
1710    fn default() -> Self {
1711        Self(HashMap::default())
1712    }
1713}
1714
1715impl<T> DeferredResultSet<T> {
1716    /// Creates a new empty result set.
1717    pub fn new() -> Self {
1718        Self::default()
1719    }
1720
1721    /// Creates a new empty result set with the given capacity.
1722    pub fn with_capacity(capacity: usize) -> Self {
1723        Self(HashMap::with_capacity(capacity))
1724    }
1725
1726    pub(crate) fn push(&mut self, idx: &DeferredResultIndex, result: T) {
1727        self.0.insert(idx.clone(), result);
1728    }
1729
1730    /// Returns the number of results in the set.
1731    pub fn len(&self) -> usize {
1732        self.0.len()
1733    }
1734
1735    /// Returns whether the set is empty.
1736    pub fn is_empty(&self) -> bool {
1737        self.0.is_empty()
1738    }
1739
1740    pub(crate) fn merge_from(&mut self, other: DeferredResultSet<T>) {
1741        self.0.extend(other.0);
1742        self.0.retain(|k, _| k.should_capture());
1743    }
1744
1745    /// Takes a result from the set.
1746    pub fn take(&mut self, index: DeferredResultIndex) -> Result<T, DeferredResultIndex> {
1747        self.0.remove(&index).ok_or(index)
1748    }
1749}
1750
1751/// An index type used to retrieve the result of a deferred command.
1752///
1753/// This type can detect if the result of a command is not used.
1754#[derive(Eq)]
1755pub struct DeferredResultIndex(Arc<()>);
1756
1757impl PartialEq for DeferredResultIndex {
1758    fn eq(&self, other: &Self) -> bool {
1759        Arc::ptr_eq(&self.0, &other.0)
1760    }
1761}
1762
1763impl fmt::Debug for DeferredResultIndex {
1764    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1765        f.debug_tuple("DeferredResultIndex")
1766            .field(&self.id())
1767            .finish()
1768    }
1769}
1770
1771impl DeferredResultIndex {
1772    // Intentionally private. User code must not be able to create these.
1773    fn new() -> Self {
1774        Self(Arc::new(()))
1775    }
1776
1777    fn id(&self) -> usize {
1778        Arc::as_ptr(&self.0) as usize
1779    }
1780
1781    pub(crate) fn should_capture(&self) -> bool {
1782        // Both the queue and the user code may hold on to at most one of the references. The queue
1783        // execution will be able to detect if the user dropped their read reference, meaning
1784        // the read data would be inaccessible.
1785        Arc::strong_count(&self.0) > 1
1786    }
1787
1788    // Intentionally private. User code must not be able to clone these.
1789    fn clone(&self) -> Self {
1790        Self(self.0.clone())
1791    }
1792}
1793
1794impl std::hash::Hash for DeferredResultIndex {
1795    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1796        self.id().hash(state)
1797    }
1798}
1799
1800/// The method that should be used for attaching.
1801#[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Serialize, Deserialize)]
1802pub enum AttachMethod {
1803    /// Attach normally with no special behavior.
1804    #[default]
1805    Normal,
1806    /// Attach to the target while it is in reset.
1807    ///
1808    /// This is required on targets that can remap SWD pins or disable the SWD interface in sleep.
1809    UnderReset,
1810}
1811
1812#[cfg(test)]
1813mod test {
1814    use super::*;
1815
1816    #[test]
1817    fn test_is_probe_factory() {
1818        let probe_info = DebugProbeInfo::new(
1819            "Mock probe",
1820            0x12,
1821            0x23,
1822            Some("mock_serial".to_owned()),
1823            &ftdi::FtdiProbeFactory,
1824            None,
1825            false,
1826        );
1827
1828        assert!(probe_info.is_probe_type::<ftdi::FtdiProbeFactory>());
1829        assert!(!probe_info.is_probe_type::<espusbjtag::EspUsbJtagFactory>());
1830    }
1831
1832    #[test]
1833    fn test_parsing_many_colons() {
1834        let selector: DebugProbeSelector = "303a:1001:DC:DA:0C:D3:FE:D8".try_into().unwrap();
1835
1836        assert_eq!(selector.vendor_id, 0x303a);
1837        assert_eq!(selector.product_id, 0x1001);
1838        assert_eq!(
1839            selector.serial_number,
1840            Some("DC:DA:0C:D3:FE:D8".to_string())
1841        );
1842    }
1843
1844    #[test]
1845    fn missing_serial_is_none() {
1846        let selector: DebugProbeSelector = "303a:1001".try_into().unwrap();
1847
1848        assert_eq!(selector.vendor_id, 0x303a);
1849        assert_eq!(selector.product_id, 0x1001);
1850        assert_eq!(selector.serial_number, None);
1851
1852        let matches = selector.match_probe_selector(0x303a, 0x1001, None, None);
1853        let matches_with_serial =
1854            selector.match_probe_selector(0x303a, 0x1001, None, Some("serial"));
1855        assert!(matches);
1856        assert!(matches_with_serial);
1857    }
1858
1859    #[test]
1860    fn empty_serial_is_some() {
1861        let selector: DebugProbeSelector = "303a:1001:".try_into().unwrap();
1862
1863        assert_eq!(selector.vendor_id, 0x303a);
1864        assert_eq!(selector.product_id, 0x1001);
1865        assert_eq!(selector.serial_number, Some(String::new()));
1866
1867        let matches = selector.match_probe_selector(0x303a, 0x1001, None, None);
1868        let matches_with_serial =
1869            selector.match_probe_selector(0x303a, 0x1001, None, Some("serial"));
1870        assert!(matches);
1871        assert!(!matches_with_serial);
1872    }
1873
1874    #[test]
1875    fn missing_interface_is_none() {
1876        let selector: DebugProbeSelector = "303a:1001".try_into().unwrap();
1877
1878        assert_eq!(selector.vendor_id, 0x303a);
1879        assert_eq!(selector.product_id, 0x1001);
1880        assert_eq!(selector.interface, None);
1881
1882        let matches = selector.match_probe_selector(0x303a, 0x1001, None, None);
1883        let matches_with_interface = selector.match_probe_selector(0x303a, 0x1001, Some(0), None);
1884        assert!(matches);
1885        assert!(matches_with_interface);
1886    }
1887
1888    #[test]
1889    fn empty_interface_is_none() {
1890        let selector: DebugProbeSelector = "303a:1001-".try_into().unwrap();
1891
1892        assert_eq!(selector.vendor_id, 0x303a);
1893        assert_eq!(selector.product_id, 0x1001);
1894        assert_eq!(selector.interface, None);
1895
1896        let matches = selector.match_probe_selector(0x303a, 0x1001, None, None);
1897        let matches_with_interface = selector.match_probe_selector(0x303a, 0x1001, Some(0), None);
1898        assert!(matches);
1899        assert!(matches_with_interface);
1900    }
1901
1902    #[test]
1903    fn set_interface_matches() {
1904        let selector: DebugProbeSelector = "303a:1001-0".try_into().unwrap();
1905
1906        assert_eq!(selector.vendor_id, 0x303a);
1907        assert_eq!(selector.product_id, 0x1001);
1908        assert_eq!(selector.interface, Some(0));
1909
1910        let no_match = selector.match_probe_selector(0x303a, 0x1001, None, None);
1911        let matches_with_interface = selector.match_probe_selector(0x303a, 0x1001, Some(0), None);
1912        let no_match_with_wrong_interface =
1913            selector.match_probe_selector(0x303a, 0x1001, Some(1), None);
1914        assert!(!no_match);
1915        assert!(matches_with_interface);
1916        assert!(!no_match_with_wrong_interface);
1917    }
1918}