stm32f1xx_hal/
i2c.rs

1//! Inter-Integrated Circuit (I2C) bus
2//!
3//! ## Alternate function remapping
4//!
5//! ### I2C1
6//!
7//! | Function \ Remap | 0 (default) | 1   |
8//! |------------------|-------------|-----|
9//! | SCL (A-OD)       | PB6         | PB8 |
10//! | SDA (A-OD)       | PB7         | PB9 |
11//!
12//! ### I2C2
13//!
14//! | Function   |      |
15//! |------------|------|
16//! | SCL (A-OD) | PB10 |
17//! | SDA (A-OD) | PB11 |
18
19// This document describes a correct i2c implementation and is what
20// parts of this code is based on
21// https://www.st.com/content/ccc/resource/technical/document/application_note/5d/ae/a3/6f/08/69/4e/9b/CD00209826.pdf/files/CD00209826.pdf/jcr:content/translations/en.CD00209826.pdf
22
23use crate::afio::{self, RInto, Rmp};
24use crate::pac::{self, i2c1};
25use crate::rcc::{BusClock, Clocks, Enable, Rcc, Reset};
26use crate::time::{kHz, Hertz};
27use core::ops::Deref;
28
29pub mod blocking;
30pub use blocking::BlockingI2c;
31
32mod common;
33mod hal_02;
34mod hal_1;
35
36pub use common::{Address, Error, NoAcknowledgeSource};
37use common::{Hal02Operation, Hal1Operation};
38
39#[derive(Debug, Eq, PartialEq)]
40pub enum DutyCycle {
41    Ratio2to1,
42    Ratio16to9,
43}
44
45#[derive(Debug, PartialEq, Eq)]
46pub enum Mode {
47    Standard {
48        frequency: Hertz,
49    },
50    Fast {
51        frequency: Hertz,
52        duty_cycle: DutyCycle,
53    },
54}
55
56impl Mode {
57    pub fn standard(frequency: Hertz) -> Self {
58        Mode::Standard { frequency }
59    }
60
61    pub fn fast(frequency: Hertz, duty_cycle: DutyCycle) -> Self {
62        Mode::Fast {
63            frequency,
64            duty_cycle,
65        }
66    }
67
68    pub fn get_frequency(&self) -> Hertz {
69        match *self {
70            Mode::Standard { frequency } => frequency,
71            Mode::Fast { frequency, .. } => frequency,
72        }
73    }
74}
75
76impl From<Hertz> for Mode {
77    fn from(frequency: Hertz) -> Self {
78        if frequency <= kHz(100) {
79            Self::Standard { frequency }
80        } else {
81            Self::Fast {
82                frequency,
83                duty_cycle: DutyCycle::Ratio2to1,
84            }
85        }
86    }
87}
88
89pub trait I2cExt: Sized + Instance {
90    fn i2c(
91        self,
92        pins: (impl RInto<Self::Scl, 0>, impl RInto<Self::Sda, 0>),
93        mode: impl Into<Mode>,
94        rcc: &mut Rcc,
95    ) -> I2c<Self>;
96}
97
98impl<I2C: Instance> I2cExt for I2C {
99    fn i2c(
100        self,
101        pins: (impl RInto<Self::Scl, 0>, impl RInto<Self::Sda, 0>),
102        mode: impl Into<Mode>,
103        rcc: &mut Rcc,
104    ) -> I2c<Self> {
105        I2c::new(self, pins, mode, rcc)
106    }
107}
108
109/// I2C peripheral operating in master mode
110pub struct I2c<I2C: Instance> {
111    i2c: I2C,
112    pins: (I2C::Scl, I2C::Sda),
113    mode: Mode,
114    pclk: Hertz,
115}
116
117pub trait Instance:
118    crate::Sealed
119    + Deref<Target = crate::pac::i2c1::RegisterBlock>
120    + Enable
121    + Reset
122    + BusClock
123    + afio::I2cCommon
124{
125}
126
127impl Instance for pac::I2C1 {}
128impl Instance for pac::I2C2 {}
129
130impl<I2C: Instance> I2c<I2C> {
131    /// Creates a generic I2C object
132    pub fn new<const R: u8>(
133        i2c: impl Into<Rmp<I2C, R>>,
134        pins: (impl RInto<I2C::Scl, R>, impl RInto<I2C::Sda, R>),
135        mode: impl Into<Mode>,
136        rcc: &mut Rcc,
137    ) -> Self {
138        i2c.into().i2c(pins, mode, rcc)
139    }
140}
141
142impl<I2C: Instance, const R: u8> Rmp<I2C, R> {
143    /// Creates a generic I2C object
144    pub fn i2c(
145        self,
146        pins: (impl RInto<I2C::Scl, R>, impl RInto<I2C::Sda, R>),
147        mode: impl Into<Mode>,
148        rcc: &mut Rcc,
149    ) -> I2c<I2C> {
150        let mode = mode.into();
151        I2C::enable(rcc);
152        I2C::reset(rcc);
153
154        let pclk1 = I2C::clock(&rcc.clocks);
155
156        assert!(mode.get_frequency() <= kHz(400));
157
158        let mut i2c = I2c {
159            i2c: self.0,
160            pins: (pins.0.rinto(), pins.1.rinto()),
161            mode,
162            pclk: pclk1,
163        };
164        i2c.init();
165        i2c
166    }
167}
168
169impl<I2C: Instance> I2c<I2C> {
170    /// Initializes I2C. Configures the `I2C_TRISE`, `I2C_CRX`, and `I2C_CCR` registers
171    /// according to the system frequency and I2C mode.
172    fn init(&mut self) {
173        let mode = &self.mode;
174        // Calculate settings for I2C speed modes
175        let clock = self.pclk.raw();
176        let clc_mhz = clock / 1_000_000;
177
178        // Configure bus frequency into I2C peripheral
179        self.i2c
180            .cr2()
181            .write(|w| unsafe { w.freq().bits(clc_mhz as u8) });
182
183        let trise = match mode {
184            Mode::Standard { .. } => clc_mhz + 1,
185            Mode::Fast { .. } => clc_mhz * 300 / 1000 + 1,
186        };
187
188        // Configure correct rise times
189        self.i2c.trise().write(|w| w.trise().set(trise as u8));
190
191        match mode {
192            // I2C clock control calculation
193            Mode::Standard { frequency } => {
194                let ccr = (clock / (frequency.raw() * 2)).max(4);
195
196                // Set clock to standard mode with appropriate parameters for selected speed
197                self.i2c.ccr().write(|w| unsafe {
198                    w.f_s().clear_bit();
199                    w.duty().clear_bit();
200                    w.ccr().bits(ccr as u16)
201                });
202            }
203            Mode::Fast {
204                frequency,
205                duty_cycle,
206            } => match duty_cycle {
207                DutyCycle::Ratio2to1 => {
208                    let ccr = (clock / (frequency.raw() * 3)).max(1);
209
210                    // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle)
211                    self.i2c.ccr().write(|w| unsafe {
212                        w.f_s().set_bit().duty().clear_bit().ccr().bits(ccr as u16)
213                    });
214                }
215                DutyCycle::Ratio16to9 => {
216                    let ccr = (clock / (frequency.raw() * 25)).max(1);
217
218                    // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle)
219                    self.i2c.ccr().write(|w| unsafe {
220                        w.f_s().set_bit().duty().set_bit().ccr().bits(ccr as u16)
221                    });
222                }
223            },
224        }
225
226        // Enable the I2C processing
227        self.i2c.cr1().modify(|_, w| w.pe().set_bit());
228    }
229
230    /// Perform an I2C software reset
231    pub fn reset(&mut self) {
232        self.i2c.cr1().write(|w| w.pe().set_bit().swrst().set_bit());
233        self.i2c.cr1().reset();
234        self.init();
235    }
236
237    /// Generate START condition
238    fn send_start(&mut self) {
239        // Clear all pending error bits
240        // NOTE(unsafe): Writing 0 clears the r/w bits and has no effect on the r bits
241        self.i2c.sr1().write(|w| unsafe { w.bits(0) });
242        self.i2c.cr1().modify(|_, w| w.start().set_bit());
243    }
244
245    /// Sends the (7-Bit) address on the I2C bus. The 8th bit on the bus is set
246    /// depending on wether it is a read or write transfer.
247    fn send_addr(&self, addr: u8, read: bool) {
248        self.i2c
249            .dr()
250            .write(|w| w.dr().set((addr << 1) | (u8::from(read))));
251    }
252
253    /// Generate STOP condition
254    fn send_stop(&self) {
255        self.i2c.cr1().modify(|_, w| w.stop().set_bit());
256    }
257
258    /// Releases the I2C peripheral and associated pins
259    pub fn release(self) -> (I2C, (I2C::Scl, I2C::Sda)) {
260        (self.i2c, self.pins)
261    }
262
263    fn check_and_clear_error_flags(&self) -> Result<i2c1::sr1::R, Error> {
264        // Note that flags should only be cleared once they have been registered. If flags are
265        // cleared otherwise, there may be an inherent race condition and flags may be missed.
266        let sr1 = self.i2c.sr1().read();
267
268        if sr1.timeout().bit_is_set() {
269            self.i2c.sr1().write(|w| w.timeout().clear_bit());
270            return Err(Error::Timeout);
271        }
272
273        if sr1.pecerr().bit_is_set() {
274            self.i2c.sr1().write(|w| w.pecerr().clear_bit());
275            return Err(Error::Crc);
276        }
277
278        if sr1.ovr().bit_is_set() {
279            self.i2c.sr1().write(|w| w.ovr().clear_bit());
280            return Err(Error::Overrun);
281        }
282
283        if sr1.af().bit_is_set() {
284            self.i2c.sr1().write(|w| w.af().clear_bit());
285            return Err(Error::NoAcknowledge(NoAcknowledgeSource::Unknown));
286        }
287
288        if sr1.arlo().bit_is_set() {
289            self.i2c.sr1().write(|w| w.arlo().clear_bit());
290            return Err(Error::ArbitrationLoss);
291        }
292
293        // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and
294        // clearing the BERR bit instead.
295        if sr1.berr().bit_is_set() {
296            self.i2c.sr1().write(|w| w.berr().clear_bit());
297        }
298
299        Ok(sr1)
300    }
301
302    /// Sends START and Address for writing
303    #[inline(always)]
304    fn prepare_write(&self, addr: Address) -> Result<(), Error> {
305        // Wait until a previous STOP condition finishes. When the previous
306        // STOP was generated inside an ISR (e.g. DMA interrupt handler),
307        // the ISR returns without waiting for the STOP condition to finish.
308        // It is possible that the STOP condition is still being generated
309        // when we reach here, so we wait until it finishes before proceeding
310        // to start a new transaction.
311        while self.i2c.cr1().read().stop().bit_is_set() {}
312
313        // Clear all pending error bits
314        self.i2c.sr1().write(|w| unsafe { w.bits(0) });
315        // Send a START condition
316        self.i2c.cr1().modify(|_, w| w.start().set_bit());
317
318        // Wait until START condition was generated
319        while self.check_and_clear_error_flags()?.sb().bit_is_clear() {}
320
321        // Also wait until signalled we're master and everything is waiting for us
322        loop {
323            self.check_and_clear_error_flags()?;
324
325            let sr2 = self.i2c.sr2().read();
326            if !(sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()) {
327                break;
328            }
329        }
330
331        // Set up current address, we're trying to talk to
332        match addr {
333            Address::Seven(addr) => {
334                self.i2c
335                    .dr()
336                    .write(|w| unsafe { w.bits(u16::from(addr) << 1) });
337            }
338            Address::Ten(addr) => {
339                let [msbs, lsbs] = addr.to_be_bytes();
340                let msbs = ((msbs & 0b11) << 1) & 0b11110000;
341                let dr = self.i2c.dr();
342                dr.write(|w| unsafe { w.bits(u16::from(msbs)) });
343                dr.write(|w| unsafe { w.bits(u16::from(lsbs)) });
344            }
345        }
346
347        // Wait until address was sent
348        loop {
349            // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
350            let sr1 = self
351                .check_and_clear_error_flags()
352                .map_err(Error::nack_addr)?;
353
354            // Wait for the address to be acknowledged
355            if sr1.addr().bit_is_set() {
356                break;
357            }
358        }
359
360        // Clear condition by reading SR2
361        self.i2c.sr2().read();
362
363        Ok(())
364    }
365
366    /// Sends START and Address for reading
367    fn prepare_read(&self, addr: Address, first_transaction: bool) -> Result<(), Error> {
368        // Wait until a previous STOP condition finishes. When the previous
369        // STOP was generated inside an ISR (e.g. DMA interrupt handler),
370        // the ISR returns without waiting for the STOP condition to finish.
371        // It is possible that the STOP condition is still being generated
372        // when we reach here, so we wait until it finishes before proceeding
373        // to start a new transaction.
374        while self.i2c.cr1().read().stop().bit_is_set() {}
375
376        // Clear all pending error bits
377        self.i2c.sr1().write(|w| unsafe { w.bits(0) });
378        // Send a START condition and set ACK bit
379        self.i2c
380            .cr1()
381            .modify(|_, w| w.start().set_bit().ack().set_bit());
382
383        // Wait until START condition was generated
384        while self.i2c.sr1().read().sb().bit_is_clear() {}
385
386        // Also wait until signalled we're master and everything is waiting for us
387        while {
388            let sr2 = self.i2c.sr2().read();
389            sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
390        } {}
391
392        // Set up current address, we're trying to talk to
393        match addr {
394            Address::Seven(addr) => {
395                self.i2c
396                    .dr()
397                    .write(|w| unsafe { w.bits((u16::from(addr) << 1) | 1) });
398            }
399            Address::Ten(addr) => {
400                let [msbs, lsbs] = addr.to_be_bytes();
401                let msbs = ((msbs & 0b11) << 1) | 0b11110000;
402                let dr = self.i2c.dr();
403                if first_transaction {
404                    dr.write(|w| unsafe { w.bits(u16::from(msbs)) });
405                    dr.write(|w| unsafe { w.bits(u16::from(lsbs)) });
406                }
407                self.i2c.cr1().modify(|_, w| w.start().set_bit());
408                // Wait until START condition was generated
409                while self.i2c.sr1().read().sb().bit_is_clear() {}
410                dr.write(|w| unsafe { w.bits(u16::from(msbs | 1)) });
411            }
412        }
413
414        // Wait until address was sent
415        loop {
416            self.check_and_clear_error_flags()
417                .map_err(Error::nack_addr)?;
418            if self.i2c.sr1().read().addr().bit_is_set() {
419                break;
420            }
421        }
422
423        // Clear condition by reading SR2
424        self.i2c.sr2().read();
425
426        Ok(())
427    }
428
429    fn write_bytes(&mut self, bytes: impl Iterator<Item = u8>) -> Result<(), Error> {
430        // Send bytes
431        for c in bytes {
432            self.send_byte(c)?;
433        }
434
435        // Fallthrough is success
436        Ok(())
437    }
438
439    fn send_byte(&self, byte: u8) -> Result<(), Error> {
440        // Wait until we're ready for sending
441        // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
442        while self
443            .check_and_clear_error_flags()
444            .map_err(Error::nack_addr)?
445            .tx_e()
446            .bit_is_clear()
447        {}
448
449        // Push out a byte of data
450        self.i2c.dr().write(|w| unsafe { w.bits(u16::from(byte)) });
451
452        // Wait until byte is transferred
453        // Check for any potential error conditions.
454        while self
455            .check_and_clear_error_flags()
456            .map_err(Error::nack_data)?
457            .btf()
458            .bit_is_clear()
459        {}
460
461        Ok(())
462    }
463
464    fn recv_byte(&self) -> Result<u8, Error> {
465        loop {
466            // Check for any potential error conditions.
467            self.check_and_clear_error_flags()
468                .map_err(Error::nack_data)?;
469
470            if self.i2c.sr1().read().rx_ne().bit_is_set() {
471                break;
472            }
473        }
474
475        let value = self.i2c.dr().read().bits() as u8;
476        Ok(value)
477    }
478
479    fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
480        // Receive bytes into buffer
481        for c in buffer {
482            *c = self.recv_byte()?;
483        }
484
485        Ok(())
486    }
487
488    pub fn read(&mut self, addr: impl Into<Address>, buffer: &mut [u8]) -> Result<(), Error> {
489        self.read_inner(addr.into(), buffer, true)
490    }
491
492    #[inline(always)]
493    fn read_inner(
494        &mut self,
495        addr: Address,
496        buffer: &mut [u8],
497        first_transaction: bool,
498    ) -> Result<(), Error> {
499        if buffer.is_empty() {
500            return Err(Error::Overrun);
501        }
502
503        self.prepare_read(addr, first_transaction)?;
504        self.read_wo_prepare(buffer)
505    }
506
507    /// Reads like normal but does'n generate start and don't send address
508    fn read_wo_prepare(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
509        if let Some((last, buffer)) = buffer.split_last_mut() {
510            // Read all bytes but not last
511            self.read_bytes(buffer)?;
512
513            // Prepare to send NACK then STOP after next byte
514            self.i2c
515                .cr1()
516                .modify(|_, w| w.ack().clear_bit().stop().set_bit());
517
518            // Receive last byte
519            *last = self.recv_byte()?;
520
521            // Wait for the STOP to be sent. Otherwise, the interface will still be
522            // busy for a while after this function returns. Immediate following
523            // operations through the DMA handle might thus encounter `WouldBlock`
524            // error. Instead, we should make sure that the interface becomes idle
525            // before returning.
526            while self.i2c.cr1().read().stop().bit_is_set() {}
527
528            // Fallthrough is success
529            Ok(())
530        } else {
531            Err(Error::Overrun)
532        }
533    }
534
535    pub fn write(&mut self, addr: impl Into<Address>, bytes: &[u8]) -> Result<(), Error> {
536        self.prepare_write(addr.into())?;
537        self.write_wo_prepare(bytes)
538    }
539
540    /// Writes like normal but does'n generate start and don't send address
541    fn write_wo_prepare(&mut self, bytes: &[u8]) -> Result<(), Error> {
542        self.write_bytes(bytes.iter().cloned())?;
543
544        // Send a STOP condition
545        self.i2c.cr1().modify(|_, w| w.stop().set_bit());
546
547        // Wait for the STOP to be sent. Otherwise, the interface will still be
548        // busy for a while after this function returns. Immediate following
549        // operations through the DMA handle might thus encounter `WouldBlock`
550        // error. Instead, we should make sure that the interface becomes idle
551        // before returning.
552        while self.i2c.cr1().read().stop().bit_is_set() {}
553
554        // Fallthrough is success
555        Ok(())
556    }
557
558    pub fn write_iter<B>(&mut self, addr: impl Into<Address>, bytes: B) -> Result<(), Error>
559    where
560        B: IntoIterator<Item = u8>,
561    {
562        self.prepare_write(addr.into())?;
563        self.write_bytes(bytes.into_iter())?;
564
565        // Send a STOP condition
566        self.i2c.cr1().modify(|_, w| w.stop().set_bit());
567
568        // Wait for the STOP to be sent. Otherwise, the interface will still be
569        // busy for a while after this function returns. Immediate following
570        // operations through the DMA handle might thus encounter `WouldBlock`
571        // error. Instead, we should make sure that the interface becomes idle
572        // before returning.
573        while self.i2c.cr1().read().stop().bit_is_set() {}
574
575        // Fallthrough is success
576        Ok(())
577    }
578
579    pub fn write_read(
580        &mut self,
581        addr: impl Into<Address>,
582        bytes: &[u8],
583        buffer: &mut [u8],
584    ) -> Result<(), Error> {
585        let addr = addr.into();
586        self.prepare_write(addr)?;
587        self.write_bytes(bytes.iter().cloned())?;
588        self.read_inner(addr, buffer, false)
589    }
590
591    pub fn write_iter_read<B>(
592        &mut self,
593        addr: impl Into<Address>,
594        bytes: B,
595        buffer: &mut [u8],
596    ) -> Result<(), Error>
597    where
598        B: IntoIterator<Item = u8>,
599    {
600        let addr = addr.into();
601        self.prepare_write(addr)?;
602        self.write_bytes(bytes.into_iter())?;
603        self.read_inner(addr, buffer, false)
604    }
605
606    pub fn transaction<'a>(
607        &mut self,
608        addr: impl Into<Address>,
609        mut ops: impl Iterator<Item = Hal1Operation<'a>>,
610    ) -> Result<(), Error> {
611        let addr = addr.into();
612        if let Some(mut prev_op) = ops.next() {
613            // 1. Generate Start for operation
614            match &prev_op {
615                Hal1Operation::Read(_) => self.prepare_read(addr, true)?,
616                Hal1Operation::Write(_) => self.prepare_write(addr)?,
617            };
618
619            for op in ops {
620                // 2. Execute previous operations.
621                match &mut prev_op {
622                    Hal1Operation::Read(rb) => self.read_bytes(rb)?,
623                    Hal1Operation::Write(wb) => self.write_bytes(wb.iter().cloned())?,
624                };
625                // 3. If operation changes type we must generate new start
626                match (&prev_op, &op) {
627                    (Hal1Operation::Read(_), Hal1Operation::Write(_)) => {
628                        self.prepare_write(addr)?
629                    }
630                    (Hal1Operation::Write(_), Hal1Operation::Read(_)) => {
631                        self.prepare_read(addr, false)?
632                    }
633                    _ => {} // No changes if operation have not changed
634                }
635
636                prev_op = op;
637            }
638
639            // 4. Now, prev_op is last command use methods variations that will generate stop
640            match prev_op {
641                Hal1Operation::Read(rb) => self.read_wo_prepare(rb)?,
642                Hal1Operation::Write(wb) => self.write_wo_prepare(wb)?,
643            };
644        }
645
646        // Fallthrough is success
647        Ok(())
648    }
649
650    pub fn transaction_slice(
651        &mut self,
652        addr: impl Into<Address>,
653        ops_slice: &mut [Hal1Operation<'_>],
654    ) -> Result<(), Error> {
655        let addr = addr.into();
656        transaction_impl!(self, addr, ops_slice, Hal1Operation);
657        // Fallthrough is success
658        Ok(())
659    }
660
661    fn transaction_slice_hal_02(
662        &mut self,
663        addr: impl Into<Address>,
664        ops_slice: &mut [Hal02Operation<'_>],
665    ) -> Result<(), Error> {
666        let addr = addr.into();
667        transaction_impl!(self, addr, ops_slice, Hal02Operation);
668        // Fallthrough is success
669        Ok(())
670    }
671}
672
673macro_rules! transaction_impl {
674    ($self:ident, $addr:ident, $ops_slice:ident, $Operation:ident) => {
675        let i2c = $self;
676        let addr = $addr;
677        let mut ops = $ops_slice.iter_mut();
678
679        if let Some(mut prev_op) = ops.next() {
680            // 1. Generate Start for operation
681            match &prev_op {
682                $Operation::Read(_) => i2c.prepare_read(addr, true)?,
683                $Operation::Write(_) => i2c.prepare_write(addr)?,
684            };
685
686            for op in ops {
687                // 2. Execute previous operations.
688                match &mut prev_op {
689                    $Operation::Read(rb) => i2c.read_bytes(rb)?,
690                    $Operation::Write(wb) => i2c.write_bytes(wb.iter().cloned())?,
691                };
692                // 3. If operation changes type we must generate new start
693                match (&prev_op, &op) {
694                    ($Operation::Read(_), $Operation::Write(_)) => i2c.prepare_write(addr)?,
695                    ($Operation::Write(_), $Operation::Read(_)) => i2c.prepare_read(addr, false)?,
696                    _ => {} // No changes if operation have not changed
697                }
698
699                prev_op = op;
700            }
701
702            // 4. Now, prev_op is last command use methods variations that will generate stop
703            match prev_op {
704                $Operation::Read(rb) => i2c.read_wo_prepare(rb)?,
705                $Operation::Write(wb) => i2c.write_wo_prepare(wb)?,
706            };
707        }
708    };
709}
710use transaction_impl;
711
712impl<I2C: Instance> embedded_hal_02::blocking::i2c::WriteIter for I2c<I2C> {
713    type Error = Error;
714
715    fn write<B>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error>
716    where
717        B: IntoIterator<Item = u8>,
718    {
719        self.write_iter(addr, bytes)
720    }
721}
722
723impl<I2C: Instance> embedded_hal_02::blocking::i2c::WriteIterRead for I2c<I2C> {
724    type Error = Error;
725
726    fn write_iter_read<B>(
727        &mut self,
728        addr: u8,
729        bytes: B,
730        buffer: &mut [u8],
731    ) -> Result<(), Self::Error>
732    where
733        B: IntoIterator<Item = u8>,
734    {
735        self.write_iter_read(addr, bytes, buffer)
736    }
737}