probe_rs/probe/ch347usbjtag/
mod.rs1mod protocol;
3
4use protocol::Ch347UsbJtagDevice;
5
6use crate::{
7 architecture::{
8 arm::{ArmCommunicationInterface, communication_interface::DapProbe},
9 riscv::dtm::jtag_dtm::JtagDtmBuilder,
10 xtensa::communication_interface::XtensaCommunicationInterface,
11 },
12 probe::{DebugProbe, ProbeFactory},
13};
14
15use super::{
16 AutoImplementJtagAccess, DebugProbeError, IoSequenceItem, JtagDriverState, ProbeStatistics,
17 RawJtagIo, RawSwdIo, SwdSettings,
18};
19
20#[derive(Debug)]
22pub struct Ch347UsbJtagFactory;
23
24impl std::fmt::Display for Ch347UsbJtagFactory {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.write_str("Ch347UsbJtag")
27 }
28}
29
30#[derive(Debug)]
32pub struct Ch347UsbJtag {
33 device: Ch347UsbJtagDevice,
34 jtag_state: JtagDriverState,
35 probe_statistics: ProbeStatistics,
36 swd_settings: SwdSettings,
37}
38
39impl ProbeFactory for Ch347UsbJtagFactory {
40 fn open(
41 &self,
42 selector: &super::DebugProbeSelector,
43 ) -> Result<Box<dyn super::DebugProbe>, super::DebugProbeError> {
44 let ch347 = Ch347UsbJtagDevice::new_from_selector(selector)?;
45
46 tracing::info!("Found ch347 device");
47 Ok(Box::new(Ch347UsbJtag {
48 device: ch347,
49 jtag_state: JtagDriverState::default(),
50 probe_statistics: ProbeStatistics::default(),
51 swd_settings: SwdSettings::default(),
52 }))
53 }
54
55 fn list_probes(&self) -> Vec<super::DebugProbeInfo> {
56 protocol::list_ch347usbjtag_devices()
57 }
58}
59
60impl RawJtagIo for Ch347UsbJtag {
61 fn shift_bit(
62 &mut self,
63 tms: bool,
64 tdi: bool,
65 capture: bool,
66 ) -> Result<(), super::DebugProbeError> {
67 self.jtag_state.state.update(tms);
68 self.device.shift_bit(tms, tdi, capture)?;
69
70 Ok(())
71 }
72
73 fn read_captured_bits(&mut self) -> Result<bitvec::prelude::BitVec, super::DebugProbeError> {
74 self.device.read_captured_bits()
75 }
76
77 fn state_mut(&mut self) -> &mut JtagDriverState {
78 &mut self.jtag_state
79 }
80
81 fn state(&self) -> &JtagDriverState {
82 &self.jtag_state
83 }
84}
85
86impl RawSwdIo for Ch347UsbJtag {
87 fn swd_io<S>(&mut self, _swdio: S) -> Result<Vec<bool>, DebugProbeError>
88 where
89 S: IntoIterator<Item = IoSequenceItem>,
90 {
91 Err(DebugProbeError::NotImplemented {
92 function_name: "swd_io",
93 })
94 }
95
96 fn swj_pins(
97 &mut self,
98 _pin_out: u32,
99 _pin_select: u32,
100 _pin_wait: u32,
101 ) -> Result<u32, DebugProbeError> {
102 Err(DebugProbeError::CommandNotSupportedByProbe {
103 command_name: "swj_pins",
104 })
105 }
106
107 fn swd_settings(&self) -> &SwdSettings {
108 &self.swd_settings
109 }
110
111 fn probe_statistics(&mut self) -> &mut ProbeStatistics {
112 &mut self.probe_statistics
113 }
114}
115
116impl AutoImplementJtagAccess for Ch347UsbJtag {}
117impl DapProbe for Ch347UsbJtag {}
118
119impl DebugProbe for Ch347UsbJtag {
120 fn get_name(&self) -> &str {
121 "CH347 USB Jtag"
122 }
123
124 fn speed_khz(&self) -> u32 {
125 self.device.speed_khz()
126 }
127
128 fn set_speed(&mut self, speed_khz: u32) -> Result<u32, super::DebugProbeError> {
129 Ok(self.device.set_speed_khz(speed_khz))
130 }
131
132 fn attach(&mut self) -> Result<(), super::DebugProbeError> {
133 self.device.attach()
134 }
135
136 fn detach(&mut self) -> Result<(), crate::Error> {
137 Ok(())
138 }
139
140 fn target_reset(&mut self) -> Result<(), super::DebugProbeError> {
141 Err(DebugProbeError::NotImplemented {
143 function_name: "target_reset",
144 })
145 }
146 fn target_reset_assert(&mut self) -> Result<(), super::DebugProbeError> {
147 Err(DebugProbeError::NotImplemented {
149 function_name: "target_reset_assert",
150 })
151 }
152
153 fn target_reset_deassert(&mut self) -> Result<(), super::DebugProbeError> {
154 Err(DebugProbeError::NotImplemented {
156 function_name: "target_reset_deassert",
157 })
158 }
159
160 fn select_protocol(
161 &mut self,
162 protocol: super::WireProtocol,
163 ) -> Result<(), super::DebugProbeError> {
164 if protocol != super::WireProtocol::Jtag {
167 Err(DebugProbeError::UnsupportedProtocol(protocol))
168 } else {
169 Ok(())
170 }
171 }
172
173 fn active_protocol(&self) -> Option<super::WireProtocol> {
174 Some(super::WireProtocol::Jtag)
176 }
177
178 fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
179 self
180 }
181
182 fn try_as_jtag_probe(&mut self) -> Option<&mut dyn super::JtagAccess> {
183 Some(self)
184 }
185
186 fn has_arm_interface(&self) -> bool {
187 true
188 }
189
190 fn try_get_arm_debug_interface<'probe>(
191 self: Box<Self>,
192 sequence: std::sync::Arc<dyn crate::architecture::arm::sequences::ArmDebugSequence>,
193 ) -> Result<
194 Box<dyn crate::architecture::arm::ArmDebugInterface + 'probe>,
195 (Box<dyn DebugProbe>, crate::architecture::arm::ArmError),
196 > {
197 Ok(ArmCommunicationInterface::create(self, sequence, true))
198 }
199
200 fn has_riscv_interface(&self) -> bool {
201 true
202 }
203
204 fn try_get_riscv_interface_builder<'probe>(
205 &'probe mut self,
206 ) -> Result<
207 Box<
208 dyn crate::architecture::riscv::communication_interface::RiscvInterfaceBuilder<'probe>
209 + 'probe,
210 >,
211 crate::architecture::riscv::communication_interface::RiscvError,
212 > {
213 Ok(Box::new(JtagDtmBuilder::new(self)))
214 }
215
216 fn has_xtensa_interface(&self) -> bool {
217 true
218 }
219
220 fn try_get_xtensa_interface<'probe>(
221 &'probe mut self,
222 state: &'probe mut crate::architecture::xtensa::communication_interface::XtensaDebugInterfaceState,
223 ) -> Result<
224 crate::architecture::xtensa::communication_interface::XtensaCommunicationInterface<'probe>,
225 crate::architecture::xtensa::communication_interface::XtensaError,
226 > {
227 Ok(XtensaCommunicationInterface::new(self, state))
228 }
229}