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 w.set_tcie(false);
88 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 while info.regs.cr2().read().start() {
137 timeout.check()?;
138 }
139 }
140
141 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 while info.regs.cr2().read().start() {
178 timeout.check()?;
179 }
180
181 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 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 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 trace!("START when waiting for RXNE. Ending receive loop.");
349 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 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 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 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 self.wait_tc(timeout)?;
468 if send_stop {
469 self.master_stop();
470 self.wait_stop(timeout)?;
471 }
472
473 Ok(())
474 }
475
476 pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
481 self.read_internal(address.into(), read, false, self.timeout())
482 }
484
485 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 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 }
497
498 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
504 let _ = addr;
505 let _ = operations;
506 todo!()
507 }
508
509 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 if let Err(err) = self.wait_txis(timeout) {
574 self.master_stop();
575 return Err(err);
576 }
577
578 self.info.regs.txdr().write(|w| w.set_txdata(*byte));
581 }
582 }
583 }
584 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 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 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 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 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 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 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 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 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 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 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 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 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 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 info.regs.icr().modify(|reg| reg.set_addrcf(true));
1000 trace!("ADDRCF cleared (ADDR interrupt enabled, clock stretching ended)");
1001 }
1002
1003 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 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); }
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) }
1053
1054 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 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 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 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 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 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 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 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 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#[derive(Copy, Clone, PartialEq)]
1302enum Stop {
1303 Software,
1305 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 let ratio = i2cclk / frequency;
1341
1342 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 let presc_reg = ((ratio - 1) / 384) as u8;
1352 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 assert!(i2cclk >= 17_000_000); let sdadel = i2cclk / 8_000_000 / presc;
1365 let scldel = i2cclk / 4_000_000 / presc - 1;
1366
1367 (sdadel, scldel)
1368 } else {
1369 assert!(i2cclk >= 8_000_000); 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 assert!(i2cclk >= 2_000_000); let presc = (ratio - 1) / 512;
1387 let presc_reg = cmp::min(presc, 15) as u8;
1388
1389 let presc = (presc_reg + 1) as u32;
1391
1392 let sclh = ((ratio / presc) - 2) / 2;
1393 let scll = sclh;
1394
1395 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 assert!(presc_reg < 16);
1406
1407 let sdadel = cmp::max(sdadel, 2);
1409 let scldel = cmp::max(scldel, 4);
1410
1411 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}