aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-04-15 23:40:12 +0200
committerDario Nieuwenhuis <[email protected]>2024-04-15 23:40:12 +0200
commit913bb19a34b88e996972c6666679b2b99ae01ce0 (patch)
tree45dfaa958f46d2f6f55e46cccd269366c2fe6df3
parent2eab099b85a7e0ba10d1f558dce89112cd577c68 (diff)
stm32/i2c: remove DMA generic params.
-rw-r--r--embassy-stm32/src/i2c/mod.rs61
-rw-r--r--embassy-stm32/src/i2c/v1.rs50
-rw-r--r--embassy-stm32/src/i2c/v2.rs276
-rw-r--r--examples/stm32f4/src/bin/i2c.rs18
-rw-r--r--examples/stm32l4/src/bin/i2c.rs18
-rw-r--r--examples/stm32l4/src/bin/i2c_blocking_async.rs18
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs2
-rw-r--r--examples/stm32u5/src/bin/i2c.rs18
8 files changed, 189 insertions, 272 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index a46061d54..ccbea9831 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -14,9 +14,10 @@ use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 15use embassy_time::{Duration, Instant};
16 16
17use crate::dma::NoDma; 17use crate::dma::ChannelAndRequest;
18use crate::gpio::{AFType, Pull}; 18use crate::gpio::{AFType, Pull};
19use crate::interrupt::typelevel::Interrupt; 19use crate::interrupt::typelevel::Interrupt;
20use crate::mode::{Async, Blocking, Mode};
20use crate::time::Hertz; 21use crate::time::Hertz;
21use crate::{interrupt, peripherals}; 22use crate::{interrupt, peripherals};
22 23
@@ -71,17 +72,16 @@ impl Default for Config {
71} 72}
72 73
73/// I2C driver. 74/// I2C driver.
74pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { 75pub struct I2c<'d, T: Instance, M: Mode> {
75 _peri: PeripheralRef<'d, T>, 76 _peri: PeripheralRef<'d, T>,
76 #[allow(dead_code)] 77 tx_dma: Option<ChannelAndRequest<'d>>,
77 tx_dma: PeripheralRef<'d, TXDMA>, 78 rx_dma: Option<ChannelAndRequest<'d>>,
78 #[allow(dead_code)]
79 rx_dma: PeripheralRef<'d, RXDMA>,
80 #[cfg(feature = "time")] 79 #[cfg(feature = "time")]
81 timeout: Duration, 80 timeout: Duration,
81 _phantom: PhantomData<M>,
82} 82}
83 83
84impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { 84impl<'d, T: Instance> I2c<'d, T, Async> {
85 /// Create a new I2C driver. 85 /// Create a new I2C driver.
86 pub fn new( 86 pub fn new(
87 peri: impl Peripheral<P = T> + 'd, 87 peri: impl Peripheral<P = T> + 'd,
@@ -90,12 +90,40 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
90 _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>> 90 _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
91 + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>> 91 + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
92 + 'd, 92 + 'd,
93 tx_dma: impl Peripheral<P = TXDMA> + 'd, 93 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
94 rx_dma: impl Peripheral<P = RXDMA> + 'd, 94 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
95 freq: Hertz, 95 freq: Hertz,
96 config: Config, 96 config: Config,
97 ) -> Self { 97 ) -> Self {
98 into_ref!(peri, scl, sda, tx_dma, rx_dma); 98 Self::new_inner(peri, scl, sda, new_dma!(tx_dma), new_dma!(rx_dma), freq, config)
99 }
100}
101
102impl<'d, T: Instance> I2c<'d, T, Blocking> {
103 /// Create a new blocking I2C driver.
104 pub fn new_blocking(
105 peri: impl Peripheral<P = T> + 'd,
106 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
107 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
108 freq: Hertz,
109 config: Config,
110 ) -> Self {
111 Self::new_inner(peri, scl, sda, None, None, freq, config)
112 }
113}
114
115impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
116 /// Create a new I2C driver.
117 fn new_inner(
118 peri: impl Peripheral<P = T> + 'd,
119 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
120 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
121 tx_dma: Option<ChannelAndRequest<'d>>,
122 rx_dma: Option<ChannelAndRequest<'d>>,
123 freq: Hertz,
124 config: Config,
125 ) -> Self {
126 into_ref!(peri, scl, sda);
99 127
100 T::enable_and_reset(); 128 T::enable_and_reset();
101 129
@@ -125,6 +153,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
125 rx_dma, 153 rx_dma,
126 #[cfg(feature = "time")] 154 #[cfg(feature = "time")]
127 timeout: config.timeout, 155 timeout: config.timeout,
156 _phantom: PhantomData,
128 }; 157 };
129 158
130 this.init(freq, config); 159 this.init(freq, config);
@@ -249,7 +278,7 @@ foreach_peripheral!(
249 }; 278 };
250); 279);
251 280
252impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { 281impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, T, M> {
253 type Error = Error; 282 type Error = Error;
254 283
255 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 284 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
@@ -257,7 +286,7 @@ impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> {
257 } 286 }
258} 287}
259 288
260impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> { 289impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, T, M> {
261 type Error = Error; 290 type Error = Error;
262 291
263 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { 292 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
@@ -265,7 +294,7 @@ impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> {
265 } 294 }
266} 295}
267 296
268impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> { 297impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T, M> {
269 type Error = Error; 298 type Error = Error;
270 299
271 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { 300 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
@@ -289,11 +318,11 @@ impl embedded_hal_1::i2c::Error for Error {
289 } 318 }
290} 319}
291 320
292impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for I2c<'d, T, TXDMA, RXDMA> { 321impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, T, M> {
293 type Error = Error; 322 type Error = Error;
294} 323}
295 324
296impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> { 325impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> {
297 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 326 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
298 self.blocking_read(address, read) 327 self.blocking_read(address, read)
299 } 328 }
@@ -315,7 +344,7 @@ impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> {
315 } 344 }
316} 345}
317 346
318impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c for I2c<'d, T, TXDMA, RXDMA> { 347impl<'d, T: Instance> embedded_hal_async::i2c::I2c for I2c<'d, T, Async> {
319 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 348 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
320 self.read(address, read).await 349 self.read(address, read).await
321 } 350 }
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index d45c48b24..13a473344 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -13,7 +13,7 @@ use embassy_hal_internal::drop::OnDrop;
13use embedded_hal_1::i2c::Operation; 13use embedded_hal_1::i2c::Operation;
14 14
15use super::*; 15use super::*;
16use crate::dma::Transfer; 16use crate::mode::Mode as PeriMode;
17use crate::pac::i2c; 17use crate::pac::i2c;
18 18
19// /!\ /!\ 19// /!\ /!\
@@ -41,7 +41,7 @@ pub unsafe fn on_interrupt<T: Instance>() {
41 }); 41 });
42} 42}
43 43
44impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { 44impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
45 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 45 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
46 T::regs().cr1().modify(|reg| { 46 T::regs().cr1().modify(|reg| {
47 reg.set_pe(false); 47 reg.set_pe(false);
@@ -326,11 +326,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
326 w.set_itevten(true); 326 w.set_itevten(true);
327 }); 327 });
328 } 328 }
329}
329 330
330 async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> 331impl<'d, T: Instance> I2c<'d, T, Async> {
331 where 332 async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> {
332 TXDMA: crate::i2c::TxDma<T>,
333 {
334 T::regs().cr2().modify(|w| { 333 T::regs().cr2().modify(|w| {
335 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for 334 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
336 // reception. 335 // reception.
@@ -415,9 +414,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
415 // this address from the memory after each TxE event. 414 // this address from the memory after each TxE event.
416 let dst = T::regs().dr().as_ptr() as *mut u8; 415 let dst = T::regs().dr().as_ptr() as *mut u8;
417 416
418 let ch = &mut self.tx_dma; 417 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default())
419 let request = ch.request();
420 Transfer::new_write(ch, request, write, dst, Default::default())
421 }; 418 };
422 419
423 // Wait for bytes to be sent, or an error to occur. 420 // Wait for bytes to be sent, or an error to occur.
@@ -479,10 +476,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
479 } 476 }
480 477
481 /// Write. 478 /// Write.
482 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> 479 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
483 where
484 TXDMA: crate::i2c::TxDma<T>,
485 {
486 self.write_frame(address, write, FrameOptions::FirstAndLastFrame) 480 self.write_frame(address, write, FrameOptions::FirstAndLastFrame)
487 .await?; 481 .await?;
488 482
@@ -490,20 +484,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
490 } 484 }
491 485
492 /// Read. 486 /// Read.
493 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> 487 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
494 where
495 RXDMA: crate::i2c::RxDma<T>,
496 {
497 self.read_frame(address, buffer, FrameOptions::FirstAndLastFrame) 488 self.read_frame(address, buffer, FrameOptions::FirstAndLastFrame)
498 .await?; 489 .await?;
499 490
500 Ok(()) 491 Ok(())
501 } 492 }
502 493
503 async fn read_frame(&mut self, address: u8, buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> 494 async fn read_frame(&mut self, address: u8, buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> {
504 where
505 RXDMA: crate::i2c::RxDma<T>,
506 {
507 if buffer.is_empty() { 495 if buffer.is_empty() {
508 return Err(Error::Overrun); 496 return Err(Error::Overrun);
509 } 497 }
@@ -623,9 +611,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
623 // from this address from the memory after each RxE event. 611 // from this address from the memory after each RxE event.
624 let src = T::regs().dr().as_ptr() as *mut u8; 612 let src = T::regs().dr().as_ptr() as *mut u8;
625 613
626 let ch = &mut self.rx_dma; 614 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
627 let request = ch.request();
628 Transfer::new_read(ch, request, src, buffer, Default::default())
629 }; 615 };
630 616
631 // Wait for bytes to be received, or an error to occur. 617 // Wait for bytes to be received, or an error to occur.
@@ -664,11 +650,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
664 } 650 }
665 651
666 /// Write, restart, read. 652 /// Write, restart, read.
667 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> 653 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
668 where
669 RXDMA: crate::i2c::RxDma<T>,
670 TXDMA: crate::i2c::TxDma<T>,
671 {
672 // Check empty read buffer before starting transaction. Otherwise, we would not generate the 654 // Check empty read buffer before starting transaction. Otherwise, we would not generate the
673 // stop condition below. 655 // stop condition below.
674 if read.is_empty() { 656 if read.is_empty() {
@@ -684,11 +666,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
684 /// Consecutive operations of same type are merged. See [transaction contract] for details. 666 /// Consecutive operations of same type are merged. See [transaction contract] for details.
685 /// 667 ///
686 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 668 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
687 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> 669 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
688 where
689 RXDMA: crate::i2c::RxDma<T>,
690 TXDMA: crate::i2c::TxDma<T>,
691 {
692 for (op, frame) in operation_frames(operations)? { 670 for (op, frame) in operation_frames(operations)? {
693 match op { 671 match op {
694 Operation::Read(read) => self.read_frame(addr, read, frame).await?, 672 Operation::Read(read) => self.read_frame(addr, read, frame).await?,
@@ -700,7 +678,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
700 } 678 }
701} 679}
702 680
703impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { 681impl<'d, T: Instance, M: PeriMode> Drop for I2c<'d, T, M> {
704 fn drop(&mut self) { 682 fn drop(&mut self) {
705 T::disable(); 683 T::disable();
706 } 684 }
@@ -806,7 +784,7 @@ impl Timings {
806 } 784 }
807} 785}
808 786
809impl<'d, T: Instance> SetConfig for I2c<'d, T> { 787impl<'d, T: Instance, M: PeriMode> SetConfig for I2c<'d, T, M> {
810 type Config = Hertz; 788 type Config = Hertz;
811 type ConfigError = (); 789 type ConfigError = ();
812 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { 790 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index da3b0ee30..12df98534 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -7,7 +7,6 @@ use embassy_hal_internal::drop::OnDrop;
7use embedded_hal_1::i2c::Operation; 7use embedded_hal_1::i2c::Operation;
8 8
9use super::*; 9use super::*;
10use crate::dma::Transfer;
11use crate::pac::i2c; 10use crate::pac::i2c;
12 11
13pub(crate) unsafe fn on_interrupt<T: Instance>() { 12pub(crate) unsafe fn on_interrupt<T: Instance>() {
@@ -24,7 +23,7 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() {
24 }); 23 });
25} 24}
26 25
27impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { 26impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
28 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 27 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
29 T::regs().cr1().modify(|reg| { 28 T::regs().cr1().modify(|reg| {
30 reg.set_pe(false); 29 reg.set_pe(false);
@@ -302,6 +301,119 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
302 result 301 result
303 } 302 }
304 303
304 // =========================
305 // Blocking public API
306
307 /// Blocking read.
308 pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
309 self.read_internal(address, read, false, self.timeout())
310 // Automatic Stop
311 }
312
313 /// Blocking write.
314 pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
315 self.write_internal(address, write, true, self.timeout())
316 }
317
318 /// Blocking write, restart, read.
319 pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
320 let timeout = self.timeout();
321 self.write_internal(address, write, false, timeout)?;
322 self.read_internal(address, read, true, timeout)
323 // Automatic Stop
324 }
325
326 /// Blocking transaction with operations.
327 ///
328 /// Consecutive operations of same type are merged. See [transaction contract] for details.
329 ///
330 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
331 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
332 let _ = addr;
333 let _ = operations;
334 todo!()
335 }
336
337 /// Blocking write multiple buffers.
338 ///
339 /// The buffers are concatenated in a single write transaction.
340 pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
341 if write.is_empty() {
342 return Err(Error::ZeroLengthTransfer);
343 }
344
345 let timeout = self.timeout();
346
347 let first_length = write[0].len();
348 let last_slice_index = write.len() - 1;
349
350 if let Err(err) = Self::master_write(
351 address,
352 first_length.min(255),
353 Stop::Software,
354 (first_length > 255) || (last_slice_index != 0),
355 timeout,
356 ) {
357 self.master_stop();
358 return Err(err);
359 }
360
361 for (idx, slice) in write.iter().enumerate() {
362 let slice_len = slice.len();
363 let completed_chunks = slice_len / 255;
364 let total_chunks = if completed_chunks * 255 == slice_len {
365 completed_chunks
366 } else {
367 completed_chunks + 1
368 };
369 let last_chunk_idx = total_chunks.saturating_sub(1);
370
371 if idx != 0 {
372 if let Err(err) = Self::master_continue(
373 slice_len.min(255),
374 (idx != last_slice_index) || (slice_len > 255),
375 timeout,
376 ) {
377 self.master_stop();
378 return Err(err);
379 }
380 }
381
382 for (number, chunk) in slice.chunks(255).enumerate() {
383 if number != 0 {
384 if let Err(err) = Self::master_continue(
385 chunk.len(),
386 (number != last_chunk_idx) || (idx != last_slice_index),
387 timeout,
388 ) {
389 self.master_stop();
390 return Err(err);
391 }
392 }
393
394 for byte in chunk {
395 // Wait until we are allowed to send data
396 // (START has been ACKed or last byte when
397 // through)
398 if let Err(err) = self.wait_txe(timeout) {
399 self.master_stop();
400 return Err(err);
401 }
402
403 // Put byte on the wire
404 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
405 T::regs().txdr().write(|w| w.set_txdata(*byte));
406 }
407 }
408 }
409 // Wait until the write finishes
410 let result = self.wait_tc(timeout);
411 self.master_stop();
412 result
413 }
414}
415
416impl<'d, T: Instance> I2c<'d, T, Async> {
305 async fn write_dma_internal( 417 async fn write_dma_internal(
306 &mut self, 418 &mut self,
307 address: u8, 419 address: u8,
@@ -309,10 +421,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
309 first_slice: bool, 421 first_slice: bool,
310 last_slice: bool, 422 last_slice: bool,
311 timeout: Timeout, 423 timeout: Timeout,
312 ) -> Result<(), Error> 424 ) -> Result<(), Error> {
313 where
314 TXDMA: crate::i2c::TxDma<T>,
315 {
316 let total_len = write.len(); 425 let total_len = write.len();
317 426
318 let dma_transfer = unsafe { 427 let dma_transfer = unsafe {
@@ -325,9 +434,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
325 }); 434 });
326 let dst = regs.txdr().as_ptr() as *mut u8; 435 let dst = regs.txdr().as_ptr() as *mut u8;
327 436
328 let ch = &mut self.tx_dma; 437 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default())
329 let request = ch.request();
330 Transfer::new_write(ch, request, write, dst, Default::default())
331 }; 438 };
332 439
333 let state = T::state(); 440 let state = T::state();
@@ -398,10 +505,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
398 buffer: &mut [u8], 505 buffer: &mut [u8],
399 restart: bool, 506 restart: bool,
400 timeout: Timeout, 507 timeout: Timeout,
401 ) -> Result<(), Error> 508 ) -> Result<(), Error> {
402 where
403 RXDMA: crate::i2c::RxDma<T>,
404 {
405 let total_len = buffer.len(); 509 let total_len = buffer.len();
406 510
407 let dma_transfer = unsafe { 511 let dma_transfer = unsafe {
@@ -412,9 +516,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
412 }); 516 });
413 let src = regs.rxdr().as_ptr() as *mut u8; 517 let src = regs.rxdr().as_ptr() as *mut u8;
414 518
415 let ch = &mut self.rx_dma; 519 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
416 let request = ch.request();
417 Transfer::new_read(ch, request, src, buffer, Default::default())
418 }; 520 };
419 521
420 let state = T::state(); 522 let state = T::state();
@@ -475,10 +577,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
475 // Async public API 577 // Async public API
476 578
477 /// Write. 579 /// Write.
478 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> 580 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
479 where
480 TXDMA: crate::i2c::TxDma<T>,
481 {
482 let timeout = self.timeout(); 581 let timeout = self.timeout();
483 if write.is_empty() { 582 if write.is_empty() {
484 self.write_internal(address, write, true, timeout) 583 self.write_internal(address, write, true, timeout)
@@ -492,10 +591,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
492 /// Write multiple buffers. 591 /// Write multiple buffers.
493 /// 592 ///
494 /// The buffers are concatenated in a single write transaction. 593 /// The buffers are concatenated in a single write transaction.
495 pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> 594 pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
496 where
497 TXDMA: crate::i2c::TxDma<T>,
498 {
499 let timeout = self.timeout(); 595 let timeout = self.timeout();
500 596
501 if write.is_empty() { 597 if write.is_empty() {
@@ -518,10 +614,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
518 } 614 }
519 615
520 /// Read. 616 /// Read.
521 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> 617 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
522 where
523 RXDMA: crate::i2c::RxDma<T>,
524 {
525 let timeout = self.timeout(); 618 let timeout = self.timeout();
526 619
527 if buffer.is_empty() { 620 if buffer.is_empty() {
@@ -533,11 +626,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
533 } 626 }
534 627
535 /// Write, restart, read. 628 /// Write, restart, read.
536 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> 629 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
537 where
538 TXDMA: super::TxDma<T>,
539 RXDMA: super::RxDma<T>,
540 {
541 let timeout = self.timeout(); 630 let timeout = self.timeout();
542 631
543 if write.is_empty() { 632 if write.is_empty() {
@@ -562,129 +651,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
562 /// Consecutive operations of same type are merged. See [transaction contract] for details. 651 /// Consecutive operations of same type are merged. See [transaction contract] for details.
563 /// 652 ///
564 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 653 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
565 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> 654 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
566 where
567 RXDMA: crate::i2c::RxDma<T>,
568 TXDMA: crate::i2c::TxDma<T>,
569 {
570 let _ = addr;
571 let _ = operations;
572 todo!()
573 }
574
575 // =========================
576 // Blocking public API
577
578 /// Blocking read.
579 pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
580 self.read_internal(address, read, false, self.timeout())
581 // Automatic Stop
582 }
583
584 /// Blocking write.
585 pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
586 self.write_internal(address, write, true, self.timeout())
587 }
588
589 /// Blocking write, restart, read.
590 pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
591 let timeout = self.timeout();
592 self.write_internal(address, write, false, timeout)?;
593 self.read_internal(address, read, true, timeout)
594 // Automatic Stop
595 }
596
597 /// Blocking transaction with operations.
598 ///
599 /// Consecutive operations of same type are merged. See [transaction contract] for details.
600 ///
601 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
602 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
603 let _ = addr; 655 let _ = addr;
604 let _ = operations; 656 let _ = operations;
605 todo!() 657 todo!()
606 } 658 }
607
608 /// Blocking write multiple buffers.
609 ///
610 /// The buffers are concatenated in a single write transaction.
611 pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
612 if write.is_empty() {
613 return Err(Error::ZeroLengthTransfer);
614 }
615
616 let timeout = self.timeout();
617
618 let first_length = write[0].len();
619 let last_slice_index = write.len() - 1;
620
621 if let Err(err) = Self::master_write(
622 address,
623 first_length.min(255),
624 Stop::Software,
625 (first_length > 255) || (last_slice_index != 0),
626 timeout,
627 ) {
628 self.master_stop();
629 return Err(err);
630 }
631
632 for (idx, slice) in write.iter().enumerate() {
633 let slice_len = slice.len();
634 let completed_chunks = slice_len / 255;
635 let total_chunks = if completed_chunks * 255 == slice_len {
636 completed_chunks
637 } else {
638 completed_chunks + 1
639 };
640 let last_chunk_idx = total_chunks.saturating_sub(1);
641
642 if idx != 0 {
643 if let Err(err) = Self::master_continue(
644 slice_len.min(255),
645 (idx != last_slice_index) || (slice_len > 255),
646 timeout,
647 ) {
648 self.master_stop();
649 return Err(err);
650 }
651 }
652
653 for (number, chunk) in slice.chunks(255).enumerate() {
654 if number != 0 {
655 if let Err(err) = Self::master_continue(
656 chunk.len(),
657 (number != last_chunk_idx) || (idx != last_slice_index),
658 timeout,
659 ) {
660 self.master_stop();
661 return Err(err);
662 }
663 }
664
665 for byte in chunk {
666 // Wait until we are allowed to send data
667 // (START has been ACKed or last byte when
668 // through)
669 if let Err(err) = self.wait_txe(timeout) {
670 self.master_stop();
671 return Err(err);
672 }
673
674 // Put byte on the wire
675 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
676 T::regs().txdr().write(|w| w.set_txdata(*byte));
677 }
678 }
679 }
680 // Wait until the write finishes
681 let result = self.wait_tc(timeout);
682 self.master_stop();
683 result
684 }
685} 659}
686 660
687impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { 661impl<'d, T: Instance, M: Mode> Drop for I2c<'d, T, M> {
688 fn drop(&mut self) { 662 fn drop(&mut self) {
689 T::disable(); 663 T::disable();
690 } 664 }
@@ -814,7 +788,7 @@ impl Timings {
814 } 788 }
815} 789}
816 790
817impl<'d, T: Instance> SetConfig for I2c<'d, T> { 791impl<'d, T: Instance, M: Mode> SetConfig for I2c<'d, T, M> {
818 type Config = Hertz; 792 type Config = Hertz;
819 type ConfigError = (); 793 type ConfigError = ();
820 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { 794 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs
index 4b5da774d..4a96357a4 100644
--- a/examples/stm32f4/src/bin/i2c.rs
+++ b/examples/stm32f4/src/bin/i2c.rs
@@ -3,35 +3,19 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dma::NoDma;
7use embassy_stm32::i2c::{Error, I2c}; 6use embassy_stm32::i2c::{Error, I2c};
8use embassy_stm32::time::Hertz; 7use embassy_stm32::time::Hertz;
9use embassy_stm32::{bind_interrupts, i2c, peripherals};
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
11 9
12const ADDRESS: u8 = 0x5F; 10const ADDRESS: u8 = 0x5F;
13const WHOAMI: u8 = 0x0F; 11const WHOAMI: u8 = 0x0F;
14 12
15bind_interrupts!(struct Irqs {
16 I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>;
17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
18});
19
20#[embassy_executor::main] 13#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 14async fn main(_spawner: Spawner) {
22 info!("Hello world!"); 15 info!("Hello world!");
23 let p = embassy_stm32::init(Default::default()); 16 let p = embassy_stm32::init(Default::default());
24 17
25 let mut i2c = I2c::new( 18 let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default());
26 p.I2C2,
27 p.PB10,
28 p.PB11,
29 Irqs,
30 NoDma,
31 NoDma,
32 Hertz(100_000),
33 Default::default(),
34 );
35 19
36 let mut data = [0u8; 1]; 20 let mut data = [0u8; 1];
37 21
diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs
index f553deb82..2861bc091 100644
--- a/examples/stm32l4/src/bin/i2c.rs
+++ b/examples/stm32l4/src/bin/i2c.rs
@@ -3,33 +3,17 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dma::NoDma;
7use embassy_stm32::i2c::I2c; 6use embassy_stm32::i2c::I2c;
8use embassy_stm32::time::Hertz; 7use embassy_stm32::time::Hertz;
9use embassy_stm32::{bind_interrupts, i2c, peripherals};
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
11 9
12const ADDRESS: u8 = 0x5F; 10const ADDRESS: u8 = 0x5F;
13const WHOAMI: u8 = 0x0F; 11const WHOAMI: u8 = 0x0F;
14 12
15bind_interrupts!(struct Irqs {
16 I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>;
17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
18});
19
20#[embassy_executor::main] 13#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 14async fn main(_spawner: Spawner) {
22 let p = embassy_stm32::init(Default::default()); 15 let p = embassy_stm32::init(Default::default());
23 let mut i2c = I2c::new( 16 let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default());
24 p.I2C2,
25 p.PB10,
26 p.PB11,
27 Irqs,
28 NoDma,
29 NoDma,
30 Hertz(100_000),
31 Default::default(),
32 );
33 17
34 let mut data = [0u8; 1]; 18 let mut data = [0u8; 1];
35 unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); 19 unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data));
diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs
index 1b8652bcc..a014b23e0 100644
--- a/examples/stm32l4/src/bin/i2c_blocking_async.rs
+++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs
@@ -4,34 +4,18 @@
4use defmt::*; 4use defmt::*;
5use embassy_embedded_hal::adapter::BlockingAsync; 5use embassy_embedded_hal::adapter::BlockingAsync;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::dma::NoDma;
8use embassy_stm32::i2c::I2c; 7use embassy_stm32::i2c::I2c;
9use embassy_stm32::time::Hertz; 8use embassy_stm32::time::Hertz;
10use embassy_stm32::{bind_interrupts, i2c, peripherals};
11use embedded_hal_async::i2c::I2c as I2cTrait; 9use embedded_hal_async::i2c::I2c as I2cTrait;
12use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
13 11
14const ADDRESS: u8 = 0x5F; 12const ADDRESS: u8 = 0x5F;
15const WHOAMI: u8 = 0x0F; 13const WHOAMI: u8 = 0x0F;
16 14
17bind_interrupts!(struct Irqs {
18 I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>;
19 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
20});
21
22#[embassy_executor::main] 15#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
24 let p = embassy_stm32::init(Default::default()); 17 let p = embassy_stm32::init(Default::default());
25 let i2c = I2c::new( 18 let i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default());
26 p.I2C2,
27 p.PB10,
28 p.PB11,
29 Irqs,
30 NoDma,
31 NoDma,
32 Hertz(100_000),
33 Default::default(),
34 );
35 let mut i2c = BlockingAsync::new(i2c); 19 let mut i2c = BlockingAsync::new(i2c);
36 20
37 let mut data = [0u8; 1]; 21 let mut data = [0u8; 1];
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index a99d08924..694629ede 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -60,7 +60,7 @@ pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>;
60pub type SpeInt = exti::ExtiInput<'static>; 60pub type SpeInt = exti::ExtiInput<'static>;
61pub type SpeRst = Output<'static>; 61pub type SpeRst = Output<'static>;
62pub type Adin1110T = ADIN1110<SpeSpiCs>; 62pub type Adin1110T = ADIN1110<SpeSpiCs>;
63pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>; 63pub type TempSensI2c = I2c<'static, peripherals::I2C3, Async>;
64 64
65static TEMP: AtomicI32 = AtomicI32::new(0); 65static TEMP: AtomicI32 = AtomicI32::new(0);
66 66
diff --git a/examples/stm32u5/src/bin/i2c.rs b/examples/stm32u5/src/bin/i2c.rs
index e376c6bc8..19a78eac9 100644
--- a/examples/stm32u5/src/bin/i2c.rs
+++ b/examples/stm32u5/src/bin/i2c.rs
@@ -3,33 +3,17 @@
3 3
4use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dma::NoDma;
7use embassy_stm32::i2c::I2c; 6use embassy_stm32::i2c::I2c;
8use embassy_stm32::time::Hertz; 7use embassy_stm32::time::Hertz;
9use embassy_stm32::{bind_interrupts, i2c, peripherals};
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
11 9
12const HTS221_ADDRESS: u8 = 0x5F; 10const HTS221_ADDRESS: u8 = 0x5F;
13const WHOAMI: u8 = 0x0F; 11const WHOAMI: u8 = 0x0F;
14 12
15bind_interrupts!(struct Irqs {
16 I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>;
17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
18});
19
20#[embassy_executor::main] 13#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 14async fn main(_spawner: Spawner) {
22 let p = embassy_stm32::init(Default::default()); 15 let p = embassy_stm32::init(Default::default());
23 let mut i2c = I2c::new( 16 let mut i2c = I2c::new_blocking(p.I2C2, p.PH4, p.PH5, Hertz(100_000), Default::default());
24 p.I2C2,
25 p.PH4,
26 p.PH5,
27 Irqs,
28 NoDma,
29 NoDma,
30 Hertz(100_000),
31 Default::default(),
32 );
33 17
34 let mut data = [0u8; 1]; 18 let mut data = [0u8; 1];
35 unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data)); 19 unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data));