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// }