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