android_usb_serial/drivers/
ch34x.rs1use super::{Driver, EndpointPair, ModemStatus, WRITE_TIMEOUT_MS};
4use crate::config::{DataBits, FlowControl, LineConfig, Parity, PurgeKind, StopBits};
5use crate::error::{Result, UsbSerialError};
6use crate::reader::SerialReader;
7use crate::transport::{ControlRequest, SharedTransport};
8
9const LCR_ENABLE_RX: u16 = 0x80;
10const LCR_ENABLE_TX: u16 = 0x40;
11const LCR_MARK_SPACE: u16 = 0x20;
12const LCR_PAR_EVEN: u16 = 0x10;
13const LCR_ENABLE_PAR: u16 = 0x08;
14const LCR_STOP_BITS_2: u16 = 0x04;
15const LCR_CS8: u16 = 0x03;
16const LCR_CS7: u16 = 0x02;
17const LCR_CS6: u16 = 0x01;
18const LCR_CS5: u16 = 0x00;
19
20const GCL_CTS: u8 = 0x01;
21const GCL_DSR: u8 = 0x02;
22const GCL_RI: u8 = 0x04;
23const GCL_CD: u8 = 0x08;
24const SCL_DTR: u16 = 0x20;
25const SCL_RTS: u16 = 0x40;
26
27const DEFAULT_BAUD_RATE: u32 = 9600;
28
29pub struct Ch34xDriver {
30 #[allow(dead_code)]
31 port_index: usize,
32 iface: u8,
33 dtr: bool,
34 rts: bool,
35 endpoints: Option<EndpointPair>,
36 transport: Option<SharedTransport>,
37 reader: Option<SerialReader>,
38}
39
40impl Ch34xDriver {
41 pub fn new(port_index: usize) -> Self {
42 Self {
43 port_index,
44 iface: 0,
45 dtr: false,
46 rts: false,
47 endpoints: None,
48 transport: None,
49 reader: None,
50 }
51 }
52
53 fn vendor_out(&self, request: u8, value: u16, index: u16) -> Result<()> {
54 self.transport
55 .as_ref()
56 .unwrap()
57 .control_out(&ControlRequest {
58 request_type: 0x40,
59 request,
60 value,
61 index,
62 data: vec![],
63 timeout_ms: WRITE_TIMEOUT_MS,
64 })
65 .map(|_| ())
66 }
67
68 fn vendor_in(&self, request: u8, value: u16, index: u16, len: usize) -> Result<Vec<u8>> {
69 self.transport
70 .as_ref()
71 .unwrap()
72 .control_in(&ControlRequest::vendor_in(request, value, index, len))
73 }
74
75 fn check_state(&self, request: u8, value: u16, expected: &[Option<u8>]) -> Result<()> {
76 let buf = self.vendor_in(request, value, 0, expected.len())?;
77 if buf.len() != expected.len() {
78 return Err(UsbSerialError::Io(format!(
79 "checkState: expected {} bytes, got {}",
80 expected.len(),
81 buf.len()
82 )));
83 }
84 for (i, exp) in expected.iter().enumerate() {
85 if let Some(want) = exp {
86 if buf[i] != *want {
87 return Err(UsbSerialError::Io(format!(
88 "checkState byte[{i}]: expected 0x{want:02x}, got 0x{:02x}",
89 buf[i]
90 )));
91 }
92 }
93 }
94 Ok(())
95 }
96
97 fn get_status(&self) -> Result<u8> {
98 let buf = self.vendor_in(0x95, 0x0706, 0, 2)?;
99 Ok(buf[0])
100 }
101}
102
103impl Driver for Ch34xDriver {
104 fn open(&mut self, transport: &SharedTransport) -> Result<()> {
105 self.transport = Some(transport.clone());
106 for iface in transport.interfaces() {
107 transport.claim_interface(iface.id)?;
108 }
109 self.iface = transport.interfaces().last().map(|i| i.id).unwrap_or(0);
110 self.endpoints = Some(EndpointPair::open(transport, self.iface)?);
111 self.initialize()?;
112 self.set_baud(DEFAULT_BAUD_RATE)?;
113 Ok(())
114 }
115
116 fn close(&mut self) -> Result<()> {
117 if let Some(mut r) = self.reader.take() {
118 r.stop();
119 }
120 if let Some(t) = &self.transport {
121 for iface in t.interfaces() {
122 let _ = t.release_interface(iface.id);
123 }
124 }
125 self.endpoints = None;
126 Ok(())
127 }
128
129 fn write(&mut self, data: &[u8]) -> Result<usize> {
130 let t = self.transport.as_ref().unwrap();
131 self.endpoints.as_mut().unwrap().write(t, data)
132 }
133
134 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
135 if let Some(reader) = &mut self.reader {
136 return reader.try_read(buf);
137 }
138 Ok(0)
139 }
140
141 fn set_line_config(&mut self, cfg: LineConfig) -> Result<()> {
142 if cfg.baud_rate == 0 {
143 return Err(UsbSerialError::Unsupported("invalid baud rate".into()));
144 }
145 self.set_baud(cfg.baud_rate)?;
146
147 let mut lcr = LCR_ENABLE_RX | LCR_ENABLE_TX;
148 lcr |= match cfg.data_bits {
149 DataBits::Five => LCR_CS5,
150 DataBits::Six => LCR_CS6,
151 DataBits::Seven => LCR_CS7,
152 DataBits::Eight => LCR_CS8,
153 };
154 if cfg.stop_bits == StopBits::Two {
155 lcr |= LCR_STOP_BITS_2;
156 } else if cfg.stop_bits == StopBits::OnePointFive {
157 return Err(UsbSerialError::Unsupported("stop bits 1.5".into()));
158 }
159 lcr |= match cfg.parity {
160 Parity::None => 0,
161 Parity::Odd => LCR_ENABLE_PAR,
162 Parity::Even => LCR_ENABLE_PAR | LCR_PAR_EVEN,
163 Parity::Mark => LCR_ENABLE_PAR | LCR_MARK_SPACE,
164 Parity::Space => LCR_ENABLE_PAR | LCR_MARK_SPACE | LCR_PAR_EVEN,
165 };
166 self.vendor_out(0x9A, 0x2518, lcr)
167 }
168
169 fn set_flow_control(&mut self, flow: FlowControl) -> Result<()> {
170 if flow == FlowControl::None {
171 Ok(())
172 } else {
173 Err(UsbSerialError::Unsupported("flow control".into()))
174 }
175 }
176
177 fn set_dtr(&mut self, value: bool) -> Result<()> {
178 self.dtr = value;
179 self.set_control_lines()
180 }
181
182 fn set_rts(&mut self, value: bool) -> Result<()> {
183 self.rts = value;
184 self.set_control_lines()
185 }
186
187 fn set_break(&mut self, enabled: bool) -> Result<()> {
188 let mut req = self.vendor_in(0x95, 0x1805, 0, 2)?;
189 if enabled {
190 req[0] &= !1;
191 req[1] &= !0x40;
192 } else {
193 req[0] |= 1;
194 req[1] |= 0x40;
195 }
196 let val = ((req[1] as u16) << 8) | (req[0] as u16);
197 self.vendor_out(0x9A, 0x1805, val)
198 }
199
200 fn purge(&mut self, _kind: PurgeKind) -> Result<()> {
201 Ok(())
202 }
203
204 fn modem_status(&mut self) -> Result<ModemStatus> {
205 let status = self.get_status()?;
206 Ok(ModemStatus {
207 cts: (status & GCL_CTS) == 0,
208 dsr: (status & GCL_DSR) == 0,
209 ri: (status & GCL_RI) == 0,
210 cd: (status & GCL_CD) == 0,
211 })
212 }
213
214 fn bulk_in_mps(&self) -> u16 {
215 self.endpoints.as_ref().map(|e| e.mps).unwrap_or(64)
216 }
217
218 fn take_bulk_in(&mut self) -> Option<Box<dyn crate::transport::BulkIn>> {
219 let transport = self.transport.as_ref()?;
220 self.endpoints.as_mut()?.take_in(transport)
221 }
222}
223
224impl Ch34xDriver {
225 fn initialize(&self) -> Result<()> {
226 self.check_state(0x5F, 0, &[None, Some(0x00)])?;
227 self.vendor_out(0xA1, 0, 0)?;
228 self.set_baud(DEFAULT_BAUD_RATE)?;
229 self.check_state(0x95, 0x2518, &[None, Some(0x00)])?;
230 self.vendor_out(0x9A, 0x2518, LCR_ENABLE_RX | LCR_ENABLE_TX | LCR_CS8)?;
231 self.check_state(0x95, 0x0706, &[None, None])?;
232 self.vendor_out(0xA1, 0x501F, 0xD90A)?;
233 self.set_baud(DEFAULT_BAUD_RATE)?;
234 self.set_control_lines()?;
235 self.check_state(0x95, 0x0706, &[None, None])?;
236 Ok(())
237 }
238
239 fn set_baud(&self, baud: u32) -> Result<()> {
240 let (val1, val2) = if baud == 921_600 {
241 let divisor = 7u16 | 0x0080;
242 let factor = 0xF300u16;
243 let val1 = (factor & 0xFF00) | divisor;
244 let val2 = factor & 0xFF;
245 (val1, val2)
246 } else {
247 const BAUDBASE_FACTOR: u64 = 1_532_620_800;
248 const BAUDBASE_DIVMAX: u32 = 3;
249
250 let mut factor = BAUDBASE_FACTOR / baud as u64;
251 let mut divisor = BAUDBASE_DIVMAX;
252 while factor > 0xfff0 && divisor > 0 {
253 factor >>= 3;
254 divisor -= 1;
255 }
256 if factor > 0xfff0 {
257 return Err(UsbSerialError::Unsupported(format!(
258 "unsupported baud rate: {baud}"
259 )));
260 }
261 factor = 0x10000 - factor;
262 let divisor = divisor | 0x0080;
263 let val1 = ((factor & 0xff00) as u16) | divisor as u16;
264 let val2 = (factor & 0xff) as u16;
265 (val1, val2)
266 };
267 self.vendor_out(0x9A, 0x1312, val1)?;
268 self.vendor_out(0x9A, 0x0F2C, val2)
269 }
270
271 fn set_control_lines(&self) -> Result<()> {
272 let mut value = 0u16;
273 if self.dtr {
274 value |= SCL_DTR;
275 }
276 if self.rts {
277 value |= SCL_RTS;
278 }
279 self.vendor_out(0xA4, !value, 0)
280 }
281}