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