stm32f4xx_hal/
i2c.rs

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