embassy_stm32/i2c/
v2.rs

1use core::cmp;
2use core::future::poll_fn;
3use core::task::Poll;
4
5use config::{Address, OwnAddresses, OA2};
6use embassy_embedded_hal::SetConfig;
7use embassy_hal_internal::drop::OnDrop;
8use embedded_hal_1::i2c::Operation;
9use mode::{Master, MultiMaster};
10use stm32_metapac::i2c::vals::{Addmode, Oamsk};
11
12use super::*;
13use crate::pac::i2c;
14
15impl From<AddrMask> for Oamsk {
16    fn from(value: AddrMask) -> Self {
17        match value {
18            AddrMask::NOMASK => Oamsk::NO_MASK,
19            AddrMask::MASK1 => Oamsk::MASK1,
20            AddrMask::MASK2 => Oamsk::MASK2,
21            AddrMask::MASK3 => Oamsk::MASK3,
22            AddrMask::MASK4 => Oamsk::MASK4,
23            AddrMask::MASK5 => Oamsk::MASK5,
24            AddrMask::MASK6 => Oamsk::MASK6,
25            AddrMask::MASK7 => Oamsk::MASK7,
26        }
27    }
28}
29
30impl Address {
31    pub(super) fn add_mode(&self) -> stm32_metapac::i2c::vals::Addmode {
32        match self {
33            Address::SevenBit(_) => stm32_metapac::i2c::vals::Addmode::BIT7,
34            Address::TenBit(_) => stm32_metapac::i2c::vals::Addmode::BIT10,
35        }
36    }
37}
38
39enum ReceiveResult {
40    DataAvailable,
41    StopReceived,
42    NewStart,
43}
44
45fn debug_print_interrupts(isr: stm32_metapac::i2c::regs::Isr) {
46    if isr.tcr() {
47        trace!("interrupt: tcr");
48    }
49    if isr.tc() {
50        trace!("interrupt: tc");
51    }
52    if isr.addr() {
53        trace!("interrupt: addr");
54    }
55    if isr.stopf() {
56        trace!("interrupt: stopf");
57    }
58    if isr.nackf() {
59        trace!("interrupt: nackf");
60    }
61    if isr.berr() {
62        trace!("interrupt: berr");
63    }
64    if isr.arlo() {
65        trace!("interrupt: arlo");
66    }
67    if isr.ovr() {
68        trace!("interrupt: ovr");
69    }
70}
71
72pub(crate) unsafe fn on_interrupt<T: Instance>() {
73    let regs = T::info().regs;
74    let isr = regs.isr().read();
75
76    if isr.tcr() || isr.tc() || isr.addr() || isr.stopf() || isr.nackf() || isr.berr() || isr.arlo() || isr.ovr() {
77        debug_print_interrupts(isr);
78
79        T::state().waker.wake();
80    }
81
82    critical_section::with(|_| {
83        regs.cr1().modify(|w| {
84            w.set_addrie(false);
85            w.set_stopie(false);
86            // The flag can only be cleared by writting to nbytes, we won't do that here
87            w.set_tcie(false);
88            // Error flags are to be read in the routines, so we also don't clear them here
89            w.set_nackie(false);
90            w.set_errie(false);
91        });
92    });
93}
94
95impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
96    pub(crate) fn init(&mut self, config: Config) {
97        self.info.regs.cr1().modify(|reg| {
98            reg.set_pe(false);
99            reg.set_anfoff(false);
100        });
101
102        let timings = Timings::new(self.kernel_clock, config.frequency.into());
103
104        self.info.regs.timingr().write(|reg| {
105            reg.set_presc(timings.prescale);
106            reg.set_scll(timings.scll);
107            reg.set_sclh(timings.sclh);
108            reg.set_sdadel(timings.sdadel);
109            reg.set_scldel(timings.scldel);
110        });
111
112        self.info.regs.cr1().modify(|reg| {
113            reg.set_pe(true);
114        });
115    }
116
117    fn master_stop(&mut self) {
118        self.info.regs.cr2().write(|w| w.set_stop(true));
119    }
120
121    fn master_read(
122        info: &'static Info,
123        address: Address,
124        length: usize,
125        stop: Stop,
126        reload: bool,
127        restart: bool,
128        timeout: Timeout,
129    ) -> Result<(), Error> {
130        assert!(length < 256);
131
132        if !restart {
133            // Wait for any previous address sequence to end
134            // automatically. This could be up to 50% of a bus
135            // cycle (ie. up to 0.5/freq)
136            while info.regs.cr2().read().start() {
137                timeout.check()?;
138            }
139        }
140
141        // Set START and prepare to receive bytes into
142        // `buffer`. The START bit can be set even if the bus
143        // is BUSY or I2C is in slave mode.
144
145        let reload = if reload {
146            i2c::vals::Reload::NOT_COMPLETED
147        } else {
148            i2c::vals::Reload::COMPLETED
149        };
150
151        info.regs.cr2().modify(|w| {
152            w.set_sadd(address.addr() << 1);
153            w.set_add10(address.add_mode());
154            w.set_dir(i2c::vals::Dir::READ);
155            w.set_nbytes(length as u8);
156            w.set_start(true);
157            w.set_autoend(stop.autoend());
158            w.set_reload(reload);
159        });
160
161        Ok(())
162    }
163
164    fn master_write(
165        info: &'static Info,
166        address: Address,
167        length: usize,
168        stop: Stop,
169        reload: bool,
170        timeout: Timeout,
171    ) -> Result<(), Error> {
172        assert!(length < 256);
173
174        // Wait for any previous address sequence to end
175        // automatically. This could be up to 50% of a bus
176        // cycle (ie. up to 0.5/freq)
177        while info.regs.cr2().read().start() {
178            timeout.check()?;
179        }
180
181        // Wait for the bus to be free
182        while info.regs.isr().read().busy() {
183            timeout.check()?;
184        }
185
186        let reload = if reload {
187            i2c::vals::Reload::NOT_COMPLETED
188        } else {
189            i2c::vals::Reload::COMPLETED
190        };
191
192        // Set START and prepare to send `bytes`. The
193        // START bit can be set even if the bus is BUSY or
194        // I2C is in slave mode.
195        info.regs.cr2().modify(|w| {
196            w.set_sadd(address.addr() << 1);
197            w.set_add10(address.add_mode());
198            w.set_dir(i2c::vals::Dir::WRITE);
199            w.set_nbytes(length as u8);
200            w.set_start(true);
201            w.set_autoend(stop.autoend());
202            w.set_reload(reload);
203        });
204
205        Ok(())
206    }
207
208    fn reload(info: &'static Info, length: usize, will_reload: bool, timeout: Timeout) -> Result<(), Error> {
209        assert!(length < 256 && length > 0);
210
211        while !info.regs.isr().read().tcr() {
212            timeout.check()?;
213        }
214
215        let will_reload = if will_reload {
216            i2c::vals::Reload::NOT_COMPLETED
217        } else {
218            i2c::vals::Reload::COMPLETED
219        };
220
221        info.regs.cr2().modify(|w| {
222            w.set_nbytes(length as u8);
223            w.set_reload(will_reload);
224        });
225
226        Ok(())
227    }
228
229    fn flush_txdr(&self) {
230        if self.info.regs.isr().read().txis() {
231            trace!("Flush TXDATA with zeroes");
232            self.info.regs.txdr().modify(|w| w.set_txdata(0));
233        }
234        if !self.info.regs.isr().read().txe() {
235            trace!("Flush TXDR");
236            self.info.regs.isr().modify(|w| w.set_txe(true))
237        }
238    }
239
240    fn error_occurred(&self, isr: &i2c::regs::Isr, timeout: Timeout) -> Result<(), Error> {
241        if isr.nackf() {
242            trace!("NACK triggered.");
243            self.info.regs.icr().modify(|reg| reg.set_nackcf(true));
244            // NACK should be followed by STOP
245            if let Ok(()) = self.wait_stop(timeout) {
246                trace!("Got STOP after NACK, clearing flag.");
247                self.info.regs.icr().modify(|reg| reg.set_stopcf(true));
248            }
249            self.flush_txdr();
250            return Err(Error::Nack);
251        } else if isr.berr() {
252            trace!("BERR triggered.");
253            self.info.regs.icr().modify(|reg| reg.set_berrcf(true));
254            self.flush_txdr();
255            return Err(Error::Bus);
256        } else if isr.arlo() {
257            trace!("ARLO triggered.");
258            self.info.regs.icr().modify(|reg| reg.set_arlocf(true));
259            self.flush_txdr();
260            return Err(Error::Arbitration);
261        } else if isr.ovr() {
262            trace!("OVR triggered.");
263            self.info.regs.icr().modify(|reg| reg.set_ovrcf(true));
264            return Err(Error::Overrun);
265        }
266        return Ok(());
267    }
268
269    fn wait_txis(&self, timeout: Timeout) -> Result<(), Error> {
270        let mut first_loop = true;
271
272        loop {
273            let isr = self.info.regs.isr().read();
274            self.error_occurred(&isr, timeout)?;
275            if isr.txis() {
276                trace!("TXIS");
277                return Ok(());
278            }
279
280            {
281                if first_loop {
282                    trace!("Waiting for TXIS...");
283                    first_loop = false;
284                }
285            }
286            timeout.check()?;
287        }
288    }
289
290    fn wait_stop_or_err(&self, timeout: Timeout) -> Result<(), Error> {
291        loop {
292            let isr = self.info.regs.isr().read();
293            self.error_occurred(&isr, timeout)?;
294            if isr.stopf() {
295                trace!("STOP triggered.");
296                self.info.regs.icr().modify(|reg| reg.set_stopcf(true));
297                return Ok(());
298            }
299            timeout.check()?;
300        }
301    }
302    fn wait_stop(&self, timeout: Timeout) -> Result<(), Error> {
303        loop {
304            let isr = self.info.regs.isr().read();
305            if isr.stopf() {
306                trace!("STOP triggered.");
307                self.info.regs.icr().modify(|reg| reg.set_stopcf(true));
308                return Ok(());
309            }
310            timeout.check()?;
311        }
312    }
313
314    fn wait_af(&self, timeout: Timeout) -> Result<(), Error> {
315        loop {
316            let isr = self.info.regs.isr().read();
317            if isr.nackf() {
318                trace!("AF triggered.");
319                self.info.regs.icr().modify(|reg| reg.set_nackcf(true));
320                return Ok(());
321            }
322            timeout.check()?;
323        }
324    }
325
326    fn wait_rxne(&self, timeout: Timeout) -> Result<ReceiveResult, Error> {
327        let mut first_loop = true;
328
329        loop {
330            let isr = self.info.regs.isr().read();
331            self.error_occurred(&isr, timeout)?;
332            if isr.stopf() {
333                trace!("STOP when waiting for RXNE.");
334                if self.info.regs.isr().read().rxne() {
335                    trace!("Data received with STOP.");
336                    return Ok(ReceiveResult::DataAvailable);
337                }
338                trace!("STOP triggered without data.");
339                return Ok(ReceiveResult::StopReceived);
340            } else if isr.rxne() {
341                trace!("RXNE.");
342                return Ok(ReceiveResult::DataAvailable);
343            } else if isr.addr() {
344                // Another addr event received, which means START was sent again
345                // which happens when accessing memory registers (common i2c interface design)
346                // e.g. master sends: START, write 1 byte (register index), START, read N bytes (until NACK)
347                // Possible to receive this flag at the same time as rxne, so check rxne first
348                trace!("START when waiting for RXNE. Ending receive loop.");
349                // Return without clearing ADDR so `listen` can catch it
350                return Ok(ReceiveResult::NewStart);
351            }
352            {
353                if first_loop {
354                    trace!("Waiting for RXNE...");
355                    first_loop = false;
356                }
357            }
358
359            timeout.check()?;
360        }
361    }
362
363    fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> {
364        loop {
365            let isr = self.info.regs.isr().read();
366            self.error_occurred(&isr, timeout)?;
367            if isr.tc() {
368                return Ok(());
369            }
370            timeout.check()?;
371        }
372    }
373
374    fn read_internal(
375        &mut self,
376        address: Address,
377        read: &mut [u8],
378        restart: bool,
379        timeout: Timeout,
380    ) -> Result<(), Error> {
381        let completed_chunks = read.len() / 255;
382        let total_chunks = if completed_chunks * 255 == read.len() {
383            completed_chunks
384        } else {
385            completed_chunks + 1
386        };
387        let last_chunk_idx = total_chunks.saturating_sub(1);
388
389        Self::master_read(
390            self.info,
391            address,
392            read.len().min(255),
393            Stop::Automatic,
394            last_chunk_idx != 0,
395            restart,
396            timeout,
397        )?;
398
399        for (number, chunk) in read.chunks_mut(255).enumerate() {
400            if number != 0 {
401                Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
402            }
403
404            for byte in chunk {
405                // Wait until we have received something
406                self.wait_rxne(timeout)?;
407
408                *byte = self.info.regs.rxdr().read().rxdata();
409            }
410        }
411        self.wait_stop(timeout)?;
412        Ok(())
413    }
414
415    fn write_internal(
416        &mut self,
417        address: Address,
418        write: &[u8],
419        send_stop: bool,
420        timeout: Timeout,
421    ) -> Result<(), Error> {
422        let completed_chunks = write.len() / 255;
423        let total_chunks = if completed_chunks * 255 == write.len() {
424            completed_chunks
425        } else {
426            completed_chunks + 1
427        };
428        let last_chunk_idx = total_chunks.saturating_sub(1);
429
430        // I2C start
431        //
432        // ST SAD+W
433        if let Err(err) = Self::master_write(
434            self.info,
435            address,
436            write.len().min(255),
437            Stop::Software,
438            last_chunk_idx != 0,
439            timeout,
440        ) {
441            if send_stop {
442                self.master_stop();
443            }
444            return Err(err);
445        }
446
447        for (number, chunk) in write.chunks(255).enumerate() {
448            if number != 0 {
449                Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
450            }
451
452            for byte in chunk {
453                // Wait until we are allowed to send data
454                // (START has been ACKed or last byte when
455                // through)
456                if let Err(err) = self.wait_txis(timeout) {
457                    if send_stop {
458                        self.master_stop();
459                    }
460                    return Err(err);
461                }
462
463                self.info.regs.txdr().write(|w| w.set_txdata(*byte));
464            }
465        }
466        // Wait until the write finishes
467        self.wait_tc(timeout)?;
468        if send_stop {
469            self.master_stop();
470            self.wait_stop(timeout)?;
471        }
472
473        Ok(())
474    }
475
476    // =========================
477    //  Blocking public API
478
479    /// Blocking read.
480    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
481        self.read_internal(address.into(), read, false, self.timeout())
482        // Automatic Stop
483    }
484
485    /// Blocking write.
486    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
487        self.write_internal(address.into(), write, true, self.timeout())
488    }
489
490    /// Blocking write, restart, read.
491    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
492        let timeout = self.timeout();
493        self.write_internal(address.into(), write, false, timeout)?;
494        self.read_internal(address.into(), read, true, timeout)
495        // Automatic Stop
496    }
497
498    /// Blocking transaction with operations.
499    ///
500    /// Consecutive operations of same type are merged. See [transaction contract] for details.
501    ///
502    /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
503    pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
504        let _ = addr;
505        let _ = operations;
506        todo!()
507    }
508
509    /// Blocking write multiple buffers.
510    ///
511    /// The buffers are concatenated in a single write transaction.
512    pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
513        if write.is_empty() {
514            return Err(Error::ZeroLengthTransfer);
515        }
516
517        let timeout = self.timeout();
518
519        let first_length = write[0].len();
520        let last_slice_index = write.len() - 1;
521
522        if let Err(err) = Self::master_write(
523            self.info,
524            address.into(),
525            first_length.min(255),
526            Stop::Software,
527            (first_length > 255) || (last_slice_index != 0),
528            timeout,
529        ) {
530            self.master_stop();
531            return Err(err);
532        }
533
534        for (idx, slice) in write.iter().enumerate() {
535            let slice_len = slice.len();
536            let completed_chunks = slice_len / 255;
537            let total_chunks = if completed_chunks * 255 == slice_len {
538                completed_chunks
539            } else {
540                completed_chunks + 1
541            };
542            let last_chunk_idx = total_chunks.saturating_sub(1);
543
544            if idx != 0 {
545                if let Err(err) = Self::reload(
546                    self.info,
547                    slice_len.min(255),
548                    (idx != last_slice_index) || (slice_len > 255),
549                    timeout,
550                ) {
551                    self.master_stop();
552                    return Err(err);
553                }
554            }
555
556            for (number, chunk) in slice.chunks(255).enumerate() {
557                if number != 0 {
558                    if let Err(err) = Self::reload(
559                        self.info,
560                        chunk.len(),
561                        (number != last_chunk_idx) || (idx != last_slice_index),
562                        timeout,
563                    ) {
564                        self.master_stop();
565                        return Err(err);
566                    }
567                }
568
569                for byte in chunk {
570                    // Wait until we are allowed to send data
571                    // (START has been ACKed or last byte when
572                    // through)
573                    if let Err(err) = self.wait_txis(timeout) {
574                        self.master_stop();
575                        return Err(err);
576                    }
577
578                    // Put byte on the wire
579                    //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
580                    self.info.regs.txdr().write(|w| w.set_txdata(*byte));
581                }
582            }
583        }
584        // Wait until the write finishes
585        self.wait_tc(timeout)?;
586        self.master_stop();
587        self.wait_stop(timeout)?;
588
589        Ok(())
590    }
591}
592
593impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
594    async fn write_dma_internal(
595        &mut self,
596        address: Address,
597        write: &[u8],
598        first_slice: bool,
599        last_slice: bool,
600        send_stop: bool,
601        timeout: Timeout,
602    ) -> Result<(), Error> {
603        let total_len = write.len();
604
605        let dma_transfer = unsafe {
606            let regs = self.info.regs;
607            regs.cr1().modify(|w| {
608                w.set_txdmaen(true);
609                if first_slice {
610                    w.set_tcie(true);
611                }
612                w.set_nackie(true);
613                w.set_errie(true);
614            });
615            let dst = regs.txdr().as_ptr() as *mut u8;
616
617            self.tx_dma.as_mut().unwrap().write(write, dst, Default::default())
618        };
619
620        let mut remaining_len = total_len;
621
622        let on_drop = OnDrop::new(|| {
623            let regs = self.info.regs;
624            let isr = regs.isr().read();
625            regs.cr1().modify(|w| {
626                if last_slice || isr.nackf() || isr.arlo() || isr.berr() || isr.ovr() {
627                    w.set_txdmaen(false);
628                }
629                w.set_tcie(false);
630                w.set_nackie(false);
631                w.set_errie(false);
632            });
633            regs.icr().write(|w| {
634                w.set_nackcf(true);
635                w.set_berrcf(true);
636                w.set_arlocf(true);
637                w.set_ovrcf(true);
638            });
639        });
640
641        poll_fn(|cx| {
642            self.state.waker.register(cx.waker());
643
644            let isr = self.info.regs.isr().read();
645
646            if isr.nackf() {
647                return Poll::Ready(Err(Error::Nack));
648            }
649            if isr.arlo() {
650                return Poll::Ready(Err(Error::Arbitration));
651            }
652            if isr.berr() {
653                return Poll::Ready(Err(Error::Bus));
654            }
655            if isr.ovr() {
656                return Poll::Ready(Err(Error::Overrun));
657            }
658
659            if remaining_len == total_len {
660                if first_slice {
661                    Self::master_write(
662                        self.info,
663                        address,
664                        total_len.min(255),
665                        Stop::Software,
666                        (total_len > 255) || !last_slice,
667                        timeout,
668                    )?;
669                } else {
670                    Self::reload(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?;
671                    self.info.regs.cr1().modify(|w| w.set_tcie(true));
672                }
673            } else if !(isr.tcr() || isr.tc()) {
674                // poll_fn was woken without an interrupt present
675                return Poll::Pending;
676            } else if remaining_len == 0 {
677                return Poll::Ready(Ok(()));
678            } else {
679                let last_piece = (remaining_len <= 255) && last_slice;
680
681                if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, timeout) {
682                    return Poll::Ready(Err(e));
683                }
684                self.info.regs.cr1().modify(|w| w.set_tcie(true));
685            }
686
687            remaining_len = remaining_len.saturating_sub(255);
688            Poll::Pending
689        })
690        .await?;
691
692        dma_transfer.await;
693        if last_slice {
694            // This should be done already
695            self.wait_tc(timeout)?;
696        }
697
698        if last_slice & send_stop {
699            self.master_stop();
700        }
701
702        drop(on_drop);
703
704        Ok(())
705    }
706
707    async fn read_dma_internal(
708        &mut self,
709        address: Address,
710        buffer: &mut [u8],
711        restart: bool,
712        timeout: Timeout,
713    ) -> Result<(), Error> {
714        let total_len = buffer.len();
715
716        let dma_transfer = unsafe {
717            let regs = self.info.regs;
718            regs.cr1().modify(|w| {
719                w.set_rxdmaen(true);
720                w.set_tcie(true);
721                w.set_nackie(true);
722                w.set_errie(true);
723            });
724            let src = regs.rxdr().as_ptr() as *mut u8;
725
726            self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
727        };
728
729        let mut remaining_len = total_len;
730
731        let on_drop = OnDrop::new(|| {
732            let regs = self.info.regs;
733            regs.cr1().modify(|w| {
734                w.set_rxdmaen(false);
735                w.set_tcie(false);
736                w.set_nackie(false);
737                w.set_errie(false);
738            });
739            regs.icr().write(|w| {
740                w.set_nackcf(true);
741                w.set_berrcf(true);
742                w.set_arlocf(true);
743                w.set_ovrcf(true);
744            });
745        });
746
747        poll_fn(|cx| {
748            self.state.waker.register(cx.waker());
749
750            let isr = self.info.regs.isr().read();
751
752            if isr.nackf() {
753                return Poll::Ready(Err(Error::Nack));
754            }
755            if isr.arlo() {
756                return Poll::Ready(Err(Error::Arbitration));
757            }
758            if isr.berr() {
759                return Poll::Ready(Err(Error::Bus));
760            }
761            if isr.ovr() {
762                return Poll::Ready(Err(Error::Overrun));
763            }
764
765            if remaining_len == total_len {
766                Self::master_read(
767                    self.info,
768                    address,
769                    total_len.min(255),
770                    Stop::Automatic,
771                    total_len > 255,
772                    restart,
773                    timeout,
774                )?;
775                if total_len <= 255 {
776                    return Poll::Ready(Ok(()));
777                }
778            } else if isr.tcr() {
779                // poll_fn was woken without an interrupt present
780                return Poll::Pending;
781            } else {
782                let last_piece = remaining_len <= 255;
783
784                if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, timeout) {
785                    return Poll::Ready(Err(e));
786                }
787                // Return here if we are on last chunk,
788                // end of transfer will be awaited with the DMA below
789                if last_piece {
790                    return Poll::Ready(Ok(()));
791                }
792                self.info.regs.cr1().modify(|w| w.set_tcie(true));
793            }
794
795            remaining_len = remaining_len.saturating_sub(255);
796            Poll::Pending
797        })
798        .await?;
799
800        dma_transfer.await;
801        drop(on_drop);
802
803        Ok(())
804    }
805    // =========================
806    //  Async public API
807
808    /// Write.
809    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
810        let timeout = self.timeout();
811        if write.is_empty() {
812            self.write_internal(address.into(), write, true, timeout)
813        } else {
814            timeout
815                .with(self.write_dma_internal(address.into(), write, true, true, true, timeout))
816                .await
817        }
818    }
819
820    /// Write multiple buffers.
821    ///
822    /// The buffers are concatenated in a single write transaction.
823    pub async fn write_vectored(&mut self, address: Address, write: &[&[u8]]) -> Result<(), Error> {
824        let timeout = self.timeout();
825
826        if write.is_empty() {
827            return Err(Error::ZeroLengthTransfer);
828        }
829        let mut iter = write.iter();
830
831        let mut first = true;
832        let mut current = iter.next();
833        while let Some(c) = current {
834            let next = iter.next();
835            let is_last = next.is_none();
836
837            let fut = self.write_dma_internal(address, c, first, is_last, is_last, timeout);
838            timeout.with(fut).await?;
839            first = false;
840            current = next;
841        }
842        Ok(())
843    }
844
845    /// Read.
846    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
847        let timeout = self.timeout();
848
849        if buffer.is_empty() {
850            self.read_internal(address.into(), buffer, false, timeout)
851        } else {
852            let fut = self.read_dma_internal(address.into(), buffer, false, timeout);
853            timeout.with(fut).await
854        }
855    }
856
857    /// Write, restart, read.
858    pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
859        let timeout = self.timeout();
860
861        if write.is_empty() {
862            self.write_internal(address.into(), write, false, timeout)?;
863        } else {
864            let fut = self.write_dma_internal(address.into(), write, true, true, false, timeout);
865            timeout.with(fut).await?;
866        }
867
868        if read.is_empty() {
869            self.read_internal(address.into(), read, true, timeout)?;
870        } else {
871            let fut = self.read_dma_internal(address.into(), read, true, timeout);
872            timeout.with(fut).await?;
873        }
874
875        Ok(())
876    }
877
878    /// Transaction with operations.
879    ///
880    /// Consecutive operations of same type are merged. See [transaction contract] for details.
881    ///
882    /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
883    pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
884        let _ = addr;
885        let _ = operations;
886        todo!()
887    }
888}
889
890impl<'d, M: Mode> I2c<'d, M, Master> {
891    /// Configure the I2C driver for slave operations, allowing for the driver to be used as a slave and a master (multimaster)
892    pub fn into_slave_multimaster(mut self, slave_addr_config: SlaveAddrConfig) -> I2c<'d, M, MultiMaster> {
893        let mut slave = I2c {
894            info: self.info,
895            state: self.state,
896            kernel_clock: self.kernel_clock,
897            tx_dma: self.tx_dma.take(),
898            rx_dma: self.rx_dma.take(),
899            #[cfg(feature = "time")]
900            timeout: self.timeout,
901            _phantom: PhantomData,
902            _phantom2: PhantomData,
903            _drop_guard: self._drop_guard,
904        };
905        slave.init_slave(slave_addr_config);
906        slave
907    }
908}
909
910impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
911    pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) {
912        self.info.regs.cr1().modify(|reg| {
913            reg.set_pe(false);
914        });
915
916        self.info.regs.cr1().modify(|reg| {
917            reg.set_nostretch(false);
918            reg.set_gcen(config.general_call);
919            reg.set_sbc(true);
920            reg.set_pe(true);
921        });
922
923        self.reconfigure_addresses(config.addr);
924    }
925
926    /// Configure the slave address.
927    pub fn reconfigure_addresses(&mut self, addresses: OwnAddresses) {
928        match addresses {
929            OwnAddresses::OA1(oa1) => self.configure_oa1(oa1),
930            OwnAddresses::OA2(oa2) => self.configure_oa2(oa2),
931            OwnAddresses::Both { oa1, oa2 } => {
932                self.configure_oa1(oa1);
933                self.configure_oa2(oa2);
934            }
935        }
936    }
937
938    fn configure_oa1(&mut self, oa1: Address) {
939        match oa1 {
940            Address::SevenBit(addr) => self.info.regs.oar1().write(|reg| {
941                reg.set_oa1en(false);
942                reg.set_oa1((addr << 1) as u16);
943                reg.set_oa1mode(Addmode::BIT7);
944                reg.set_oa1en(true);
945            }),
946            Address::TenBit(addr) => self.info.regs.oar1().write(|reg| {
947                reg.set_oa1en(false);
948                reg.set_oa1(addr);
949                reg.set_oa1mode(Addmode::BIT10);
950                reg.set_oa1en(true);
951            }),
952        }
953    }
954
955    fn configure_oa2(&mut self, oa2: OA2) {
956        self.info.regs.oar2().write(|reg| {
957            reg.set_oa2en(false);
958            reg.set_oa2msk(oa2.mask.into());
959            reg.set_oa2(oa2.addr << 1);
960            reg.set_oa2en(true);
961        });
962    }
963
964    fn determine_matched_address(&self) -> Result<Address, Error> {
965        let matched = self.info.regs.isr().read().addcode();
966
967        if matched >> 3 == 0b11110 {
968            // is 10-bit address and we need to get the other 8 bits from the rxdr
969            // we do this by doing a blocking read of 1 byte
970            let mut buffer = [0];
971            self.slave_read_internal(&mut buffer, self.timeout())?;
972            Ok(Address::TenBit((matched as u16) << 6 | buffer[0] as u16))
973        } else {
974            Ok(Address::SevenBit(matched))
975        }
976    }
977}
978
979impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
980    /// # Safety
981    /// This function will clear the address flag which will stop the clock stretching.
982    /// This should only be done after the dma transfer has been set up.
983    fn slave_start(info: &'static Info, length: usize, reload: bool) {
984        assert!(length < 256);
985
986        let reload = if reload {
987            i2c::vals::Reload::NOT_COMPLETED
988        } else {
989            i2c::vals::Reload::COMPLETED
990        };
991
992        info.regs.cr2().modify(|w| {
993            w.set_nbytes(length as u8);
994            w.set_reload(reload);
995        });
996
997        // clear the address flag, will stop the clock stretching.
998        // this should only be done after the dma transfer has been set up.
999        info.regs.icr().modify(|reg| reg.set_addrcf(true));
1000        trace!("ADDRCF cleared (ADDR interrupt enabled, clock stretching ended)");
1001    }
1002
1003    // A blocking read operation
1004    fn slave_read_internal(&self, read: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
1005        let completed_chunks = read.len() / 255;
1006        let total_chunks = if completed_chunks * 255 == read.len() {
1007            completed_chunks
1008        } else {
1009            completed_chunks + 1
1010        };
1011        let last_chunk_idx = total_chunks.saturating_sub(1);
1012        let total_len = read.len();
1013        let mut remaining_len = total_len;
1014
1015        for (number, chunk) in read.chunks_mut(255).enumerate() {
1016            trace!(
1017                "--- Slave RX transmission start - chunk: {}, expected (max) size: {}",
1018                number,
1019                chunk.len()
1020            );
1021            if number == 0 {
1022                Self::slave_start(self.info, chunk.len(), number != last_chunk_idx);
1023            } else {
1024                Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
1025            }
1026
1027            let mut index = 0;
1028
1029            for byte in chunk {
1030                // Wait until we have received something
1031                match self.wait_rxne(timeout) {
1032                    Ok(ReceiveResult::StopReceived) | Ok(ReceiveResult::NewStart) => {
1033                        trace!("--- Slave RX transmission end (early)");
1034                        return Ok(total_len - remaining_len); // Return N bytes read
1035                    }
1036                    Ok(ReceiveResult::DataAvailable) => {
1037                        *byte = self.info.regs.rxdr().read().rxdata();
1038                        remaining_len = remaining_len.saturating_sub(1);
1039                        {
1040                            trace!("Slave RX data {}: {:#04x}", index, byte);
1041                            index = index + 1;
1042                        }
1043                    }
1044                    Err(e) => return Err(e),
1045                };
1046            }
1047        }
1048        self.wait_stop_or_err(timeout)?;
1049
1050        trace!("--- Slave RX transmission end");
1051        Ok(total_len - remaining_len) // Return N bytes read
1052    }
1053
1054    // A blocking write operation
1055    fn slave_write_internal(&mut self, write: &[u8], timeout: Timeout) -> Result<(), Error> {
1056        let completed_chunks = write.len() / 255;
1057        let total_chunks = if completed_chunks * 255 == write.len() {
1058            completed_chunks
1059        } else {
1060            completed_chunks + 1
1061        };
1062        let last_chunk_idx = total_chunks.saturating_sub(1);
1063
1064        for (number, chunk) in write.chunks(255).enumerate() {
1065            trace!(
1066                "--- Slave TX transmission start - chunk: {}, size: {}",
1067                number,
1068                chunk.len()
1069            );
1070            if number == 0 {
1071                Self::slave_start(self.info, chunk.len(), number != last_chunk_idx);
1072            } else {
1073                Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
1074            }
1075
1076            let mut index = 0;
1077
1078            for byte in chunk {
1079                // Wait until we are allowed to send data
1080                // (START has been ACKed or last byte when through)
1081                self.wait_txis(timeout)?;
1082
1083                {
1084                    trace!("Slave TX data {}: {:#04x}", index, byte);
1085                    index = index + 1;
1086                }
1087                self.info.regs.txdr().write(|w| w.set_txdata(*byte));
1088            }
1089        }
1090        self.wait_af(timeout)?;
1091        self.flush_txdr();
1092        self.wait_stop_or_err(timeout)?;
1093
1094        trace!("--- Slave TX transmission end");
1095        Ok(())
1096    }
1097
1098    /// Listen for incoming I2C messages.
1099    ///
1100    /// The listen method is an asynchronous method but it does not require DMA to be asynchronous.
1101    pub async fn listen(&mut self) -> Result<SlaveCommand, Error> {
1102        let state = self.state;
1103        self.info.regs.cr1().modify(|reg| {
1104            reg.set_addrie(true);
1105            trace!("Enable ADDRIE");
1106        });
1107
1108        poll_fn(|cx| {
1109            state.waker.register(cx.waker());
1110            let isr = self.info.regs.isr().read();
1111            if !isr.addr() {
1112                Poll::Pending
1113            } else {
1114                trace!("ADDR triggered (address match)");
1115                // we do not clear the address flag here as it will be cleared by the dma read/write
1116                // if we clear it here the clock stretching will stop and the master will read in data before the slave is ready to send it
1117                match isr.dir() {
1118                    i2c::vals::Dir::WRITE => {
1119                        trace!("DIR: write");
1120                        Poll::Ready(Ok(SlaveCommand {
1121                            kind: SlaveCommandKind::Write,
1122                            address: self.determine_matched_address()?,
1123                        }))
1124                    }
1125                    i2c::vals::Dir::READ => {
1126                        trace!("DIR: read");
1127                        Poll::Ready(Ok(SlaveCommand {
1128                            kind: SlaveCommandKind::Read,
1129                            address: self.determine_matched_address()?,
1130                        }))
1131                    }
1132                }
1133            }
1134        })
1135        .await
1136    }
1137
1138    /// Respond to a write command.
1139    ///
1140    /// Returns total number of bytes received.
1141    pub fn blocking_respond_to_write(&self, read: &mut [u8]) -> Result<usize, Error> {
1142        let timeout = self.timeout();
1143        self.slave_read_internal(read, timeout)
1144    }
1145
1146    /// Respond to a read command.
1147    pub fn blocking_respond_to_read(&mut self, write: &[u8]) -> Result<(), Error> {
1148        let timeout = self.timeout();
1149        self.slave_write_internal(write, timeout)
1150    }
1151}
1152
1153impl<'d> I2c<'d, Async, MultiMaster> {
1154    /// Respond to a write command.
1155    ///
1156    /// Returns the total number of bytes received.
1157    pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
1158        let timeout = self.timeout();
1159        timeout.with(self.read_dma_internal_slave(buffer, timeout)).await
1160    }
1161
1162    /// Respond to a read request from an I2C master.
1163    pub async fn respond_to_read(&mut self, write: &[u8]) -> Result<SendStatus, Error> {
1164        let timeout = self.timeout();
1165        timeout.with(self.write_dma_internal_slave(write, timeout)).await
1166    }
1167
1168    // for data reception in slave mode
1169    //
1170    // returns the total number of bytes received
1171    async fn read_dma_internal_slave(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
1172        let total_len = buffer.len();
1173        let mut remaining_len = total_len;
1174
1175        let regs = self.info.regs;
1176
1177        let dma_transfer = unsafe {
1178            regs.cr1().modify(|w| {
1179                w.set_rxdmaen(true);
1180                w.set_stopie(true);
1181                w.set_tcie(true);
1182            });
1183            let src = regs.rxdr().as_ptr() as *mut u8;
1184
1185            self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
1186        };
1187
1188        let state = self.state;
1189
1190        let on_drop = OnDrop::new(|| {
1191            regs.cr1().modify(|w| {
1192                w.set_rxdmaen(false);
1193                w.set_stopie(false);
1194                w.set_tcie(false);
1195            });
1196        });
1197
1198        let total_received = poll_fn(|cx| {
1199            state.waker.register(cx.waker());
1200
1201            let isr = regs.isr().read();
1202
1203            if remaining_len == total_len {
1204                Self::slave_start(self.info, total_len.min(255), total_len > 255);
1205                remaining_len = remaining_len.saturating_sub(255);
1206                Poll::Pending
1207            } else if isr.tcr() {
1208                let is_last_slice = remaining_len <= 255;
1209                if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, timeout) {
1210                    return Poll::Ready(Err(e));
1211                }
1212                remaining_len = remaining_len.saturating_sub(255);
1213                regs.cr1().modify(|w| w.set_tcie(true));
1214                Poll::Pending
1215            } else if isr.stopf() {
1216                regs.icr().write(|reg| reg.set_stopcf(true));
1217                let poll = Poll::Ready(Ok(total_len - remaining_len));
1218                poll
1219            } else {
1220                Poll::Pending
1221            }
1222        })
1223        .await?;
1224
1225        dma_transfer.await;
1226
1227        drop(on_drop);
1228
1229        Ok(total_received)
1230    }
1231
1232    async fn write_dma_internal_slave(&mut self, buffer: &[u8], timeout: Timeout) -> Result<SendStatus, Error> {
1233        let total_len = buffer.len();
1234        let mut remaining_len = total_len;
1235
1236        let mut dma_transfer = unsafe {
1237            let regs = self.info.regs;
1238            regs.cr1().modify(|w| {
1239                w.set_txdmaen(true);
1240                w.set_stopie(true);
1241                w.set_tcie(true);
1242            });
1243            let dst = regs.txdr().as_ptr() as *mut u8;
1244
1245            self.tx_dma.as_mut().unwrap().write(buffer, dst, Default::default())
1246        };
1247
1248        let on_drop = OnDrop::new(|| {
1249            let regs = self.info.regs;
1250            regs.cr1().modify(|w| {
1251                w.set_txdmaen(false);
1252                w.set_stopie(false);
1253                w.set_tcie(false);
1254            })
1255        });
1256
1257        let state = self.state;
1258
1259        let size = poll_fn(|cx| {
1260            state.waker.register(cx.waker());
1261
1262            let isr = self.info.regs.isr().read();
1263
1264            if remaining_len == total_len {
1265                Self::slave_start(self.info, total_len.min(255), total_len > 255);
1266                remaining_len = remaining_len.saturating_sub(255);
1267                Poll::Pending
1268            } else if isr.tcr() {
1269                let is_last_slice = remaining_len <= 255;
1270                if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, timeout) {
1271                    return Poll::Ready(Err(e));
1272                }
1273                remaining_len = remaining_len.saturating_sub(255);
1274                self.info.regs.cr1().modify(|w| w.set_tcie(true));
1275                Poll::Pending
1276            } else if isr.stopf() {
1277                self.info.regs.icr().write(|reg| reg.set_stopcf(true));
1278                if remaining_len > 0 {
1279                    dma_transfer.request_stop();
1280                    Poll::Ready(Ok(SendStatus::LeftoverBytes(remaining_len as usize)))
1281                } else {
1282                    Poll::Ready(Ok(SendStatus::Done))
1283                }
1284            } else {
1285                Poll::Pending
1286            }
1287        })
1288        .await?;
1289
1290        dma_transfer.await;
1291
1292        drop(on_drop);
1293
1294        Ok(size)
1295    }
1296}
1297
1298/// I2C Stop Configuration
1299///
1300/// Peripheral options for generating the STOP condition
1301#[derive(Copy, Clone, PartialEq)]
1302enum Stop {
1303    /// Software end mode: Must write register to generate STOP condition
1304    Software,
1305    /// Automatic end mode: A STOP condition is automatically generated once the
1306    /// configured number of bytes have been transferred
1307    Automatic,
1308}
1309
1310impl Stop {
1311    fn autoend(&self) -> i2c::vals::Autoend {
1312        match self {
1313            Stop::Software => i2c::vals::Autoend::SOFTWARE,
1314            Stop::Automatic => i2c::vals::Autoend::AUTOMATIC,
1315        }
1316    }
1317}
1318
1319struct Timings {
1320    prescale: u8,
1321    scll: u8,
1322    sclh: u8,
1323    sdadel: u8,
1324    scldel: u8,
1325}
1326
1327impl Timings {
1328    fn new(i2cclk: Hertz, frequency: Hertz) -> Self {
1329        let i2cclk = i2cclk.0;
1330        let frequency = frequency.0;
1331        // Refer to RM0433 Rev 7 Figure 539 for setup and hold timing:
1332        //
1333        // t_I2CCLK = 1 / PCLK1
1334        // t_PRESC  = (PRESC + 1) * t_I2CCLK
1335        // t_SCLL   = (SCLL + 1) * t_PRESC
1336        // t_SCLH   = (SCLH + 1) * t_PRESC
1337        //
1338        // t_SYNC1 + t_SYNC2 > 4 * t_I2CCLK
1339        // t_SCL ~= t_SYNC1 + t_SYNC2 + t_SCLL + t_SCLH
1340        let ratio = i2cclk / frequency;
1341
1342        // For the standard-mode configuration method, we must have a ratio of 4
1343        // or higher
1344        assert!(ratio >= 4, "The I2C PCLK must be at least 4 times the bus frequency!");
1345
1346        let (presc_reg, scll, sclh, sdadel, scldel) = if frequency > 100_000 {
1347            // Fast-mode (Fm) or Fast-mode Plus (Fm+)
1348            // here we pick SCLL + 1 = 2 * (SCLH + 1)
1349
1350            // Prescaler, 384 ticks for sclh/scll. Round up then subtract 1
1351            let presc_reg = ((ratio - 1) / 384) as u8;
1352            // ratio < 1200 by pclk 120MHz max., therefore presc < 16
1353
1354            // Actual precale value selected
1355            let presc = (presc_reg + 1) as u32;
1356
1357            let sclh = ((ratio / presc) - 3) / 3;
1358            let scll = (2 * (sclh + 1)) - 1;
1359
1360            let (sdadel, scldel) = if frequency > 400_000 {
1361                // Fast-mode Plus (Fm+)
1362                assert!(i2cclk >= 17_000_000); // See table in datsheet
1363
1364                let sdadel = i2cclk / 8_000_000 / presc;
1365                let scldel = i2cclk / 4_000_000 / presc - 1;
1366
1367                (sdadel, scldel)
1368            } else {
1369                // Fast-mode (Fm)
1370                assert!(i2cclk >= 8_000_000); // See table in datsheet
1371
1372                let sdadel = i2cclk / 4_000_000 / presc;
1373                let scldel = i2cclk / 2_000_000 / presc - 1;
1374
1375                (sdadel, scldel)
1376            };
1377
1378            (presc_reg, scll as u8, sclh as u8, sdadel as u8, scldel as u8)
1379        } else {
1380            // Standard-mode (Sm)
1381            // here we pick SCLL = SCLH
1382            assert!(i2cclk >= 2_000_000); // See table in datsheet
1383
1384            // Prescaler, 512 ticks for sclh/scll. Round up then
1385            // subtract 1
1386            let presc = (ratio - 1) / 512;
1387            let presc_reg = cmp::min(presc, 15) as u8;
1388
1389            // Actual prescale value selected
1390            let presc = (presc_reg + 1) as u32;
1391
1392            let sclh = ((ratio / presc) - 2) / 2;
1393            let scll = sclh;
1394
1395            // Speed check
1396            assert!(sclh < 256, "The I2C PCLK is too fast for this bus frequency!");
1397
1398            let sdadel = i2cclk / 2_000_000 / presc;
1399            let scldel = i2cclk / 500_000 / presc - 1;
1400
1401            (presc_reg, scll as u8, sclh as u8, sdadel as u8, scldel as u8)
1402        };
1403
1404        // Sanity check
1405        assert!(presc_reg < 16);
1406
1407        // Keep values within reasonable limits for fast per_ck
1408        let sdadel = cmp::max(sdadel, 2);
1409        let scldel = cmp::max(scldel, 4);
1410
1411        //(presc_reg, scll, sclh, sdadel, scldel)
1412        Self {
1413            prescale: presc_reg,
1414            scll,
1415            sclh,
1416            sdadel,
1417            scldel,
1418        }
1419    }
1420}
1421
1422impl<'d, M: Mode> SetConfig for I2c<'d, M, Master> {
1423    type Config = Hertz;
1424    type ConfigError = ();
1425    fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
1426        self.info.regs.cr1().modify(|reg| {
1427            reg.set_pe(false);
1428        });
1429
1430        let timings = Timings::new(self.kernel_clock, *config);
1431
1432        self.info.regs.timingr().write(|reg| {
1433            reg.set_presc(timings.prescale);
1434            reg.set_scll(timings.scll);
1435            reg.set_sclh(timings.sclh);
1436            reg.set_sdadel(timings.sdadel);
1437            reg.set_scldel(timings.scldel);
1438        });
1439
1440        self.info.regs.cr1().modify(|reg| {
1441            reg.set_pe(true);
1442        });
1443
1444        Ok(())
1445    }
1446}
1447
1448impl<'d, M: Mode> SetConfig for I2c<'d, M, MultiMaster> {
1449    type Config = (Hertz, SlaveAddrConfig);
1450    type ConfigError = ();
1451    fn set_config(&mut self, (config, addr_config): &Self::Config) -> Result<(), ()> {
1452        let timings = Timings::new(self.kernel_clock, *config);
1453        self.info.regs.timingr().write(|reg| {
1454            reg.set_presc(timings.prescale);
1455            reg.set_scll(timings.scll);
1456            reg.set_sclh(timings.sclh);
1457            reg.set_sdadel(timings.sdadel);
1458            reg.set_scldel(timings.scldel);
1459        });
1460        self.init_slave(*addr_config);
1461
1462        Ok(())
1463    }
1464}