1use either::Either::{Left, Right};
2use embedded_hal::i2c::{ErrorKind, NoAcknowledgeSource, Operation};
3
4use crate::{CmdWord, Error, ValidAddressMode};
5
6use super::{AnyPin, PIOExt, StateMachineIndex, I2C};
7
8impl<P, SMI, SDA, SCL> I2C<'_, P, SMI, SDA, SCL>
9where
10 P: PIOExt,
11 SMI: StateMachineIndex,
12 SDA: AnyPin,
13 SCL: AnyPin,
14{
15 pub fn write_iter<B, A>(&mut self, address: A, bytes: B) -> Result<(), Error>
16 where
17 A: ValidAddressMode,
18 B: IntoIterator<Item = u8> + Clone,
19 {
20 self.process_queue(
21 super::setup(address, false, false).chain(bytes.into_iter().map(CmdWord::write)),
22 )?;
23 self.generate_stop();
24 Ok(())
25 }
26
27 pub fn write_iter_read<A, B>(
28 &mut self,
29 address: A,
30 bytes: B,
31 buffer: &mut [u8],
32 ) -> Result<(), Error>
33 where
34 A: ValidAddressMode,
35 B: IntoIterator<Item = u8>,
36 {
37 self.process_queue(
38 super::setup(address, false, false)
39 .chain(bytes.into_iter().map(CmdWord::write))
40 .chain(super::setup(address, true, true))
41 .chain(buffer.iter_mut().map(CmdWord::read)),
42 )?;
43 self.generate_stop();
44 Ok(())
45 }
46
47 pub fn transaction_iter<'a, A, O>(&mut self, address: A, operations: O) -> Result<(), Error>
48 where
49 A: ValidAddressMode,
50 O: IntoIterator<Item = Operation<'a>>,
51 {
52 let mut first = true;
53 for op in operations {
54 let iter = match op {
55 Operation::Read(buf) => Left(
56 super::setup(address, true, !first).chain(buf.iter_mut().map(CmdWord::read)),
57 ),
58 Operation::Write(buf) => Right(
59 super::setup(address, false, !first)
60 .chain(buf.iter().cloned().map(CmdWord::write)),
61 ),
62 };
63 self.process_queue(iter)?;
64 first = false;
65 }
66 self.generate_stop();
67 Ok(())
68 }
69}
70
71impl embedded_hal::i2c::Error for super::Error {
72 fn kind(&self) -> ErrorKind {
73 match self {
74 Error::NoAcknowledgeAddress => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Address),
75 Error::NoAcknowledgeData => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Data),
76 Error::BusContention => ErrorKind::ArbitrationLoss,
77 }
78 }
79}
80
81impl<P, SMI, SDA, SCL> embedded_hal::i2c::ErrorType for I2C<'_, P, SMI, SDA, SCL>
82where
83 P: PIOExt,
84 SMI: StateMachineIndex,
85 SDA: AnyPin,
86 SCL: AnyPin,
87{
88 type Error = super::Error;
89}
90
91impl<A, P, SMI, SDA, SCL> embedded_hal::i2c::I2c<A> for I2C<'_, P, SMI, SDA, SCL>
92where
93 A: ValidAddressMode,
94 P: PIOExt,
95 SMI: StateMachineIndex,
96 SDA: AnyPin,
97 SCL: AnyPin,
98{
99 fn transaction(
100 &mut self,
101 address: A,
102 operations: &mut [Operation<'_>],
103 ) -> Result<(), Self::Error> {
104 let mut first = true;
105 for op in operations {
106 let iter = match op {
107 Operation::Read(buf) => Left(
108 super::setup(address, true, !first).chain(buf.iter_mut().map(CmdWord::read)),
109 ),
110 Operation::Write(buf) => Right(
111 super::setup(address, false, !first)
112 .chain(buf.iter().cloned().map(CmdWord::write)),
113 ),
114 };
115 self.process_queue(iter)?;
116 first = false;
117 }
118 self.generate_stop();
119 Ok(())
120 }
121}