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