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