1use crate::error::Error;
2use crate::error::ErrorKind::I2cNoAck;
3use crate::{FtInner, PinUse};
4use eh1::i2c::{NoAcknowledgeSource, Operation, SevenBitAddress};
5use ftdi_mpsse::{ClockBitsIn, ClockBitsOut, MpsseCmdBuilder, MpsseCmdExecutor};
6use std::sync::{Arc, Mutex};
7
8const SCL: u8 = 1 << 0;
10const SDA: u8 = 1 << 1;
12
13const BITS_IN: ClockBitsIn = ClockBitsIn::MsbPos;
14const BITS_OUT: ClockBitsOut = ClockBitsOut::MsbNeg;
15
16#[derive(Debug)]
22pub struct I2c<Device: MpsseCmdExecutor> {
23 mtx: Arc<Mutex<FtInner<Device>>>,
25 start_stop_cmds: u8,
30 fast: bool,
32}
33
34impl<Device, E> I2c<Device>
35where
36 Device: MpsseCmdExecutor<Error = E>,
37 E: std::error::Error,
38 Error<E>: From<E>,
39{
40 pub(crate) fn new(mtx: Arc<Mutex<FtInner<Device>>>) -> Result<I2c<Device>, Error<E>> {
41 {
42 let mut lock = mtx.lock().expect("Failed to aquire FTDI mutex");
43
44 lock.allocate_pin(0, PinUse::I2c);
45 lock.allocate_pin(1, PinUse::I2c);
46 lock.allocate_pin(2, PinUse::I2c);
47
48 lock.direction &= !0x07;
51 lock.value &= !0x07;
52 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
59 .set_gpio_lower(lock.value, lock.direction)
60 .enable_3phase_data_clocking()
61 .send_immediate();
62 lock.ft.send(cmd.as_slice())?;
63 }
64
65 Ok(I2c {
66 mtx,
67 start_stop_cmds: 3,
68 fast: false,
69 })
70 }
71
72 pub fn set_stop_start_len(&mut self, start_stop_cmds: u8) {
95 self.start_stop_cmds = start_stop_cmds
96 }
97
98 pub fn set_fast(&mut self, fast: bool) {
134 self.fast = fast
135 }
136
137 fn read_fast(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error<E>> {
138 assert!(!buffer.is_empty(), "buffer must be a non-empty slice");
139
140 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
141
142 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
144 for _ in 0..self.start_stop_cmds {
145 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
146 }
147 for _ in 0..self.start_stop_cmds {
148 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
149 }
150
151 mpsse_cmd = mpsse_cmd
152 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
154 .clock_bits_out(BITS_OUT, (address << 1) | 1, 8)
155 .set_gpio_lower(lock.value, SCL | lock.direction)
157 .clock_bits_in(BITS_IN, 1);
158
159 for idx in 0..buffer.len() {
160 mpsse_cmd = mpsse_cmd
162 .set_gpio_lower(lock.value, SCL | lock.direction)
163 .clock_bits_in(BITS_IN, 8);
164 if idx == buffer.len() - 1 {
165 mpsse_cmd = mpsse_cmd
167 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
168 .clock_bits_out(BITS_OUT, 0x80, 1)
169 } else {
170 mpsse_cmd = mpsse_cmd
172 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
173 .clock_bits_out(BITS_OUT, 0x00, 1)
174 }
175 }
176
177 for _ in 0..self.start_stop_cmds {
179 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
180 }
181 for _ in 0..self.start_stop_cmds {
182 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
183 }
184 for _ in 0..self.start_stop_cmds {
185 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
186 }
187
188 mpsse_cmd = mpsse_cmd
189 .set_gpio_lower(lock.value, lock.direction)
191 .send_immediate();
192
193 lock.ft.send(mpsse_cmd.as_slice())?;
194 let mut ack_buf: [u8; 1] = [0; 1];
195 lock.ft.recv(&mut ack_buf)?;
196 lock.ft.recv(buffer)?;
197
198 if (ack_buf[0] & 0b1) != 0x00 {
199 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Unknown)));
200 }
201
202 Ok(())
203 }
204
205 fn read_slow(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error<E>> {
206 assert!(!buffer.is_empty(), "buffer must be a non-empty slice");
207
208 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
209
210 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
212 for _ in 0..self.start_stop_cmds {
213 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
214 }
215 for _ in 0..self.start_stop_cmds {
216 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
217 }
218
219 mpsse_cmd = mpsse_cmd
220 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
222 .clock_bits_out(BITS_OUT, (address << 1) | 1, 8)
223 .set_gpio_lower(lock.value, SCL | lock.direction)
225 .clock_bits_in(BITS_IN, 1)
226 .send_immediate();
227
228 lock.ft.send(mpsse_cmd.as_slice())?;
229 let mut ack_buf: [u8; 1] = [0; 1];
230 lock.ft.recv(&mut ack_buf)?;
231 if (ack_buf[0] & 0b1) != 0x00 {
232 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Address)));
233 }
234
235 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
236 for idx in 0..buffer.len() {
237 mpsse_cmd = mpsse_cmd
239 .set_gpio_lower(lock.value, SCL | lock.direction)
240 .clock_bits_in(BITS_IN, 8);
241 if idx == buffer.len() - 1 {
242 mpsse_cmd = mpsse_cmd
244 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
245 .clock_bits_out(BITS_OUT, 0x80, 1)
246 } else {
247 mpsse_cmd = mpsse_cmd
249 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
250 .clock_bits_out(BITS_OUT, 0x00, 1)
251 }
252 }
253
254 for _ in 0..self.start_stop_cmds {
256 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
257 }
258 for _ in 0..self.start_stop_cmds {
259 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
260 }
261 for _ in 0..self.start_stop_cmds {
262 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
263 }
264
265 mpsse_cmd = mpsse_cmd
266 .set_gpio_lower(lock.value, lock.direction)
268 .send_immediate();
269
270 lock.ft.send(mpsse_cmd.as_slice())?;
271 lock.ft.recv(buffer)?;
272
273 Ok(())
274 }
275
276 fn write_fast(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error<E>> {
277 assert!(!bytes.is_empty(), "bytes must be a non-empty slice");
278
279 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
280
281 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
282
283 for _ in 0..self.start_stop_cmds {
285 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
286 }
287 for _ in 0..self.start_stop_cmds {
288 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
289 }
290
291 mpsse_cmd = mpsse_cmd
292 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
294 .clock_bits_out(BITS_OUT, addr << 1, 8)
295 .set_gpio_lower(lock.value, SCL | lock.direction)
297 .clock_bits_in(BITS_IN, 1);
298
299 for byte in bytes.iter() {
300 mpsse_cmd = mpsse_cmd
301 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
303 .clock_bits_out(BITS_OUT, *byte, 8)
304 .set_gpio_lower(lock.value, SCL | lock.direction)
306 .clock_bits_in(BITS_IN, 1);
307 }
308
309 for _ in 0..self.start_stop_cmds {
311 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
312 }
313 for _ in 0..self.start_stop_cmds {
314 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
315 }
316 for _ in 0..self.start_stop_cmds {
317 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
318 }
319
320 mpsse_cmd = mpsse_cmd
321 .set_gpio_lower(lock.value, lock.direction)
323 .send_immediate();
324
325 lock.ft.send(mpsse_cmd.as_slice())?;
326 let mut ack_buf: Vec<u8> = vec![0; 1 + bytes.len()];
327 lock.ft.recv(ack_buf.as_mut_slice())?;
328 if ack_buf.iter().any(|&ack| (ack & 0b1) != 0x00) {
329 Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Unknown)))
330 } else {
331 Ok(())
332 }
333 }
334
335 fn write_slow(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error<E>> {
336 assert!(!bytes.is_empty(), "bytes must be a non-empty slice");
337
338 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
339
340 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
342 for _ in 0..self.start_stop_cmds {
343 mpsse_cmd = mpsse_cmd.set_gpio_lower(SCL | SDA | lock.value, SCL | SDA | lock.direction)
344 }
345 for _ in 0..self.start_stop_cmds {
346 mpsse_cmd = mpsse_cmd.set_gpio_lower(SCL | lock.value, SCL | SDA | lock.direction)
347 }
348
349 mpsse_cmd = mpsse_cmd
350 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
352 .clock_bits_out(BITS_OUT, addr << 1, 8)
353 .set_gpio_lower(lock.value, SCL | lock.direction)
355 .clock_bits_in(BITS_IN, 1)
356 .send_immediate();
357
358 lock.ft.send(mpsse_cmd.as_slice())?;
359 let mut ack_buf: [u8; 1] = [0; 1];
360 lock.ft.recv(&mut ack_buf)?;
361 if (ack_buf[0] & 0b1) != 0x00 {
362 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Address)));
363 }
364
365 for (idx, byte) in bytes.iter().enumerate() {
366 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
367 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
369 .clock_bits_out(BITS_OUT, *byte, 8)
370 .set_gpio_lower(lock.value, SCL | lock.direction)
372 .clock_bits_in(BITS_IN, 1);
373
374 if idx == bytes.len() - 1 {
376 for _ in 0..self.start_stop_cmds {
378 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
379 }
380 for _ in 0..self.start_stop_cmds {
381 mpsse_cmd =
382 mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
383 }
384 for _ in 0..self.start_stop_cmds {
385 mpsse_cmd =
386 mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
387 }
388
389 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, lock.direction)
391 }
392
393 mpsse_cmd = mpsse_cmd.send_immediate();
394
395 lock.ft.send(mpsse_cmd.as_slice())?;
396 let mut ack_buf: [u8; 1] = [0; 1];
397 lock.ft.recv(&mut ack_buf)?;
398 if (ack_buf[0] & 0b1) != 0x00 {
399 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Data)));
400 }
401 }
402
403 Ok(())
404 }
405
406 fn write_read_fast(
407 &mut self,
408 address: u8,
409 bytes: &[u8],
410 buffer: &mut [u8],
411 ) -> Result<(), Error<E>> {
412 assert!(!bytes.is_empty(), "bytes must be a non-empty slice");
413 assert!(!buffer.is_empty(), "buffer must be a non-empty slice");
414
415 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
418
419 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
420
421 for _ in 0..self.start_stop_cmds {
423 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
424 }
425 for _ in 0..self.start_stop_cmds {
426 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
427 }
428
429 mpsse_cmd = mpsse_cmd
430 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
432 .clock_bits_out(BITS_OUT, address << 1, 8)
433 .set_gpio_lower(lock.value, SCL | lock.direction)
435 .clock_bits_in(BITS_IN, 1);
436
437 for byte in bytes {
438 mpsse_cmd = mpsse_cmd
439 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
441 .clock_bits_out(BITS_OUT, *byte, 8)
442 .set_gpio_lower(lock.value, SCL | lock.direction)
444 .clock_bits_in(BITS_IN, 1);
445 }
446
447 for _ in 0..self.start_stop_cmds {
449 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
450 }
451 for _ in 0..self.start_stop_cmds {
452 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
453 }
454 for _ in 0..self.start_stop_cmds {
455 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
456 }
457
458 mpsse_cmd = mpsse_cmd
459 .clock_bits_out(BITS_OUT, (address << 1) | 1, 8)
461 .set_gpio_lower(lock.value, SCL | lock.direction)
463 .clock_bits_in(BITS_IN, 1);
464
465 for idx in 0..buffer.len() {
466 mpsse_cmd = mpsse_cmd
467 .set_gpio_lower(lock.value, SCL | lock.direction)
468 .clock_bits_in(BITS_IN, 8);
469 if idx == buffer.len() - 1 {
470 mpsse_cmd = mpsse_cmd
472 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
473 .clock_bits_out(BITS_OUT, 0x80, 1)
474 } else {
475 mpsse_cmd = mpsse_cmd
477 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
478 .clock_bits_out(BITS_OUT, 0x00, 1)
479 }
480 }
481
482 for _ in 0..self.start_stop_cmds {
484 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
485 }
486 for _ in 0..self.start_stop_cmds {
487 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
488 }
489 for _ in 0..self.start_stop_cmds {
490 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
491 }
492
493 mpsse_cmd = mpsse_cmd
494 .set_gpio_lower(lock.value, lock.direction)
496 .send_immediate();
497
498 lock.ft.send(mpsse_cmd.as_slice())?;
499 let mut ack_buf: Vec<u8> = vec![0; 2 + bytes.len()];
500 lock.ft.recv(&mut ack_buf)?;
501 lock.ft.recv(buffer)?;
502
503 if ack_buf.iter().any(|&ack| (ack & 0b1) != 0x00) {
504 Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Unknown)))
505 } else {
506 Ok(())
507 }
508 }
509
510 fn write_read_slow(
511 &mut self,
512 address: u8,
513 bytes: &[u8],
514 buffer: &mut [u8],
515 ) -> Result<(), Error<E>> {
516 assert!(!bytes.is_empty(), "bytes must be a non-empty slice");
517 assert!(!buffer.is_empty(), "buffer must be a non-empty slice");
518
519 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
522
523 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
525 for _ in 0..self.start_stop_cmds {
526 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
527 }
528 for _ in 0..self.start_stop_cmds {
529 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
530 }
531
532 mpsse_cmd = mpsse_cmd
533 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
535 .clock_bits_out(BITS_OUT, address << 1, 8)
536 .set_gpio_lower(lock.value, SCL | lock.direction)
538 .clock_bits_in(BITS_IN, 1)
539 .send_immediate();
540
541 lock.ft.send(mpsse_cmd.as_slice())?;
542 let mut ack_buf: [u8; 1] = [0; 1];
543 lock.ft.recv(&mut ack_buf)?;
544 if (ack_buf[0] & 0b1) != 0x00 {
545 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Address)));
546 }
547
548 for byte in bytes {
549 let mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
550 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
552 .clock_bits_out(BITS_OUT, *byte, 8)
553 .set_gpio_lower(lock.value, SCL | lock.direction)
555 .clock_bits_in(BITS_IN, 1)
556 .send_immediate();
557
558 lock.ft.send(mpsse_cmd.as_slice())?;
559 let mut ack_buf: [u8; 1] = [0; 1];
560 lock.ft.recv(&mut ack_buf)?;
561 if (ack_buf[0] & 0b1) != 0x00 {
562 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Data)));
563 }
564 }
565
566 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
568 for _ in 0..self.start_stop_cmds {
569 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
570 }
571 for _ in 0..self.start_stop_cmds {
572 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
573 }
574 for _ in 0..self.start_stop_cmds {
575 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
576 }
577
578 mpsse_cmd = mpsse_cmd
579 .clock_bits_out(BITS_OUT, (address << 1) | 1, 8)
581 .set_gpio_lower(lock.value, SCL | lock.direction)
583 .clock_bits_in(BITS_IN, 1)
584 .send_immediate();
585
586 lock.ft.send(mpsse_cmd.as_slice())?;
587 let mut ack_buf: [u8; 1] = [0; 1];
588 lock.ft.recv(&mut ack_buf)?;
589 if (ack_buf[0] & 0b1) != 0x00 {
590 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Data)));
591 }
592
593 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
594 for idx in 0..buffer.len() {
595 mpsse_cmd = mpsse_cmd
596 .set_gpio_lower(lock.value, SCL | lock.direction)
597 .clock_bits_in(BITS_IN, 8);
598 if idx == buffer.len() - 1 {
599 mpsse_cmd = mpsse_cmd
601 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
602 .clock_bits_out(BITS_OUT, 0x80, 1)
603 } else {
604 mpsse_cmd = mpsse_cmd
606 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
607 .clock_bits_out(BITS_OUT, 0x00, 1)
608 }
609 }
610
611 for _ in 0..self.start_stop_cmds {
613 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
614 }
615 for _ in 0..self.start_stop_cmds {
616 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
617 }
618 for _ in 0..self.start_stop_cmds {
619 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
620 }
621
622 mpsse_cmd = mpsse_cmd
623 .set_gpio_lower(lock.value, lock.direction)
625 .send_immediate();
626
627 lock.ft.send(mpsse_cmd.as_slice())?;
628 lock.ft.recv(buffer)?;
629
630 Ok(())
631 }
632
633 fn transaction(
634 &mut self,
635 address: u8,
636 operations: &mut [Operation<'_>],
637 ) -> Result<(), Error<E>> {
638 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
641
642 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
644 for _ in 0..self.start_stop_cmds {
645 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
646 }
647 for _ in 0..self.start_stop_cmds {
648 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
649 }
650 lock.ft.send(mpsse_cmd.as_slice())?;
651
652 let mut prev_op_was_a_read: bool = false;
653 for (idx, operation) in operations.iter_mut().enumerate() {
654 match operation {
655 Operation::Read(buffer) => {
656 if idx == 0 || !prev_op_was_a_read {
657 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
658 if idx != 0 {
659 for _ in 0..self.start_stop_cmds {
661 mpsse_cmd = mpsse_cmd.set_gpio_lower(
662 lock.value | SCL | SDA,
663 SCL | SDA | lock.direction,
664 )
665 }
666 for _ in 0..self.start_stop_cmds {
667 mpsse_cmd = mpsse_cmd
668 .set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
669 }
670 for _ in 0..self.start_stop_cmds {
671 mpsse_cmd =
672 mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
673 }
674 }
675
676 mpsse_cmd = mpsse_cmd
677 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
679 .clock_bits_out(BITS_OUT, (address << 1) | 1, 8)
680 .set_gpio_lower(lock.value, SCL | lock.direction)
682 .clock_bits_in(BITS_IN, 1)
683 .send_immediate();
684
685 lock.ft.send(mpsse_cmd.as_slice())?;
686 let mut ack_buf: [u8; 1] = [0; 1];
687 lock.ft.recv(&mut ack_buf)?;
688 if (ack_buf[0] & 0b1) != 0x00 {
689 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Address)));
690 }
691 }
692
693 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
694 for idx in 0..buffer.len() {
695 mpsse_cmd = mpsse_cmd
696 .set_gpio_lower(lock.value, SCL | lock.direction)
697 .clock_bits_in(BITS_IN, 8);
698 if idx == buffer.len() - 1 {
699 mpsse_cmd = mpsse_cmd
701 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
702 .clock_bits_out(BITS_OUT, 0x80, 1)
703 } else {
704 mpsse_cmd = mpsse_cmd
706 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
707 .clock_bits_out(BITS_OUT, 0x00, 1)
708 }
709 }
710 lock.ft.send(mpsse_cmd.as_slice())?;
711 lock.ft.recv(buffer)?;
712
713 prev_op_was_a_read = true;
714 }
715 Operation::Write(bytes) => {
716 if idx == 0 || prev_op_was_a_read {
717 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
718 if idx != 0 {
719 for _ in 0..self.start_stop_cmds {
721 mpsse_cmd = mpsse_cmd.set_gpio_lower(
722 lock.value | SCL | SDA,
723 SCL | SDA | lock.direction,
724 )
725 }
726 for _ in 0..self.start_stop_cmds {
727 mpsse_cmd = mpsse_cmd
728 .set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
729 }
730 for _ in 0..self.start_stop_cmds {
731 mpsse_cmd =
732 mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
733 }
734 }
735
736 mpsse_cmd = mpsse_cmd
737 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
739 .clock_bits_out(BITS_OUT, address << 1, 8)
740 .set_gpio_lower(lock.value, SCL | lock.direction)
742 .clock_bits_in(BITS_IN, 1)
743 .send_immediate();
744
745 lock.ft.send(mpsse_cmd.as_slice())?;
746 let mut ack_buf: [u8; 1] = [0; 1];
747 lock.ft.recv(&mut ack_buf)?;
748 if (ack_buf[0] & 0b1) != 0x00 {
749 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Address)));
750 }
751 }
752
753 for byte in *bytes {
754 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
755 mpsse_cmd = mpsse_cmd
756 .set_gpio_lower(lock.value, SCL | SDA | lock.direction)
758 .clock_bits_out(BITS_OUT, *byte, 8)
759 .set_gpio_lower(lock.value, SCL | lock.direction)
761 .clock_bits_in(BITS_IN, 1)
762 .send_immediate();
763
764 lock.ft.send(mpsse_cmd.as_slice())?;
765 let mut ack_buf: [u8; 1] = [0; 1];
766 lock.ft.recv(&mut ack_buf)?;
767 if (ack_buf[0] & 0b1) != 0x00 {
768 return Err(Error::Hal(I2cNoAck(NoAcknowledgeSource::Data)));
769 }
770 }
771
772 prev_op_was_a_read = false;
773 }
774 }
775 }
776
777 let mut mpsse_cmd: MpsseCmdBuilder = MpsseCmdBuilder::new();
778 for _ in 0..self.start_stop_cmds {
780 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value, SCL | SDA | lock.direction)
781 }
782 for _ in 0..self.start_stop_cmds {
783 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL, SCL | SDA | lock.direction)
784 }
785 for _ in 0..self.start_stop_cmds {
786 mpsse_cmd = mpsse_cmd.set_gpio_lower(lock.value | SCL | SDA, SCL | SDA | lock.direction)
787 }
788
789 mpsse_cmd = mpsse_cmd
791 .set_gpio_lower(lock.value, lock.direction)
792 .send_immediate();
793 lock.ft.send(mpsse_cmd.as_slice())?;
794
795 Ok(())
796 }
797}
798
799impl<Device, E> eh0::blocking::i2c::Read for I2c<Device>
800where
801 Device: MpsseCmdExecutor<Error = E>,
802 E: std::error::Error,
803 Error<E>: From<E>,
804{
805 type Error = Error<E>;
806
807 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error<E>> {
808 if self.fast {
809 self.read_fast(address, buffer)
810 } else {
811 self.read_slow(address, buffer)
812 }
813 }
814}
815
816impl<Device, E> eh0::blocking::i2c::Write for I2c<Device>
817where
818 Device: MpsseCmdExecutor<Error = E>,
819 E: std::error::Error,
820 Error<E>: From<E>,
821{
822 type Error = Error<E>;
823
824 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error<E>> {
825 if self.fast {
826 self.write_fast(addr, bytes)
827 } else {
828 self.write_slow(addr, bytes)
829 }
830 }
831}
832
833impl<Device, E> eh0::blocking::i2c::WriteRead for I2c<Device>
834where
835 Device: MpsseCmdExecutor<Error = E>,
836 E: std::error::Error,
837 Error<E>: From<E>,
838{
839 type Error = Error<E>;
840
841 fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error<E>> {
842 if self.fast {
843 self.write_read_fast(address, bytes, buffer)
844 } else {
845 self.write_read_slow(address, bytes, buffer)
846 }
847 }
848}
849
850impl<Device, E> eh1::i2c::ErrorType for I2c<Device>
851where
852 Device: MpsseCmdExecutor<Error = E>,
853 E: std::error::Error,
854 Error<E>: From<E>,
855{
856 type Error = Error<E>;
857}
858
859impl<Device, E> eh1::i2c::I2c for I2c<Device>
860where
861 Device: MpsseCmdExecutor<Error = E>,
862 E: std::error::Error,
863 Error<E>: From<E>,
864{
865 fn transaction(
866 &mut self,
867 address: SevenBitAddress,
868 operations: &mut [Operation<'_>],
869 ) -> Result<(), Self::Error> {
870 self.transaction(address, operations)
871 }
872}