stm32_hal2/
i2c.rs

1//! Support for the Inter-Integrated Circuit (I2C) bus peripheral. Also supports SMBUS.
2//! Provides APIs to configure, read, and write from
3//! I2C, with blocking, nonblocking, and DMA functionality.
4
5use core::ops::Deref;
6
7// #[cfg(feature = "embedded_hal")]
8// use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
9#[cfg(any(feature = "f3", feature = "l4"))]
10use crate::dma::DmaInput;
11#[cfg(not(any(feature = "l552", feature = "h5")))]
12use crate::dma::{self, ChannelCfg, DmaChannel};
13#[cfg(any(feature = "c0", feature = "h5"))]
14use crate::pac::DMA as DMA1;
15#[cfg(not(any(feature = "h5", feature = "c0")))]
16use crate::pac::DMA1;
17use crate::{
18    clocks::Clocks,
19    error::{Error, Result},
20    pac::{self, RCC},
21    util::RccPeriph,
22};
23
24const MAX_ITERS: u32 = 300_000;
25
26macro_rules! busy_wait {
27    ($regs:expr, $flag:ident) => {
28        let mut i = 0;
29
30        loop {
31            let isr = $regs.isr().read();
32
33            i += 1;
34            if i >= MAX_ITERS {
35                return Err(Error::I2cError(I2cError::Hardware));
36            }
37
38            if isr.$flag().bit_is_set() {
39                break;
40            } else if isr.berr().bit_is_set() {
41                $regs.icr().write(|w| w.berrcf().bit(true));
42                return Err(Error::I2cError(I2cError::Bus));
43            } else if isr.arlo().bit_is_set() {
44                $regs.icr().write(|w| w.arlocf().bit(true));
45                return Err(Error::I2cError(I2cError::Arbitration));
46            } else if isr.nackf().bit_is_set() {
47                $regs
48                    .icr()
49                    .write(|w| w.stopcf().bit(true).nackcf().bit(true));
50
51                // If a pending TXIS flag is set, write dummy data to TXDR
52                if $regs.isr().read().txis().bit_is_set() {
53                    $regs.txdr().write(|w| unsafe { w.txdata().bits(0) });
54                }
55
56                // If TXDR is not flagged as empty, write 1 to flush it
57                if $regs.isr().read().txe().bit_is_clear() {
58                    $regs.isr().write(|w| w.txe().bit(true));
59                }
60
61                return Err(Error::I2cError(I2cError::Nack));
62            } else {
63            }
64        }
65    };
66}
67
68/// I2C error
69#[non_exhaustive]
70#[cfg_attr(feature = "defmt", derive(defmt::Format))]
71#[derive(Debug, Clone, Copy, Eq, PartialEq)]
72pub enum I2cError {
73    /// Bus error
74    Bus,
75    /// Arbitration loss
76    Arbitration,
77    /// NACK
78    Nack,
79    // Overrun, // slave mode only
80    // Pec, // SMBUS mode only
81    // Timeout, // SMBUS mode only
82    // Alert, // SMBUS mode only
83    Hardware,
84    Overrun,
85}
86
87#[derive(Clone, Copy)]
88#[repr(u8)]
89/// Set master or slave mode. Sets the __ register, _ field.
90pub enum I2cMode {
91    /// In Master mode, the I2C interface initiates a data transfer and generates the clock signal. A
92    /// serial data transfer always begins with a START condition and ends with a STOP condition.
93    /// Both START and STOP conditions are generated in master mode by software.
94    Master = 0,
95    /// In Slave mode, the interface is capable of recognizing its own addresses (7 or 10-bit), and
96    /// the general call address. The general call address detection can be enabled or disabled by
97    /// software. The reserved SMBus addresses can also be enabled by software.
98    Slave = 1,
99}
100
101#[derive(Clone, Copy)]
102/// Set a preset I2C speed, based on RM tables: Examples of timings settings.
103/// Sets 5 fields of the TIMINGR register.
104pub enum I2cSpeed {
105    /// Standard-mode: 10kHz.
106    Standard10K,
107    /// Standard-mode: 100kHz.
108    Standard100K,
109    /// Fast-mode: 400kHz.
110    Fast400K,
111    /// Fast-mode +: 1Mhz.
112    FastPlus1M,
113}
114
115#[derive(Clone, Copy)]
116#[repr(u8)]
117/// Set the number of address bits to 7 or 10. Sets the CR2 register, ADD10 field.
118pub enum AddressBits {
119    B7 = 0,
120    B10 = 1,
121}
122
123#[derive(Clone, Copy, PartialEq)]
124/// Set the number of address bits to 7 or 10. Sets the CR1 register, ANFOFF and DNF fields.
125pub enum NoiseFilter {
126    /// Analog noise filter enabled.
127    Analog,
128    /// Digital filter enabled and filtering capability ( filters spikes with a length of)
129    /// up to (value) t_I2CCLK
130    Digital(u8),
131    /// Analog and digital filters disabled.
132    Disabled,
133}
134
135/// Configuration data for the I2C peripheral.
136#[derive(Clone)]
137pub struct I2cConfig {
138    /// Select master or slave mode. Defaults to Master.
139    pub mode: I2cMode,
140    /// Select between one of 4 preset speeds. If you'd like to use custom
141    /// speed settings, use the PAC directly, with I2C disabled, after the
142    /// peripheral clocks are enabled by `new()`. Defaults to Standard mode, 100kHz.
143    pub speed: I2cSpeed,
144    /// Allows setting 7 or 10-bit addresses. Defaults to 7.
145    pub address_bits: AddressBits,
146    /// Select the analog noise filter, a digital filter, or no filter. Deafults to analog.
147    pub noise_filter: NoiseFilter,
148    /// Support for SMBUS, including hardware PEC, and alert pin. Defaults to false.
149    pub smbus: bool,
150    /// Optionally disable clock stretching. Defaults to false (stretching allowed).
151    /// Only relevant in slave mode.
152    pub nostretch: bool,
153}
154
155impl Default for I2cConfig {
156    fn default() -> Self {
157        Self {
158            mode: I2cMode::Master,
159            speed: I2cSpeed::Standard100K,
160            address_bits: AddressBits::B7,
161            noise_filter: NoiseFilter::Analog,
162            smbus: false,
163            nostretch: false,
164        }
165    }
166}
167
168/// Represents an Inter-Integrated Circuit (I2C) peripheral.
169pub struct I2c<R> {
170    pub regs: R,
171    pub cfg: I2cConfig,
172}
173
174impl<R> I2c<R>
175where
176    R: Deref<Target = pac::i2c1::RegisterBlock> + RccPeriph,
177{
178    /// Initialize a I2C peripheral, including configuration register writes, and enabling and resetting
179    /// its RCC peripheral clock. `freq` is in Hz.
180    pub fn new(regs: R, cfg: I2cConfig, clocks: &Clocks) -> Self {
181        let rcc = unsafe { &(*RCC::ptr()) };
182        R::en_reset(rcc);
183
184        // Make sure the I2C unit is disabled so we can configure it
185        regs.cr1().modify(|_, w| w.pe().clear_bit());
186
187        // todo: Slave currently nonfunctional!
188        // todo: Check out the RM recipes for slave transmitter and receiver.
189
190        // RM: I2C timings:
191        // The timings must be configured in order to guarantee a correct data hold and setup time,
192        // used in master and slave modes. This is done by programming the PRESC[3:0],
193        // SCLDEL[3:0] and SDADEL[3:0] bits in the I2C_TIMINGR register.
194        // ... Additionally, in master mode, the SCL clock high and low levels must be configured by
195        // programming the PRESC[3:0], SCLH[7:0] and SCLL[7:0] bits in the I2C_TIMINGR register
196
197        // For these speed and frequency variables, we use the RM's conventions.
198        let t_i2cclk = clocks.apb1();
199
200        // assert!(t_i2cclk < (t_low - f_f) / 4);
201        // assert!(t_i2cclk < t_high);
202
203        // Set the prescaler using RM tables as a guide;
204        // L552 RM, Tables 324 - 326: Examples of timings settings.
205        // Note that the table only includes I2C clock multiples of 4Mhz (well, multiples of 8Mhz).
206        // In this case, we'll use the integer floor rounding to handle in-between
207        // values.
208
209        // We use this constant in several calculations.
210        let presc_const = match cfg.speed {
211            I2cSpeed::Standard10K => 4_000_000,
212            I2cSpeed::Standard100K => 4_000_000,
213            I2cSpeed::Fast400K => 8_000_000,
214            // Note: The 16Mhz example uses F+ / 16. The other 2 examples
215            // use 8e6.
216            I2cSpeed::FastPlus1M => 8_000_000,
217        };
218
219        // This is (offset by 1) which we set as the prescaler.
220        let mut presc_val = t_i2cclk / presc_const;
221
222        // The tables don't show faster I2C input clocks than 48Mhz, but it often will be.
223        // For example, an 80Mhz APB clock will peg prescaler at its maximum value.
224        // Let's just set it to this max. (Maybe we should use fast mode etc if this is so?)
225        if presc_val > 16 {
226            presc_val = 16;
227        }
228
229        // Hit the target freq by setting up t_scll (Period of SCL low)
230        // to be half the whole period. These constants
231        // are from the tables.
232        let freq = match cfg.speed {
233            I2cSpeed::Standard10K => 10_000,
234            I2cSpeed::Standard100K => 100_000,
235            I2cSpeed::Fast400K => 400_000,
236            I2cSpeed::FastPlus1M => 1_000_000,
237        };
238
239        // Set SCLL (SCL low time) to be half the duty period
240        // associated with the target frequency.
241        // todo: QC this is right if you peg presc_val at 16.
242        let scll_val;
243        if presc_val == 16 {
244            // IF we peg presc, we need to modify out calculation of scll (??)
245            scll_val = (t_i2cclk / presc_val) / (2 * freq);
246        } else {
247            scll_val = presc_const / (2 * freq);
248        }
249
250        // SCLH is smaller than SCLH. For standard mode it's close, although
251        // in the example tables, 20% different for 100Khz, and 2% different for
252        // 10K. THis may be due to delays
253        // involved. The ratio is different for Fast-mode and Fast-mode+.
254        // todo: Come back to this. How should we set this?
255        let sclh_val = match cfg.speed {
256            I2cSpeed::Standard10K => scll_val - 4,
257            I2cSpeed::Standard100K => scll_val - 4,
258            I2cSpeed::Fast400K => scll_val * 4 / 10,
259            I2cSpeed::FastPlus1M => scll_val / 2,
260        };
261
262        // Timing prescaler. This field is used to prescale I2CCLK in order to generate the clock period tPRESC used for
263        // data setup and hold counters (refer to I2C timings on page 1495) and for SCL high and low
264        // level counters (refer to I2C master initialization on page 1510).
265        // Sets TIMINGR reg, PRESC field.
266
267        let presc = presc_val - 1;
268
269        // SCL low period (master mode)
270        // This field is used to generate the SCL low period in master mode.
271        // tSCLL = (SCLL+1) x tPRESC
272        // Note: SCLL is also used to generate tBUF and tSU:STA timings.
273        // Sets TIMINGR reg, SCLL field.
274        let scll = scll_val - 1;
275
276        // SCL high period (master mode)
277        // This field is used to generate the SCL high period in master mode.
278        // tSCLH = (SCLH+1) x tPRESC
279        // Note: SCLH is also used to generate tSU:STO and tHD:STA timing
280        // Set the clock prescaler value. Sets TIMINGR reg, SCLH field.
281        let sclh = sclh_val - 1;
282
283        // todo: Can't find the sdadel and scldel pattern
284        // Data hold time
285        // This field is used to generate the delay tSDADEL between SCL falling edge and SDA edge. In
286        // master mode and in slave mode with NOSTRETCH = 0, the SCL line is stretched low during
287        // tSDADEL.
288        // tSDADEL= SDADEL x tPRESC
289        // Note: SDADEL is used to generate tHD:DAT timing
290        // Sets TIMINGR reg, SDADEL field.
291        let sdadel = match cfg.speed {
292            I2cSpeed::Standard10K => 0x2,
293            I2cSpeed::Standard100K => 0x2,
294            I2cSpeed::Fast400K => 0x3,
295            I2cSpeed::FastPlus1M => 0x0,
296        };
297
298        // Data setup time
299        // This field is used to generate a delay tSCLDEL between SDA edge and SCL rising edge. In
300        // master mode and in slave mode with NOSTRETCH = 0, the SCL line is stretched low during
301        // tSCLDEL.
302        // tSCLDEL = (SCLDEL+1) x tPRESC
303        // Note: tSCLDEL is used to generate tSU:DAT timing
304        // Sets TIMINGR reg, SCLDEL field.
305        let scldel = match cfg.speed {
306            I2cSpeed::Standard10K => 0x4,
307            I2cSpeed::Standard100K => 0x4,
308            I2cSpeed::Fast400K => 0x3,
309            I2cSpeed::FastPlus1M => 0x1,
310        };
311
312        // The fields for PRESC, SCLDEL, and SDADEL are 4-bits; don't overflow.
313        // The other TIMINGR fields we set are 8-bits, so won't overflow with u8.
314        assert!(presc <= 15);
315        assert!(scldel <= 15);
316        assert!(sdadel <= 15);
317
318        assert!(scll <= 255);
319        assert!(sclh <= 255);
320
321        regs.timingr().write(|w| unsafe {
322            w.presc().bits(presc as u8);
323            w.scldel().bits(scldel as u8);
324            w.sdadel().bits(sdadel as u8);
325            w.sclh().bits(sclh as u8);
326            w.scll().bits(scll as u8)
327        });
328
329        // Before enabling the I2C peripheral by setting the PE bit in I2C_CR1 register, the user must
330        // configure the noise filters, if needed. By default, an analog noise filter is present on the SDA
331        // and SCL inputs. This analog filter is compliant with the I2C specification which requires the
332        // suppression of spikes with a pulse width up to 50 ns in Fast-mode and Fast-mode Plus. The
333        // user can disable this analog filter by setting the ANFOFF bit, and/or select a digital filter by
334        // configuring the DNF[3:0] bit in the I2C_CR1 register.
335        // When the digital filter is enabled, the level of the SCL or the SDA line is internally changed
336        // only if it remains stable for more than DNF x I2CCLK periods. This allows spikes with a
337        // programmable length of 1 to 15 I2CCLK periods to be suppressed.
338        let (anf_bit, dnf_bits) = match cfg.noise_filter {
339            NoiseFilter::Analog => (false, 0),
340            NoiseFilter::Digital(filtering_len) => {
341                assert!(filtering_len <= 0b1111);
342                (true, filtering_len)
343            }
344            NoiseFilter::Disabled => (true, 0),
345        };
346
347        regs.cr1().modify(|_, w| unsafe {
348            w.anfoff().bit(anf_bit);
349            w.dnf().bits(dnf_bits)
350        });
351
352        if let I2cMode::Slave = cfg.mode {
353            regs.cr1().modify(|_, w| w.nostretch().bit(cfg.nostretch));
354        }
355
356        let mut result = Self { regs, cfg };
357
358        if result.cfg.smbus {
359            result.enable_smbus().ok();
360        }
361
362        // Enable the peripheral
363        result.regs.cr1().write(|w| w.pe().bit(true));
364
365        result
366    }
367
368    /// Enable SMBus support. See L44 RM, section 37.4.11: SMBus initialization
369    pub fn enable_smbus(&mut self) -> Result<()> {
370        // todo: Roll this into an init setting or I2cConfig struct etc.
371        // PEC calculation is enabled by setting the PECEN bit in the I2C_CR1 register. Then the PEC
372        // transfer is managed with the help of a hardware byte counter: NBYTES[7:0] in the I2C_CR2
373        // register. The PECEN bit must be configured before enabling the I2C.
374
375        // The PEC transfer is managed with the hardware byte counter, so the SBC bit must be set
376        // when interfacing the SMBus in slave mode. The PEC is transferred after NBYTES-1 data
377        // have been transferred when the PECBYTE bit is set and the RELOAD bit is cleared. If
378        // RELOAD is set, PECBYTE has no effect.
379        // Caution: Changing the PECEN configuration is not allowed when the I2C is enabled.
380
381        let originally_enabled = self.regs.cr1().read().pe().bit_is_set();
382        if originally_enabled {
383            self.regs.cr1().modify(|_, w| w.pe().clear_bit());
384
385            let mut i = 0;
386            while self.regs.cr1().read().pe().bit_is_set() {
387                i += 1;
388                if i >= MAX_ITERS {
389                    return Err(Error::I2cError(I2cError::Hardware));
390                }
391            }
392        }
393
394        self.regs.cr1().modify(|_, w| w.pecen().bit(true));
395
396        // todo: Timeout detection?
397
398        // todo: HWCFGR Missing from PAC
399        // self.regs.hwcfgr().modify(|_, w| w.smbus().bit(true));
400
401        if originally_enabled {
402            self.regs.cr1().modify(|_, w| w.pe().bit(true));
403        }
404
405        Ok(())
406    }
407
408    /// Read multiple words to a buffer. Can return an error due to Bus, Arbitration, or NACK.
409    pub fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<()> {
410        // Wait for any previous address sequence to end
411        // automatically. This could be up to 50% of a bus
412        // cycle (ie. up to 0.5/freq)
413
414        let mut i = 0;
415        while self.regs.cr2().read().start().bit_is_set() {
416            i += 1;
417            if i >= MAX_ITERS {
418                return Err(Error::I2cError(I2cError::Hardware));
419            }
420        }
421
422        // Set START and prepare to receive bytes into
423        // `buffer`. The START bit can be set even if the bus
424        // is BUSY or I2C is in slave mode.
425        self.set_cr2_read(addr, bytes.len() as u8);
426
427        for byte in bytes {
428            // Wait until we have received something
429            busy_wait!(self.regs, rxne);
430
431            *byte = self.regs.rxdr().read().rxdata().bits();
432        }
433
434        Ok(())
435    }
436
437    /// Write an array of words. Can return an error due to Bus, Arbitration, or NACK.
438    pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<()> {
439        // Wait for any previous address sequence to end
440        // automatically. This could be up to 50% of a bus
441        // cycle (ie. up to 0.5/freq)
442        let mut i = 0;
443        while self.regs.cr2().read().start().bit_is_set() {
444            i += 1;
445            if i >= MAX_ITERS {
446                return Err(Error::I2cError(I2cError::Hardware));
447            }
448        }
449
450        self.set_cr2_write(addr, bytes.len() as u8, true);
451
452        for byte in bytes {
453            // Wait until we are allowed to send data
454            // (START has been ACKed or last byte when
455            // through)
456            busy_wait!(self.regs, txis); // TXDR register is empty
457
458            // Put byte on the wire
459            self.regs
460                .txdr()
461                .write(|w| unsafe { w.txdata().bits(*byte) });
462        }
463
464        Ok(())
465    }
466
467    /// Write and read an array of words. Can return an error due to Bus, Arbitration, or NACK.
468    pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<()> {
469        // Wait for any previous address sequence to end
470        // automatically. This could be up to 50% of a bus
471        // cycle (ie. up to 0.5/freq)
472        let mut i = 0;
473        while self.regs.cr2().read().start().bit_is_set() {
474            i += 1;
475            if i >= MAX_ITERS {
476                return Err(Error::I2cError(I2cError::Hardware));
477            }
478        }
479
480        self.set_cr2_write(addr, bytes.len() as u8, false);
481
482        for byte in bytes {
483            // Wait until we are allowed to send data
484            // (START has been ACKed or last byte went through)
485
486            busy_wait!(self.regs, txis); // TXDR register is empty
487
488            // Put byte on the wire
489            self.regs
490                .txdr()
491                .write(|w| unsafe { w.txdata().bits(*byte) });
492        }
493
494        // Wait until the write finishes before beginning to read.
495        busy_wait!(self.regs, tc); // transfer is complete
496
497        // reSTART and prepare to receive bytes into `buffer`
498
499        self.set_cr2_read(addr, buffer.len() as u8);
500
501        for byte in buffer {
502            // Wait until we have received something
503            busy_wait!(self.regs, rxne);
504
505            *byte = self.regs.rxdr().read().rxdata().bits();
506        }
507
508        Ok(())
509    }
510
511    /// Helper function to prevent repetition between `write`, `write_read`, and `write_dma`.
512    fn set_cr2_write(&mut self, addr: u8, len: u8, autoend: bool) {
513        // L44 RM: "Master communication initialization (address phase)
514        // In order to initiate the communication, the user must program the following parameters for
515        // the addressed slave in the I2C_CR2 register:
516        self.regs.cr2().write(|w| {
517            unsafe {
518                // Addressing mode (7-bit or 10-bit): ADD10
519                w.add10().bit(self.cfg.address_bits as u8 != 0);
520                // Slave address to be sent: SADD[9:0]
521                // SADD0: "This bit is don’t care"
522                // SADD[7:1]: "These bits should be written with the 7-bit slave address to be sent"
523                w.sadd().bits((addr << 1) as u16);
524                // Transfer direction: RD_WRN
525                w.rd_wrn().clear_bit(); // write
526                // The number of bytes to be transferred: NBYTES[7:0]. If the number of bytes is equal to
527                // or greater than 255 bytes, NBYTES[7:0] must initially be filled with 0xFF.
528                w.nbytes().bits(len);
529                w.autoend().bit(autoend); // software end mode
530                // The user must then set the START bit in I2C_CR2 register. Changing all the above bits is
531                // not allowed when START bit is set.
532                // When the SMBus master wants to transmit the PEC, the PECBYTE bit must be set and the
533                // number of bytes must be programmed in the NBYTES[7:0] field, before setting the START
534                // bit. In this case the total number of TXIS interrupts is NBYTES-1. So if the PECBYTE bit is
535                // set when NBYTES=0x1, the content of the I2C_PECR register is automatically transmitted.
536                // If the SMBus master wants to send a STOP condition after the PEC, automatic end mode
537                // must be selected (AUTOEND=1). In this case, the STOP condition automatically follows the
538                // PEC transmission.
539                w.pecbyte().bit(self.cfg.smbus);
540                w.start().bit(true)
541            }
542        });
543        // Note on start bit (RM):
544        // If the I2C is already in master mode with AUTOEND = 0, setting this bit generates a
545        // Repeated Start condition when RELOAD=0, after the end of the NBYTES transfer.
546        // Otherwise setting this bit generates a START condition once the bus is free.
547        // (This is why we don't set autoend on the write portion of a write_read.)
548    }
549
550    /// Helper function to prevent repetition between `read`, `write_read`, and `read_dma`.
551    fn set_cr2_read(&mut self, addr: u8, len: u8) {
552        self.regs.cr2().write(|w| {
553            unsafe {
554                w.add10().bit(self.cfg.address_bits as u8 != 0);
555                w.sadd().bits((addr << 1) as u16);
556                w.rd_wrn().bit(true); // read
557                w.nbytes().bits(len);
558                w.autoend().bit(true); // automatic end mode
559                // When the SMBus master wants to receive the PEC followed by a STOP at the end of the
560                // transfer, automatic end mode can be selected (AUTOEND=1). The PECBYTE bit must be
561                // set and the slave address must be programmed, before setting the START bit. In this case,
562                // after NBYTES-1 data have been received, the next received byte is automatically checked
563                // versus the I2C_PECR register content. A NACK response is given to the PEC byte, followed
564                // by a STOP condition.
565                w.pecbyte().bit(self.cfg.smbus);
566                w.start().bit(true)
567            }
568        });
569    }
570
571    #[cfg(not(feature = "g0"))]
572    /// Read data, using DMA. See L44 RM, 37.4.16: "Transmission using DMA"
573    /// Note that the `channel` argument is unused on F3 and L4, since it is hard-coded,
574    /// and can't be configured using the DMAMUX peripheral. (`dma::mux()` fn).
575    /// For a single write, set `autoend` to `true`. For a write_read and other use cases,
576    /// set it to `false`.
577    #[cfg(not(any(feature = "l552", feature = "h5")))]
578    pub unsafe fn write_dma(
579        &mut self,
580        addr: u8,
581        buf: &[u8],
582        autoend: bool,
583        channel: DmaChannel,
584        channel_cfg: ChannelCfg,
585        dma_periph: dma::DmaPeriph,
586    ) {
587        let (ptr, len) = (buf.as_ptr(), buf.len());
588
589        #[cfg(any(feature = "f3", feature = "l4"))]
590        let channel = R::write_chan();
591        #[cfg(feature = "l4")]
592        let mut dma_regs = unsafe { &(*DMA1::ptr()) }; // todo: Hardcoded DMA1
593        #[cfg(feature = "l4")]
594        R::write_sel(&mut dma_regs);
595
596        // DMA (Direct Memory Access) can be enabled for transmission by setting the TXDMAEN bit
597        // in the I2C_CR1 register. Data is loaded from an SRAM area configured using the DMA
598        // peripheral (see Section 11: Direct memory access controller (DMA) on page 295) to the
599        // I2C_TXDR register whenever the TXIS bit is set.
600        self.regs.cr1().modify(|_, w| w.txdmaen().bit(true));
601        while self.regs.cr1().read().txdmaen().bit_is_clear() {}
602
603        // Only the data are transferred with DMA.
604        // • In master mode: the initialization, the slave address, direction, number of bytes and
605        // START bit are programmed by software (the transmitted slave address cannot be
606        // transferred with DMA). When all data are transferred using DMA, the DMA must be
607        // initialized before setting the START bit. The end of transfer is managed with the
608        // NBYTES counter. Refer to Master transmitter on page 1151.
609        // (The steps above are handled in the write this function performs.)
610        self.set_cr2_write(addr, len as u8, autoend);
611
612        // • In slave mode:
613        // – With NOSTRETCH=0, when all data are transferred using DMA, the DMA must be
614        // initialized before the address match event, or in ADDR interrupt subroutine, before
615        // clearing ADDR.
616        // – With NOSTRETCH=1, the DMA must be initialized before the address match
617        // event.
618
619        // • For instances supporting SMBus: the PEC transfer is managed with NBYTES counter.
620        // Refer to SMBus Slave transmitter on page 1165 and SMBus Master transmitter on
621        // page 1169.
622        // Note: If DMA is used for transmission, the TXIE bit does not need to be enabled
623
624        // #[cfg(feature = "h7")]
625        let num_data = len as u32;
626        // #[cfg(not(feature = "h7"))]
627        // let num_data = len as u16;
628
629        match dma_periph {
630            dma::DmaPeriph::Dma1 => {
631                let mut regs = unsafe { &(*DMA1::ptr()) };
632                dma::cfg_channel(
633                    &mut regs,
634                    channel,
635                    self.regs.txdr().as_ptr() as u32,
636                    ptr as u32,
637                    num_data,
638                    dma::Direction::ReadFromMem,
639                    dma::DataSize::S8,
640                    dma::DataSize::S8,
641                    channel_cfg,
642                );
643            }
644            #[cfg(dma2)]
645            dma::DmaPeriph::Dma2 => {
646                let mut regs = unsafe { &(*pac::DMA2::ptr()) };
647                dma::cfg_channel(
648                    &mut regs,
649                    channel,
650                    self.regs.txdr().as_ptr() as u32,
651                    ptr as u32,
652                    num_data,
653                    dma::Direction::ReadFromMem,
654                    dma::DataSize::S8,
655                    dma::DataSize::S8,
656                    channel_cfg,
657                );
658            }
659        }
660    }
661
662    /// Read data, using DMA. See L44 RM, 37.4.16: "Reception using DMA"
663    /// Note that the `channel` argument is unused on F3 and L4, since it is hard-coded,
664    /// and can't be configured using the DMAMUX peripheral. (`dma::mux()` fn).
665    #[cfg(not(any(feature = "l552", feature = "h5")))]
666    pub unsafe fn read_dma(
667        &mut self,
668        addr: u8,
669        buf: &mut [u8],
670        channel: DmaChannel,
671        channel_cfg: ChannelCfg,
672        dma_periph: dma::DmaPeriph,
673    ) {
674        let (ptr, len) = (buf.as_mut_ptr(), buf.len());
675
676        #[cfg(any(feature = "f3", feature = "l4"))]
677        let channel = R::read_chan();
678        #[cfg(feature = "l4")]
679        let mut dma_regs = unsafe { &(*DMA1::ptr()) }; // todo: Hardcoded DMA1
680        #[cfg(feature = "l4")]
681        R::write_sel(&mut dma_regs);
682
683        // DMA (Direct Memory Access) can be enabled for reception by setting the RXDMAEN bit in
684        // the I2C_CR1 register. Data is loaded from the I2C_RXDR register to an SRAM area
685        // configured using the DMA peripheral (refer to Section 11: Direct memory access controller
686        // (DMA) on page 295) whenever the RXNE bit is set. Only the data (including PEC) are
687        // transferred with DMA.
688        self.regs.cr1().modify(|_, w| w.rxdmaen().bit(true));
689        while self.regs.cr1().read().rxdmaen().bit_is_clear() {}
690
691        // • In master mode, the initialization, the slave address, direction, number of bytes and
692        // START bit are programmed by software. When all data are transferred using DMA, the
693        // DMA must be initialized before setting the START bit. The end of transfer is managed
694        // with the NBYTES counter.
695        self.set_cr2_read(addr, len as u8);
696
697        // • In slave mode with NOSTRETCH=0, when all data are transferred using DMA, the
698        // DMA must be initialized before the address match event, or in the ADDR interrupt
699        // subroutine, before clearing the ADDR flag.
700        // • If SMBus is supported (see Section 37.3: I2C implementation): the PEC transfer is
701        // managed with the NBYTES counter. Refer to SMBus Slave receiver on page 1167 and
702        // SMBus Master receiver on page 1171.
703        // Note: If DMA is used for reception, the RXIE bit does not need to be enabled
704
705        let num_data = len as u32;
706
707        match dma_periph {
708            dma::DmaPeriph::Dma1 => {
709                let mut regs = unsafe { &(*DMA1::ptr()) };
710                dma::cfg_channel(
711                    &mut regs,
712                    channel,
713                    self.regs.rxdr().as_ptr() as u32,
714                    ptr as u32,
715                    num_data,
716                    dma::Direction::ReadFromPeriph,
717                    dma::DataSize::S8,
718                    dma::DataSize::S8,
719                    channel_cfg,
720                );
721            }
722            #[cfg(dma2)]
723            dma::DmaPeriph::Dma2 => {
724                let mut regs = unsafe { &(*pac::DMA2::ptr()) };
725                dma::cfg_channel(
726                    &mut regs,
727                    channel,
728                    self.regs.rxdr().as_ptr() as u32,
729                    ptr as u32,
730                    num_data,
731                    dma::Direction::ReadFromPeriph,
732                    dma::DataSize::S8,
733                    dma::DataSize::S8,
734                    channel_cfg,
735                );
736            }
737        }
738    }
739
740    /// Print the (raw) contents of the status register.
741    pub fn read_status(&self) -> u32 {
742        unsafe { self.regs.isr().read().bits() }
743    }
744}
745//
746// #[cfg(feature = "embedded_hal")]
747// // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
748// impl<R> Write for I2c<R>
749// where
750//     R: Deref<Target = pac::i2c1::RegisterBlock> + RccPeriph,
751// {
752//     type Error = Error;
753//
754//     fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
755//         I2c::write(self, addr, bytes)
756//     }
757// }
758//
759// #[cfg(feature = "embedded_hal")]
760// // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
761// impl<R> Read for I2c<R>
762// where
763//     R: Deref<Target = pac::i2c1::RegisterBlock> + RccPeriph,
764// {
765//     type Error = Error;
766//
767//     fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> {
768//         I2c::read(self, addr, bytes)
769//     }
770// }
771//
772// #[cfg(feature = "embedded_hal")]
773// // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
774// impl<R> WriteRead for I2c<R>
775// where
776//     R: Deref<Target = pac::i2c1::RegisterBlock> + RccPeriph,
777// {
778//     type Error = Error;
779//
780//     fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
781//         I2c::write_read(self, addr, bytes, buffer)
782//     }
783// }