1use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
54use embedded_hal::digital::v2::{InputPin, OutputPin};
55use embedded_hal::timer::{CountDown, Periodic};
56use nb::block;
57
58#[derive(Debug, Eq, PartialEq)]
60pub enum Error<E> {
61 Bus(E),
63 NoAck,
65 InvalidData,
67}
68
69pub struct I2cBB<SCL, SDA, CLK>
71where
72 SCL: OutputPin,
73 SDA: OutputPin + InputPin,
74 CLK: CountDown + Periodic,
75{
76 scl: SCL,
77 sda: SDA,
78 clk: CLK,
79}
80
81impl<SCL, SDA, CLK, E> I2cBB<SCL, SDA, CLK>
82where
83 SCL: OutputPin<Error = E>,
84 SDA: OutputPin<Error = E> + InputPin<Error = E>,
85 CLK: CountDown + Periodic,
86{
87 pub fn new(scl: SCL, sda: SDA, clk: CLK) -> Self {
89 I2cBB { scl, sda, clk }
90 }
91
92 pub fn raw_i2c_start(&mut self) -> Result<(), crate::i2c::Error<E>> {
98 self.set_scl_high()?;
99 self.set_sda_high()?;
100 self.wait_for_clk();
101
102 self.set_sda_low()?;
103 self.wait_for_clk();
104
105 self.set_scl_low()?;
106 self.wait_for_clk();
107
108 Ok(())
109 }
110
111 pub fn raw_i2c_stop(&mut self) -> Result<(), crate::i2c::Error<E>> {
117 self.set_scl_high()?;
118 self.wait_for_clk();
119
120 self.set_sda_high()?;
121 self.wait_for_clk();
122
123 Ok(())
124 }
125
126 fn i2c_is_ack(&mut self) -> Result<bool, crate::i2c::Error<E>> {
127 self.set_sda_high()?;
128 self.set_scl_high()?;
129 self.wait_for_clk();
130
131 let ack = self.sda.is_low().map_err(Error::Bus)?;
132
133 self.set_scl_low()?;
134 self.set_sda_low()?;
135 self.wait_for_clk();
136
137 Ok(ack)
138 }
139
140 fn i2c_read_byte(&mut self, should_send_ack: bool) -> Result<u8, crate::i2c::Error<E>> {
141 let mut byte: u8 = 0;
142
143 self.set_sda_high()?;
144
145 for bit_offset in 0..8 {
146 self.set_scl_high()?;
147 self.wait_for_clk();
148
149 if self.sda.is_high().map_err(Error::Bus)? {
150 byte |= 1 << (7 - bit_offset);
151 }
152
153 self.set_scl_low()?;
154 self.wait_for_clk();
155 }
156
157 if should_send_ack {
158 self.set_sda_low()?;
159 } else {
160 self.set_sda_high()?;
161 }
162
163 self.set_scl_high()?;
164 self.wait_for_clk();
165
166 self.set_scl_low()?;
167 self.set_sda_low()?;
168 self.wait_for_clk();
169
170 Ok(byte)
171 }
172
173 fn i2c_write_byte(&mut self, byte: u8) -> Result<(), crate::i2c::Error<E>> {
174 for bit_offset in 0..8 {
175 let out_bit = (byte >> (7 - bit_offset)) & 0b1;
176
177 if out_bit == 1 {
178 self.set_sda_high()?;
179 } else {
180 self.set_sda_low()?;
181 }
182
183 self.set_scl_high()?;
184 self.wait_for_clk();
185
186 self.set_scl_low()?;
187 self.set_sda_low()?;
188 self.wait_for_clk();
189 }
190
191 Ok(())
192 }
193
194 #[inline]
200 pub fn raw_read_from_slave(&mut self, input: &mut [u8]) -> Result<(), crate::i2c::Error<E>> {
201 for i in 0..input.len() {
202 let should_send_ack = i != (input.len() - 1);
203 input[i] = self.i2c_read_byte(should_send_ack)?;
204 }
205 Ok(())
206 }
207
208 #[inline]
214 pub fn raw_write_to_slave(&mut self, output: &[u8]) -> Result<(), crate::i2c::Error<E>> {
215 for byte in output {
216 self.i2c_write_byte(*byte)?;
217 self.check_ack()?;
218 }
219 Ok(())
220 }
221
222 #[inline]
223 fn set_scl_high(&mut self) -> Result<(), crate::i2c::Error<E>> {
224 self.scl.set_high().map_err(Error::Bus)
225 }
226
227 #[inline]
228 fn set_scl_low(&mut self) -> Result<(), crate::i2c::Error<E>> {
229 self.scl.set_low().map_err(Error::Bus)
230 }
231
232 #[inline]
233 fn set_sda_high(&mut self) -> Result<(), crate::i2c::Error<E>> {
234 self.sda.set_high().map_err(Error::Bus)
235 }
236
237 #[inline]
238 fn set_sda_low(&mut self) -> Result<(), crate::i2c::Error<E>> {
239 self.sda.set_low().map_err(Error::Bus)
240 }
241
242 #[inline]
243 fn wait_for_clk(&mut self) {
244 block!(self.clk.wait()).ok();
245 }
246
247 #[inline]
248 fn check_ack(&mut self) -> Result<(), crate::i2c::Error<E>> {
249 if !self.i2c_is_ack()? {
250 Err(Error::NoAck)
251 } else {
252 Ok(())
253 }
254 }
255}
256
257impl<SCL, SDA, CLK, E> Write for I2cBB<SCL, SDA, CLK>
258where
259 SCL: OutputPin<Error = E>,
260 SDA: OutputPin<Error = E> + InputPin<Error = E>,
261 CLK: CountDown + Periodic,
262{
263 type Error = crate::i2c::Error<E>;
264
265 fn write(&mut self, addr: u8, output: &[u8]) -> Result<(), Self::Error> {
266 self.raw_i2c_start()?;
268
269 self.i2c_write_byte((addr << 1) | 0x0)?;
271 self.check_ack()?;
272
273 self.raw_write_to_slave(output)?;
274
275 self.raw_i2c_stop()
277 }
278}
279
280impl<SCL, SDA, CLK, E> Read for I2cBB<SCL, SDA, CLK>
281where
282 SCL: OutputPin<Error = E>,
283 SDA: OutputPin<Error = E> + InputPin<Error = E>,
284 CLK: CountDown + Periodic,
285{
286 type Error = crate::i2c::Error<E>;
287
288 fn read(&mut self, addr: u8, input: &mut [u8]) -> Result<(), Self::Error> {
289 if input.is_empty() {
290 return Ok(());
291 }
292
293 self.raw_i2c_start()?;
295
296 self.i2c_write_byte((addr << 1) | 0x1)?;
298 self.check_ack()?;
299
300 self.raw_read_from_slave(input)?;
301
302 self.raw_i2c_stop()
304 }
305}
306
307impl<SCL, SDA, CLK, E> WriteRead for I2cBB<SCL, SDA, CLK>
308where
309 SCL: OutputPin<Error = E>,
310 SDA: OutputPin<Error = E> + InputPin<Error = E>,
311 CLK: CountDown + Periodic,
312{
313 type Error = crate::i2c::Error<E>;
314
315 fn write_read(&mut self, addr: u8, output: &[u8], input: &mut [u8]) -> Result<(), Self::Error> {
316 if output.is_empty() || input.is_empty() {
317 return Err(Error::InvalidData);
318 }
319
320 self.raw_i2c_start()?;
322
323 self.i2c_write_byte((addr << 1) | 0x0)?;
325 self.check_ack()?;
326
327 self.raw_write_to_slave(output)?;
328
329 self.raw_i2c_start()?;
331
332 self.i2c_write_byte((addr << 1) | 0x1)?;
334 self.check_ack()?;
335
336 self.raw_read_from_slave(input)?;
337
338 self.raw_i2c_stop()
340 }
341}