1use core::{
24 marker::PhantomData,
25 pin::Pin,
26 task::{Context, Poll},
27};
28
29use embedded_hal::i2c::Operation as EhalOperation;
30use enumset::{EnumSet, EnumSetType};
31
32use crate::{
33 Async,
34 Blocking,
35 DriverMode,
36 asynch::AtomicWaker,
37 clock::Clocks,
38 gpio::{
39 DriveMode,
40 InputSignal,
41 OutputConfig,
42 OutputSignal,
43 PinGuard,
44 Pull,
45 interconnect::{self, PeripheralOutput},
46 },
47 i2c::{AnyI2c, AnyI2cInner},
48 interrupt::InterruptHandler,
49 pac::i2c0::{COMD, RegisterBlock},
50 peripherals::Interrupt,
51 private,
52 system::PeripheralGuard,
53 time::{Duration, Instant, Rate},
54};
55
56const I2C_LL_INTR_MASK: u32 = if cfg!(esp32s2) { 0x1ffff } else { 0x3ffff };
57const I2C_FIFO_SIZE: usize = if cfg!(esp32c2) { 16 } else { 32 };
58
59const I2C_CHUNK_SIZE: usize = I2C_FIFO_SIZE - 1;
61const CLEAR_BUS_TIMEOUT_MS: Duration = Duration::from_millis(50);
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
65#[cfg_attr(feature = "defmt", derive(defmt::Format))]
66#[non_exhaustive]
67pub enum I2cAddress {
68 SevenBit(u8),
81}
82
83impl I2cAddress {
84 fn validate(&self) -> Result<(), Error> {
85 match self {
86 I2cAddress::SevenBit(addr) => {
87 if *addr > 0x7F {
88 return Err(Error::AddressInvalid(*self));
89 }
90 }
91 }
92
93 Ok(())
94 }
95}
96
97impl From<u8> for I2cAddress {
98 fn from(value: u8) -> Self {
99 I2cAddress::SevenBit(value)
100 }
101}
102
103#[doc = ""]
110#[cfg_attr(
111 not(esp32),
112 doc = "Note that the effective timeout may be longer than the value configured here."
113)]
114#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, strum::Display)]
115#[cfg_attr(feature = "defmt", derive(defmt::Format))]
116#[non_exhaustive]
117pub enum BusTimeout {
120 Maximum,
122
123 #[cfg(not(any(esp32, esp32s2)))]
125 Disabled,
126
127 BusCycles(u32),
129}
130
131impl BusTimeout {
132 fn cycles(&self) -> u32 {
133 match self {
134 BusTimeout::Maximum => {
135 if cfg!(esp32) {
136 0xF_FFFF
137 } else if cfg!(esp32s2) {
138 0xFF_FFFF
139 } else {
140 0x1F
141 }
142 }
143
144 #[cfg(not(any(esp32, esp32s2)))]
145 BusTimeout::Disabled => 1,
146
147 BusTimeout::BusCycles(cycles) => *cycles,
148 }
149 }
150
151 #[cfg(not(esp32))]
152 fn is_set(&self) -> bool {
153 matches!(self, BusTimeout::BusCycles(_) | BusTimeout::Maximum)
154 }
155}
156
157#[instability::unstable]
168#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
169#[cfg_attr(feature = "defmt", derive(defmt::Format))]
170pub enum SoftwareTimeout {
171 None,
173
174 Transaction(Duration),
176
177 PerByte(Duration),
183}
184
185#[instability::unstable]
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
191#[cfg_attr(feature = "defmt", derive(defmt::Format))]
192#[cfg(not(any(esp32, esp32s2)))]
193pub struct FsmTimeout {
194 value: u8,
195}
196
197#[cfg(not(any(esp32, esp32s2)))]
198impl FsmTimeout {
199 const FSM_TIMEOUT_MAX: u8 = 23;
200
201 const FSM_TIMEOUT_DEFAULT: u8 = 0x10;
202
203 #[instability::unstable]
208 pub const fn new_const<const VALUE: u8>() -> Self {
209 const {
210 core::assert!(VALUE <= Self::FSM_TIMEOUT_MAX, "Invalid timeout value");
211 }
212 Self { value: VALUE }
213 }
214
215 #[instability::unstable]
220 pub fn new(value: u8) -> Result<Self, ConfigError> {
221 if value > Self::FSM_TIMEOUT_MAX {
222 return Err(ConfigError::TimeoutInvalid);
223 }
224
225 Ok(Self { value })
226 }
227
228 fn value(&self) -> u8 {
229 self.value
230 }
231}
232
233#[cfg(not(any(esp32, esp32s2)))]
234impl Default for FsmTimeout {
235 fn default() -> Self {
236 Self::new_const::<{ Self::FSM_TIMEOUT_DEFAULT }>()
237 }
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
242#[cfg_attr(feature = "defmt", derive(defmt::Format))]
243#[non_exhaustive]
244pub enum Error {
245 FifoExceeded,
247 AcknowledgeCheckFailed(AcknowledgeCheckFailedReason),
249 Timeout,
251 ArbitrationLost,
253 ExecutionIncomplete,
255 CommandNumberExceeded,
257 ZeroLengthInvalid,
259 AddressInvalid(I2cAddress),
261}
262
263#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
267#[cfg_attr(feature = "defmt", derive(defmt::Format))]
268#[non_exhaustive]
269pub enum AcknowledgeCheckFailedReason {
270 Address,
272
273 Data,
276
277 Unknown,
280}
281
282impl core::fmt::Display for AcknowledgeCheckFailedReason {
283 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
284 match self {
285 AcknowledgeCheckFailedReason::Address => write!(f, "Address"),
286 AcknowledgeCheckFailedReason::Data => write!(f, "Data"),
287 AcknowledgeCheckFailedReason::Unknown => write!(f, "Unknown"),
288 }
289 }
290}
291
292impl From<&AcknowledgeCheckFailedReason> for embedded_hal::i2c::NoAcknowledgeSource {
293 fn from(value: &AcknowledgeCheckFailedReason) -> Self {
294 match value {
295 AcknowledgeCheckFailedReason::Address => {
296 embedded_hal::i2c::NoAcknowledgeSource::Address
297 }
298 AcknowledgeCheckFailedReason::Data => embedded_hal::i2c::NoAcknowledgeSource::Data,
299 AcknowledgeCheckFailedReason::Unknown => {
300 embedded_hal::i2c::NoAcknowledgeSource::Unknown
301 }
302 }
303 }
304}
305
306impl core::error::Error for Error {}
307
308impl core::fmt::Display for Error {
309 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
310 match self {
311 Error::FifoExceeded => write!(f, "The transmission exceeded the FIFO size"),
312 Error::AcknowledgeCheckFailed(reason) => {
313 write!(f, "The acknowledgment check failed. Reason: {reason}")
314 }
315 Error::Timeout => write!(f, "A timeout occurred during transmission"),
316 Error::ArbitrationLost => write!(f, "The arbitration for the bus was lost"),
317 Error::ExecutionIncomplete => {
318 write!(f, "The execution of the I2C command was incomplete")
319 }
320 Error::CommandNumberExceeded => {
321 write!(f, "The number of commands issued exceeded the limit")
322 }
323 Error::ZeroLengthInvalid => write!(f, "Zero length read or write operation"),
324 Error::AddressInvalid(address) => {
325 write!(f, "The given address ({address:?}) is invalid")
326 }
327 }
328 }
329}
330
331#[derive(Debug, Clone, Copy, PartialEq)]
333#[cfg_attr(feature = "defmt", derive(defmt::Format))]
334#[non_exhaustive]
335pub enum ConfigError {
336 FrequencyInvalid,
338 TimeoutInvalid,
340}
341
342impl core::error::Error for ConfigError {}
343
344impl core::fmt::Display for ConfigError {
345 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
346 match self {
347 ConfigError::FrequencyInvalid => write!(
348 f,
349 "Provided bus frequency is invalid for the current configuration"
350 ),
351 ConfigError::TimeoutInvalid => write!(
352 f,
353 "Provided timeout is invalid for the current configuration"
354 ),
355 }
356 }
357}
358
359#[derive(PartialEq)]
365enum OpKind {
366 Write,
367 Read,
368}
369
370#[derive(Debug, PartialEq, Eq, Hash, strum::Display)]
374#[cfg_attr(feature = "defmt", derive(defmt::Format))]
375pub enum Operation<'a> {
376 Write(&'a [u8]),
378
379 Read(&'a mut [u8]),
381}
382
383impl<'a, 'b> From<&'a mut embedded_hal::i2c::Operation<'b>> for Operation<'a> {
384 fn from(value: &'a mut embedded_hal::i2c::Operation<'b>) -> Self {
385 match value {
386 embedded_hal::i2c::Operation::Write(buffer) => Operation::Write(buffer),
387 embedded_hal::i2c::Operation::Read(buffer) => Operation::Read(buffer),
388 }
389 }
390}
391
392impl<'a, 'b> From<&'a mut Operation<'b>> for Operation<'a> {
393 fn from(value: &'a mut Operation<'b>) -> Self {
394 match value {
395 Operation::Write(buffer) => Operation::Write(buffer),
396 Operation::Read(buffer) => Operation::Read(buffer),
397 }
398 }
399}
400
401impl Operation<'_> {
402 fn is_write(&self) -> bool {
403 matches!(self, Operation::Write(_))
404 }
405
406 fn kind(&self) -> OpKind {
407 match self {
408 Operation::Write(_) => OpKind::Write,
409 Operation::Read(_) => OpKind::Read,
410 }
411 }
412
413 fn is_empty(&self) -> bool {
414 match self {
415 Operation::Write(buffer) => buffer.is_empty(),
416 Operation::Read(buffer) => buffer.is_empty(),
417 }
418 }
419}
420
421impl embedded_hal::i2c::Error for Error {
422 fn kind(&self) -> embedded_hal::i2c::ErrorKind {
423 use embedded_hal::i2c::ErrorKind;
424
425 match self {
426 Self::FifoExceeded => ErrorKind::Overrun,
427 Self::ArbitrationLost => ErrorKind::ArbitrationLoss,
428 Self::AcknowledgeCheckFailed(reason) => ErrorKind::NoAcknowledge(reason.into()),
429 _ => ErrorKind::Other,
430 }
431 }
432}
433
434#[derive(Debug)]
436enum Command {
437 Start,
438 Stop,
439 End,
440 Write {
441 ack_exp: Ack,
443 ack_check_en: bool,
445 #[cfg_attr(esp32c2, doc = "16")]
447 #[cfg_attr(not(esp32c2), doc = "32")]
448 length: u8,
450 },
451 Read {
452 ack_value: Ack,
455 #[cfg_attr(esp32c2, doc = "16")]
457 #[cfg_attr(not(esp32c2), doc = "32")]
458 length: u8,
460 },
461}
462
463enum OperationType {
464 Write = 0,
465 Read = 1,
466}
467
468#[derive(Eq, PartialEq, Copy, Clone, Debug)]
469enum Ack {
470 Ack = 0,
471 Nack = 1,
472}
473
474impl From<u32> for Ack {
475 fn from(ack: u32) -> Self {
476 match ack {
477 0 => Ack::Ack,
478 1 => Ack::Nack,
479 _ => unreachable!(),
480 }
481 }
482}
483
484impl From<Ack> for u32 {
485 fn from(ack: Ack) -> u32 {
486 ack as u32
487 }
488}
489
490#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, procmacros::BuilderLite)]
492#[cfg_attr(feature = "defmt", derive(defmt::Format))]
493#[non_exhaustive]
494pub struct Config {
495 frequency: Rate,
497
498 timeout: BusTimeout,
500
501 #[builder_lite(unstable)]
503 software_timeout: SoftwareTimeout,
504
505 #[cfg(not(any(esp32, esp32s2)))]
507 #[builder_lite(unstable)]
508 scl_st_timeout: FsmTimeout,
509
510 #[cfg(not(any(esp32, esp32s2)))]
512 #[builder_lite(unstable)]
513 scl_main_st_timeout: FsmTimeout,
514}
515
516impl Default for Config {
517 fn default() -> Self {
518 Config {
519 frequency: Rate::from_khz(100),
520 timeout: BusTimeout::BusCycles(10),
521 software_timeout: SoftwareTimeout::PerByte(Duration::from_millis(1)),
522 #[cfg(not(any(esp32, esp32s2)))]
523 scl_st_timeout: Default::default(),
524 #[cfg(not(any(esp32, esp32s2)))]
525 scl_main_st_timeout: Default::default(),
526 }
527 }
528}
529
530#[doc = crate::before_snippet!()]
535#[derive(Debug)]
550#[cfg_attr(feature = "defmt", derive(defmt::Format))]
551pub struct I2c<'d, Dm: DriverMode> {
552 i2c: AnyI2c<'d>,
553 phantom: PhantomData<Dm>,
554 guard: PeripheralGuard,
555 config: DriverConfig,
556}
557
558#[derive(Debug)]
559#[cfg_attr(feature = "defmt", derive(defmt::Format))]
560struct DriverConfig {
561 config: Config,
562 sda_pin: PinGuard,
563 scl_pin: PinGuard,
564}
565
566#[instability::unstable]
567impl<Dm: DriverMode> embassy_embedded_hal::SetConfig for I2c<'_, Dm> {
568 type Config = Config;
569 type ConfigError = ConfigError;
570
571 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
572 self.apply_config(config)
573 }
574}
575
576impl<Dm: DriverMode> embedded_hal::i2c::ErrorType for I2c<'_, Dm> {
577 type Error = Error;
578}
579
580impl<Dm: DriverMode> embedded_hal::i2c::I2c for I2c<'_, Dm> {
581 fn transaction(
582 &mut self,
583 address: u8,
584 operations: &mut [embedded_hal::i2c::Operation<'_>],
585 ) -> Result<(), Self::Error> {
586 self.driver()
587 .transaction_impl(
588 I2cAddress::SevenBit(address),
589 operations.iter_mut().map(Operation::from),
590 )
591 .inspect_err(|_| self.internal_recover())
592 }
593}
594
595impl<'d> I2c<'d, Blocking> {
596 pub fn new(i2c: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
603 let guard = PeripheralGuard::new(i2c.info().peripheral);
604
605 let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output);
606 let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output);
607
608 let mut i2c = I2c {
609 i2c: i2c.degrade(),
610 phantom: PhantomData,
611 guard,
612 config: DriverConfig {
613 config,
614 sda_pin,
615 scl_pin,
616 },
617 };
618
619 i2c.apply_config(&config)?;
620
621 Ok(i2c)
622 }
623
624 pub fn into_async(mut self) -> I2c<'d, Async> {
626 self.set_interrupt_handler(self.driver().info.async_handler);
627
628 I2c {
629 i2c: self.i2c,
630 phantom: PhantomData,
631 guard: self.guard,
632 config: self.config,
633 }
634 }
635
636 #[cfg_attr(
637 not(multi_core),
638 doc = "Registers an interrupt handler for the peripheral."
639 )]
640 #[cfg_attr(
641 multi_core,
642 doc = "Registers an interrupt handler for the peripheral on the current core."
643 )]
644 #[doc = ""]
645 #[instability::unstable]
656 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
657 self.i2c.info().set_interrupt_handler(handler);
658 }
659
660 #[instability::unstable]
662 pub fn listen(&mut self, interrupts: impl Into<EnumSet<Event>>) {
663 self.i2c.info().enable_listen(interrupts.into(), true)
664 }
665
666 #[instability::unstable]
668 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<Event>>) {
669 self.i2c.info().enable_listen(interrupts.into(), false)
670 }
671
672 #[instability::unstable]
674 pub fn interrupts(&mut self) -> EnumSet<Event> {
675 self.i2c.info().interrupts()
676 }
677
678 #[instability::unstable]
680 pub fn clear_interrupts(&mut self, interrupts: EnumSet<Event>) {
681 self.i2c.info().clear_interrupts(interrupts)
682 }
683}
684
685impl private::Sealed for I2c<'_, Blocking> {}
686
687#[instability::unstable]
688impl crate::interrupt::InterruptConfigurable for I2c<'_, Blocking> {
689 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
690 self.i2c.info().set_interrupt_handler(handler);
691 }
692}
693
694#[cfg_attr(esp32, allow(dead_code))]
695#[derive(Debug, EnumSetType)]
696#[cfg_attr(feature = "defmt", derive(defmt::Format))]
697#[non_exhaustive]
698#[instability::unstable]
699pub enum Event {
700 EndDetect,
703
704 TxComplete,
706
707 #[cfg(not(any(esp32, esp32s2)))]
710 TxFifoWatermark,
711}
712
713#[must_use = "futures do nothing unless you `.await` or poll them"]
714struct I2cFuture<'a> {
715 events: EnumSet<Event>,
716 driver: Driver<'a>,
717 deadline: Option<Instant>,
718 finished: bool,
719}
720
721impl<'a> I2cFuture<'a> {
722 pub fn new(events: EnumSet<Event>, driver: Driver<'a>, deadline: Option<Instant>) -> Self {
723 driver.regs().int_ena().modify(|_, w| {
724 for event in events {
725 match event {
726 Event::EndDetect => w.end_detect().set_bit(),
727 Event::TxComplete => w.trans_complete().set_bit(),
728 #[cfg(not(any(esp32, esp32s2)))]
729 Event::TxFifoWatermark => w.txfifo_wm().set_bit(),
730 };
731 }
732
733 w.arbitration_lost().set_bit();
734 w.time_out().set_bit();
735 w.nack().set_bit();
736 #[cfg(not(any(esp32, esp32s2)))]
737 {
738 w.scl_main_st_to().set_bit();
739 w.scl_st_to().set_bit();
740 }
741
742 w
743 });
744
745 Self::new_blocking(events, driver, deadline)
746 }
747
748 pub fn new_blocking(
749 events: EnumSet<Event>,
750 driver: Driver<'a>,
751 deadline: Option<Instant>,
752 ) -> Self {
753 Self {
754 events,
755 driver,
756 deadline,
757 finished: false,
758 }
759 }
760
761 fn is_done(&self) -> bool {
762 !self.driver.info.interrupts().is_disjoint(self.events)
763 }
764
765 fn poll_completion(&mut self) -> Poll<Result<(), Error>> {
766 let error = self.driver.check_errors();
767
768 let now = if self.deadline.is_some() {
769 Instant::now()
770 } else {
771 Instant::EPOCH
772 };
773
774 if self.is_done() {
775 self.finished = true;
776 let result = if error == Err(Error::Timeout) {
778 Ok(())
779 } else {
780 error
781 };
782 Poll::Ready(result)
783 } else if error.is_err() {
784 self.finished = true;
785 Poll::Ready(error)
786 } else {
787 if let Some(deadline) = self.deadline {
788 if now > deadline {
789 return Poll::Ready(Err(Error::Timeout));
791 }
792 }
793
794 Poll::Pending
795 }
796 }
797}
798
799impl core::future::Future for I2cFuture<'_> {
800 type Output = Result<(), Error>;
801
802 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
803 self.driver.state.waker.register(ctx.waker());
804
805 let result = self.poll_completion();
806
807 if result.is_pending() && self.deadline.is_some() {
808 ctx.waker().wake_by_ref();
809 }
810
811 result
812 }
813}
814
815impl Drop for I2cFuture<'_> {
816 fn drop(&mut self) {
817 if !self.finished {
818 self.driver.reset_fsm();
819 self.driver.clear_bus_blocking();
820 }
821 }
822}
823
824impl<'d> I2c<'d, Async> {
825 pub fn into_blocking(self) -> I2c<'d, Blocking> {
827 self.i2c.info().disable_interrupts();
828
829 I2c {
830 i2c: self.i2c,
831 phantom: PhantomData,
832 guard: self.guard,
833 config: self.config,
834 }
835 }
836
837 pub async fn write_async<A: Into<I2cAddress>>(
839 &mut self,
840 address: A,
841 buffer: &[u8],
842 ) -> Result<(), Error> {
843 self.transaction_async(address, &mut [Operation::Write(buffer)])
844 .await
845 }
846
847 pub async fn read_async<A: Into<I2cAddress>>(
854 &mut self,
855 address: A,
856 buffer: &mut [u8],
857 ) -> Result<(), Error> {
858 self.transaction_async(address, &mut [Operation::Read(buffer)])
859 .await
860 }
861
862 pub async fn write_read_async<A: Into<I2cAddress>>(
870 &mut self,
871 address: A,
872 write_buffer: &[u8],
873 read_buffer: &mut [u8],
874 ) -> Result<(), Error> {
875 self.transaction_async(
876 address,
877 &mut [Operation::Write(write_buffer), Operation::Read(read_buffer)],
878 )
879 .await
880 }
881
882 #[cfg_attr(
902 any(esp32, esp32s2),
903 doc = "\n\nOn ESP32 and ESP32-S2 there might be issues combining large read/write operations with small (<3 bytes) read/write operations.\n\n"
904 )]
905 pub async fn transaction_async<'a, A: Into<I2cAddress>>(
910 &mut self,
911 address: A,
912 operations: impl IntoIterator<Item = &'a mut Operation<'a>>,
913 ) -> Result<(), Error> {
914 self.driver()
915 .transaction_impl_async(address.into(), operations.into_iter().map(Operation::from))
916 .await
917 .inspect_err(|_| self.internal_recover())
918 }
919}
920
921impl<'d, Dm> I2c<'d, Dm>
922where
923 Dm: DriverMode,
924{
925 fn driver(&self) -> Driver<'_> {
926 Driver {
927 info: self.i2c.info(),
928 state: self.i2c.state(),
929 config: &self.config,
930 }
931 }
932
933 fn internal_recover(&self) {
934 if self.driver().regs().sr().read().bus_busy().bit_is_set() {
935 self.driver().clear_bus_blocking();
937 }
938
939 self.driver().reset_fsm();
940 }
941
942 pub fn with_sda(mut self, sda: impl PeripheralOutput<'d>) -> Self {
946 let info = self.driver().info;
947 let input = info.sda_input;
948 let output = info.sda_output;
949 Driver::connect_pin(sda.into(), input, output, &mut self.config.sda_pin);
950
951 self
952 }
953
954 pub fn with_scl(mut self, scl: impl PeripheralOutput<'d>) -> Self {
958 let info = self.driver().info;
959 let input = info.scl_input;
960 let output = info.scl_output;
961 Driver::connect_pin(scl.into(), input, output, &mut self.config.scl_pin);
962
963 self
964 }
965
966 #[doc = crate::before_snippet!()]
969 pub fn write<A: Into<I2cAddress>>(&mut self, address: A, buffer: &[u8]) -> Result<(), Error> {
980 self.transaction(address, &mut [Operation::Write(buffer)])
981 }
982
983 #[doc = crate::before_snippet!()]
986 pub fn read<A: Into<I2cAddress>>(
1002 &mut self,
1003 address: A,
1004 buffer: &mut [u8],
1005 ) -> Result<(), Error> {
1006 self.transaction(address, &mut [Operation::Read(buffer)])
1007 }
1008
1009 #[doc = crate::before_snippet!()]
1013 pub fn write_read<A: Into<I2cAddress>>(
1029 &mut self,
1030 address: A,
1031 write_buffer: &[u8],
1032 read_buffer: &mut [u8],
1033 ) -> Result<(), Error> {
1034 self.transaction(
1035 address,
1036 &mut [Operation::Write(write_buffer), Operation::Read(read_buffer)],
1037 )
1038 }
1039
1040 #[doc = crate::before_snippet!()]
1061 #[cfg_attr(
1077 any(esp32, esp32s2),
1078 doc = "\n\nOn ESP32 and ESP32-S2 it is advisable to not combine large read/write operations with small (<3 bytes) read/write operations.\n\n"
1079 )]
1080 pub fn transaction<'a, A: Into<I2cAddress>>(
1085 &mut self,
1086 address: A,
1087 operations: impl IntoIterator<Item = &'a mut Operation<'a>>,
1088 ) -> Result<(), Error> {
1089 self.driver()
1090 .transaction_impl(address.into(), operations.into_iter().map(Operation::from))
1091 .inspect_err(|_| self.internal_recover())
1092 }
1093
1094 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1101 self.config.config = *config;
1102 self.driver().setup(config)?;
1103 self.driver().reset_fsm();
1104 Ok(())
1105 }
1106}
1107
1108impl embedded_hal_async::i2c::I2c for I2c<'_, Async> {
1109 async fn transaction(
1110 &mut self,
1111 address: u8,
1112 operations: &mut [EhalOperation<'_>],
1113 ) -> Result<(), Self::Error> {
1114 self.driver()
1115 .transaction_impl_async(address.into(), operations.iter_mut().map(Operation::from))
1116 .await
1117 .inspect_err(|_| self.internal_recover())
1118 }
1119}
1120
1121fn async_handler(info: &Info, state: &State) {
1122 info.regs().int_ena().write(|w| unsafe { w.bits(0) });
1125
1126 state.waker.wake();
1127}
1128
1129fn set_filter(
1132 register_block: &RegisterBlock,
1133 sda_threshold: Option<u8>,
1134 scl_threshold: Option<u8>,
1135) {
1136 cfg_if::cfg_if! {
1137 if #[cfg(any(esp32, esp32s2))] {
1138 register_block.sda_filter_cfg().modify(|_, w| {
1139 if let Some(threshold) = sda_threshold {
1140 unsafe { w.sda_filter_thres().bits(threshold) };
1141 }
1142 w.sda_filter_en().bit(sda_threshold.is_some())
1143 });
1144 register_block.scl_filter_cfg().modify(|_, w| {
1145 if let Some(threshold) = scl_threshold {
1146 unsafe { w.scl_filter_thres().bits(threshold) };
1147 }
1148 w.scl_filter_en().bit(scl_threshold.is_some())
1149 });
1150 } else {
1151 register_block.filter_cfg().modify(|_, w| {
1152 if let Some(threshold) = sda_threshold {
1153 unsafe { w.sda_filter_thres().bits(threshold) };
1154 }
1155 if let Some(threshold) = scl_threshold {
1156 unsafe { w.scl_filter_thres().bits(threshold) };
1157 }
1158 w.sda_filter_en().bit(sda_threshold.is_some());
1159 w.scl_filter_en().bit(scl_threshold.is_some())
1160 });
1161 }
1162 }
1163}
1164
1165#[allow(clippy::too_many_arguments, unused)]
1166fn configure_clock(
1168 register_block: &RegisterBlock,
1169 sclk_div: u32,
1170 scl_low_period: u32,
1171 scl_high_period: u32,
1172 scl_wait_high_period: u32,
1173 sda_hold_time: u32,
1174 sda_sample_time: u32,
1175 scl_rstart_setup_time: u32,
1176 scl_stop_setup_time: u32,
1177 scl_start_hold_time: u32,
1178 scl_stop_hold_time: u32,
1179 timeout: BusTimeout,
1180) -> Result<(), ConfigError> {
1181 unsafe {
1182 #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
1184 register_block.clk_conf().modify(|_, w| {
1185 w.sclk_sel().clear_bit();
1186 w.sclk_div_num().bits((sclk_div - 1) as u8)
1187 });
1188
1189 register_block
1191 .scl_low_period()
1192 .write(|w| w.scl_low_period().bits(scl_low_period as u16));
1193
1194 #[cfg(not(esp32))]
1195 let scl_wait_high_period = scl_wait_high_period
1196 .try_into()
1197 .map_err(|_| ConfigError::FrequencyInvalid)?;
1198
1199 register_block.scl_high_period().write(|w| {
1200 #[cfg(not(esp32))] w.scl_wait_high_period().bits(scl_wait_high_period);
1202 w.scl_high_period().bits(scl_high_period as u16)
1203 });
1204
1205 register_block
1207 .sda_hold()
1208 .write(|w| w.time().bits(sda_hold_time as u16));
1209 register_block
1210 .sda_sample()
1211 .write(|w| w.time().bits(sda_sample_time as u16));
1212
1213 register_block
1215 .scl_rstart_setup()
1216 .write(|w| w.time().bits(scl_rstart_setup_time as u16));
1217 register_block
1218 .scl_stop_setup()
1219 .write(|w| w.time().bits(scl_stop_setup_time as u16));
1220
1221 register_block
1223 .scl_start_hold()
1224 .write(|w| w.time().bits(scl_start_hold_time as u16));
1225 register_block
1226 .scl_stop_hold()
1227 .write(|w| w.time().bits(scl_stop_hold_time as u16));
1228
1229 cfg_if::cfg_if! {
1232 if #[cfg(esp32)] {
1233 register_block
1234 .to()
1235 .write(|w| w.time_out().bits(timeout.cycles()));
1236 } else {
1237 register_block
1238 .to()
1239 .write(|w| w.time_out_en().bit(timeout.is_set())
1240 .time_out_value()
1241 .bits(timeout.cycles() as _)
1242 );
1243 }
1244 }
1245 }
1246 Ok(())
1247}
1248
1249#[doc(hidden)]
1251#[derive(Debug)]
1252#[non_exhaustive]
1253pub struct Info {
1254 pub register_block: *const RegisterBlock,
1258
1259 pub peripheral: crate::system::Peripheral,
1261
1262 pub async_handler: InterruptHandler,
1264
1265 pub interrupt: Interrupt,
1267
1268 pub scl_output: OutputSignal,
1270
1271 pub scl_input: InputSignal,
1273
1274 pub sda_output: OutputSignal,
1276
1277 pub sda_input: InputSignal,
1279}
1280
1281impl Info {
1282 pub fn regs(&self) -> &RegisterBlock {
1284 unsafe { &*self.register_block }
1285 }
1286
1287 fn enable_listen(&self, interrupts: EnumSet<Event>, enable: bool) {
1289 let reg_block = self.regs();
1290
1291 reg_block.int_ena().modify(|_, w| {
1292 for interrupt in interrupts {
1293 match interrupt {
1294 Event::EndDetect => w.end_detect().bit(enable),
1295 Event::TxComplete => w.trans_complete().bit(enable),
1296 #[cfg(not(any(esp32, esp32s2)))]
1297 Event::TxFifoWatermark => w.txfifo_wm().bit(enable),
1298 };
1299 }
1300 w
1301 });
1302 }
1303
1304 fn interrupts(&self) -> EnumSet<Event> {
1305 let mut res = EnumSet::new();
1306 let reg_block = self.regs();
1307
1308 let ints = reg_block.int_raw().read();
1309
1310 if ints.end_detect().bit_is_set() {
1311 res.insert(Event::EndDetect);
1312 }
1313 if ints.trans_complete().bit_is_set() {
1314 res.insert(Event::TxComplete);
1315 }
1316 #[cfg(not(any(esp32, esp32s2)))]
1317 if ints.txfifo_wm().bit_is_set() {
1318 res.insert(Event::TxFifoWatermark);
1319 }
1320
1321 res
1322 }
1323
1324 fn clear_interrupts(&self, interrupts: EnumSet<Event>) {
1325 let reg_block = self.regs();
1326
1327 reg_block.int_clr().write(|w| {
1328 for interrupt in interrupts {
1329 match interrupt {
1330 Event::EndDetect => w.end_detect().clear_bit_by_one(),
1331 Event::TxComplete => w.trans_complete().clear_bit_by_one(),
1332 #[cfg(not(any(esp32, esp32s2)))]
1333 Event::TxFifoWatermark => w.txfifo_wm().clear_bit_by_one(),
1334 };
1335 }
1336 w
1337 });
1338 }
1339
1340 fn set_interrupt_handler(&self, handler: InterruptHandler) {
1341 for core in crate::system::Cpu::other() {
1342 crate::interrupt::disable(core, self.interrupt);
1343 }
1344 self.enable_listen(EnumSet::all(), false);
1345 self.clear_interrupts(EnumSet::all());
1346 unsafe { crate::interrupt::bind_interrupt(self.interrupt, handler.handler()) };
1347 unwrap!(crate::interrupt::enable(self.interrupt, handler.priority()));
1348 }
1349
1350 fn disable_interrupts(&self) {
1351 crate::interrupt::disable(crate::system::Cpu::current(), self.interrupt);
1352 }
1353}
1354
1355impl PartialEq for Info {
1356 fn eq(&self, other: &Self) -> bool {
1357 core::ptr::eq(self.register_block, other.register_block)
1358 }
1359}
1360
1361unsafe impl Sync for Info {}
1362
1363#[derive(Clone, Copy)]
1364enum Deadline {
1365 None,
1366 Fixed(Instant),
1367 PerByte(Duration),
1368}
1369
1370impl Deadline {
1371 fn start(self, data_len: usize) -> Option<Instant> {
1372 match self {
1373 Deadline::None => None,
1374 Deadline::Fixed(deadline) => Some(deadline),
1375 Deadline::PerByte(duration) => Some(Instant::now() + duration * data_len as u32),
1376 }
1377 }
1378}
1379
1380#[allow(dead_code)] #[derive(Clone, Copy)]
1382struct Driver<'a> {
1383 info: &'a Info,
1384 state: &'a State,
1385 config: &'a DriverConfig,
1386}
1387
1388impl Driver<'_> {
1389 fn regs(&self) -> &RegisterBlock {
1390 self.info.regs()
1391 }
1392
1393 fn connect_pin(
1394 pin: crate::gpio::interconnect::OutputSignal<'_>,
1395 input: InputSignal,
1396 output: OutputSignal,
1397 guard: &mut PinGuard,
1398 ) {
1399 pin.set_output_high(true);
1401
1402 pin.apply_output_config(
1403 &OutputConfig::default()
1404 .with_drive_mode(DriveMode::OpenDrain)
1405 .with_pull(Pull::Up),
1406 );
1407 pin.set_output_enable(true);
1408 pin.set_input_enable(true);
1409
1410 input.connect_to(&pin);
1411
1412 *guard = interconnect::OutputSignal::connect_with_guard(pin, output);
1413 }
1414
1415 fn init_master(&self) {
1416 self.regs().ctr().write(|w| {
1417 w.ms_mode().set_bit();
1419 w.sda_force_out().set_bit();
1421 w.scl_force_out().set_bit();
1422 w.tx_lsb_first().clear_bit();
1424 w.rx_lsb_first().clear_bit();
1425
1426 #[cfg(not(esp32))]
1427 w.arbitration_en().clear_bit();
1428
1429 #[cfg(esp32s2)]
1430 w.ref_always_on().set_bit();
1431
1432 w.clk_en().set_bit()
1434 });
1435 }
1436
1437 fn setup(&self, config: &Config) -> Result<(), ConfigError> {
1440 self.init_master();
1441
1442 set_filter(self.regs(), Some(7), Some(7));
1445
1446 self.set_frequency(config)?;
1448
1449 #[cfg(not(any(esp32, esp32s2)))]
1451 {
1452 self.regs()
1453 .scl_st_time_out()
1454 .write(|w| unsafe { w.scl_st_to().bits(config.scl_st_timeout.value()) });
1455 self.regs()
1456 .scl_main_st_time_out()
1457 .write(|w| unsafe { w.scl_main_st_to().bits(config.scl_main_st_timeout.value()) });
1458 }
1459
1460 self.update_registers();
1461
1462 Ok(())
1463 }
1464
1465 fn reset_fsm(&self) {
1474 cfg_if::cfg_if! {
1475 if #[cfg(any(esp32c6, esp32h2))] {
1476 self.regs().ctr().modify(|_, w| w.fsm_rst().set_bit());
1478 } else {
1479 crate::system::PeripheralClockControl::disable(self.info.peripheral);
1484 crate::system::PeripheralClockControl::enable(self.info.peripheral);
1485
1486 self.setup(&self.config.config).ok();
1489 }
1490 }
1491 }
1492
1493 fn ensure_idle_blocking(&self) {
1494 if self.regs().sr().read().bus_busy().bit_is_set() {
1495 self.clear_bus_blocking();
1497 }
1498 }
1499
1500 async fn ensure_idle(&self) {
1501 if self.regs().sr().read().bus_busy().bit_is_set() {
1502 self.clear_bus().await;
1504 }
1505 }
1506
1507 fn reset_before_transmission(&self) {
1508 self.clear_all_interrupts();
1510
1511 self.reset_fifo();
1513
1514 self.reset_command_list();
1516 }
1517
1518 fn clear_bus_blocking(&self) {
1524 let mut future = ClearBusFuture::new(*self);
1525 let start = Instant::now();
1526 while future.poll_completion().is_pending() {
1527 if start.elapsed() > CLEAR_BUS_TIMEOUT_MS {
1528 break;
1529 }
1530 }
1531 }
1532
1533 async fn clear_bus(&self) {
1534 let clear_bus = ClearBusFuture::new(*self);
1535 let start = Instant::now();
1536
1537 embassy_futures::select::select(clear_bus, async {
1538 while start.elapsed() < CLEAR_BUS_TIMEOUT_MS {
1539 embassy_futures::yield_now().await;
1540 }
1541 })
1542 .await;
1543 }
1544
1545 fn reset_command_list(&self) {
1547 for cmd in self.regs().comd_iter() {
1548 cmd.reset();
1549 }
1550 }
1551
1552 #[cfg(esp32)]
1553 fn set_frequency(&self, clock_config: &Config) -> Result<(), ConfigError> {
1557 let timeout = clock_config.timeout;
1558
1559 let clocks = Clocks::get();
1560 let source_clk = clocks.i2c_clock.as_hz();
1561 let bus_freq = clock_config.frequency.as_hz();
1562
1563 let half_cycle: u32 = source_clk / bus_freq / 2;
1564 let scl_low = half_cycle;
1565 let scl_high = half_cycle;
1566 let sda_hold = half_cycle / 2;
1567 let sda_sample = scl_high / 2;
1568 let setup = half_cycle;
1569 let hold = half_cycle;
1570 let timeout = BusTimeout::BusCycles(match timeout {
1571 BusTimeout::Maximum => 0xF_FFFF,
1572 BusTimeout::BusCycles(cycles) => check_timeout(cycles * 2 * half_cycle, 0xF_FFFF)?,
1573 });
1574
1575 let scl_low = scl_low - 1;
1578 let mut scl_high = scl_high;
1584 scl_high -= 7 + 6;
1590
1591 let scl_high_period = scl_high;
1603 let scl_low_period = scl_low;
1604 let sda_hold_time = sda_hold;
1606 let sda_sample_time = sda_sample;
1607 let scl_rstart_setup_time = setup;
1609 let scl_stop_setup_time = setup;
1610 let scl_start_hold_time = hold;
1612 let scl_stop_hold_time = hold;
1613
1614 configure_clock(
1615 self.regs(),
1616 0,
1617 scl_low_period,
1618 scl_high_period,
1619 0,
1620 sda_hold_time,
1621 sda_sample_time,
1622 scl_rstart_setup_time,
1623 scl_stop_setup_time,
1624 scl_start_hold_time,
1625 scl_stop_hold_time,
1626 timeout,
1627 )?;
1628
1629 Ok(())
1630 }
1631
1632 #[cfg(esp32s2)]
1633 fn set_frequency(&self, clock_config: &Config) -> Result<(), ConfigError> {
1637 let timeout = clock_config.timeout;
1638
1639 let clocks = Clocks::get();
1640 let source_clk = clocks.apb_clock.as_hz();
1641 let bus_freq = clock_config.frequency.as_hz();
1642
1643 let half_cycle: u32 = source_clk / bus_freq / 2;
1644 let scl_low = half_cycle;
1646 let scl_high = half_cycle / 2 + 2;
1648 let scl_wait_high = half_cycle - scl_high;
1649 let sda_hold = half_cycle / 2;
1650 let sda_sample = half_cycle / 2 - 1;
1652 let setup = half_cycle;
1653 let hold = half_cycle;
1654
1655 let scl_low_period = scl_low - 1;
1657 let scl_high_period = scl_high;
1658 let scl_wait_high_period = scl_wait_high;
1659 let sda_hold_time = sda_hold;
1661 let sda_sample_time = sda_sample;
1662 let scl_rstart_setup_time = setup;
1664 let scl_stop_setup_time = setup;
1665 let scl_start_hold_time = hold - 1;
1667 let scl_stop_hold_time = hold;
1668
1669 let timeout = BusTimeout::BusCycles(match timeout {
1670 BusTimeout::Maximum => 0xFF_FFFF,
1671 BusTimeout::BusCycles(cycles) => check_timeout(cycles * 2 * half_cycle, 0xFF_FFFF)?,
1672 });
1673
1674 configure_clock(
1675 self.regs(),
1676 0,
1677 scl_low_period,
1678 scl_high_period,
1679 scl_wait_high_period,
1680 sda_hold_time,
1681 sda_sample_time,
1682 scl_rstart_setup_time,
1683 scl_stop_setup_time,
1684 scl_start_hold_time,
1685 scl_stop_hold_time,
1686 timeout,
1687 )?;
1688
1689 Ok(())
1690 }
1691
1692 #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
1693 fn set_frequency(&self, clock_config: &Config) -> Result<(), ConfigError> {
1697 let timeout = clock_config.timeout;
1698
1699 let clocks = Clocks::get();
1700 let source_clk = clocks.xtal_clock.as_hz();
1701 let bus_freq = clock_config.frequency.as_hz();
1702
1703 let clkm_div: u32 = source_clk / (bus_freq * 1024) + 1;
1704 let sclk_freq: u32 = source_clk / clkm_div;
1705 let half_cycle: u32 = sclk_freq / bus_freq / 2;
1706 let scl_low = half_cycle;
1708 let scl_wait_high = if bus_freq >= 80 * 1000 {
1713 half_cycle / 2 - 2
1714 } else {
1715 half_cycle / 4
1716 };
1717 let scl_high = half_cycle - scl_wait_high;
1718 let sda_hold = half_cycle / 4;
1719 let sda_sample = half_cycle / 2 + scl_wait_high;
1720 let setup = half_cycle;
1721 let hold = half_cycle;
1722
1723 let scl_low_period = scl_low - 1;
1731 let scl_high_period = scl_high;
1732 let scl_wait_high_period = scl_wait_high;
1733 let sda_hold_time = sda_hold - 1;
1735 let sda_sample_time = sda_sample - 1;
1736 let scl_rstart_setup_time = setup - 1;
1738 let scl_stop_setup_time = setup - 1;
1739 let scl_start_hold_time = hold - 1;
1741 let scl_stop_hold_time = hold - 1;
1742
1743 let timeout = match timeout {
1744 BusTimeout::Maximum => BusTimeout::BusCycles(0x1F),
1745 BusTimeout::Disabled => BusTimeout::Disabled,
1746 BusTimeout::BusCycles(cycles) => {
1747 let to_peri = (cycles * 2 * half_cycle).max(1);
1748 let log2 = to_peri.ilog2();
1749 let raw = if to_peri != 1 << log2 { log2 + 1 } else { log2 };
1751 BusTimeout::BusCycles(check_timeout(raw, 0x1F)?)
1752 }
1753 };
1754
1755 configure_clock(
1756 self.regs(),
1757 clkm_div,
1758 scl_low_period,
1759 scl_high_period,
1760 scl_wait_high_period,
1761 sda_hold_time,
1762 sda_sample_time,
1763 scl_rstart_setup_time,
1764 scl_stop_setup_time,
1765 scl_start_hold_time,
1766 scl_stop_hold_time,
1767 timeout,
1768 )?;
1769
1770 Ok(())
1771 }
1772
1773 fn setup_write<'a, I>(
1780 &self,
1781 addr: I2cAddress,
1782 bytes: &[u8],
1783 start: bool,
1784 cmd_iterator: &mut I,
1785 ) -> Result<(), Error>
1786 where
1787 I: Iterator<Item = &'a COMD>,
1788 {
1789 let max_len = if start {
1792 I2C_CHUNK_SIZE
1793 } else {
1794 I2C_CHUNK_SIZE + 1
1795 };
1796 if bytes.len() > max_len {
1797 return Err(Error::FifoExceeded);
1798 }
1799
1800 if start {
1801 add_cmd(cmd_iterator, Command::Start)?;
1802 }
1803
1804 let write_len = if start { bytes.len() + 1 } else { bytes.len() };
1805 if write_len > 0 {
1807 if cfg!(any(esp32, esp32s2)) {
1808 if write_len < 2 {
1810 add_cmd(
1811 cmd_iterator,
1812 Command::Write {
1813 ack_exp: Ack::Ack,
1814 ack_check_en: true,
1815 length: write_len as u8,
1816 },
1817 )?;
1818 } else if start {
1819 add_cmd(
1820 cmd_iterator,
1821 Command::Write {
1822 ack_exp: Ack::Ack,
1823 ack_check_en: true,
1824 length: (write_len as u8) - 1,
1825 },
1826 )?;
1827 add_cmd(
1828 cmd_iterator,
1829 Command::Write {
1830 ack_exp: Ack::Ack,
1831 ack_check_en: true,
1832 length: 1,
1833 },
1834 )?;
1835 } else {
1836 add_cmd(
1837 cmd_iterator,
1838 Command::Write {
1839 ack_exp: Ack::Ack,
1840 ack_check_en: true,
1841 length: (write_len as u8) - 2,
1842 },
1843 )?;
1844 add_cmd(
1845 cmd_iterator,
1846 Command::Write {
1847 ack_exp: Ack::Ack,
1848 ack_check_en: true,
1849 length: 1,
1850 },
1851 )?;
1852 add_cmd(
1853 cmd_iterator,
1854 Command::Write {
1855 ack_exp: Ack::Ack,
1856 ack_check_en: true,
1857 length: 1,
1858 },
1859 )?;
1860 }
1861 } else {
1862 add_cmd(
1863 cmd_iterator,
1864 Command::Write {
1865 ack_exp: Ack::Ack,
1866 ack_check_en: true,
1867 length: write_len as u8,
1868 },
1869 )?;
1870 }
1871 }
1872
1873 if start {
1874 match addr {
1876 I2cAddress::SevenBit(addr) => {
1877 write_fifo(self.regs(), (addr << 1) | OperationType::Write as u8);
1878 }
1879 }
1880 }
1881 for b in bytes {
1882 write_fifo(self.regs(), *b);
1883 }
1884
1885 Ok(())
1886 }
1887
1888 fn setup_read<'a, I>(
1897 &self,
1898 addr: I2cAddress,
1899 buffer: &mut [u8],
1900 start: bool,
1901 will_continue: bool,
1902 cmd_iterator: &mut I,
1903 ) -> Result<(), Error>
1904 where
1905 I: Iterator<Item = &'a COMD>,
1906 {
1907 if buffer.is_empty() {
1908 return Err(Error::ZeroLengthInvalid);
1909 }
1910 let (max_len, initial_len) = if will_continue {
1911 (I2C_CHUNK_SIZE + 1, buffer.len())
1912 } else {
1913 (I2C_CHUNK_SIZE, buffer.len() - 1)
1914 };
1915 if buffer.len() > max_len {
1916 return Err(Error::FifoExceeded);
1917 }
1918
1919 if start {
1920 add_cmd(cmd_iterator, Command::Start)?;
1921 add_cmd(
1923 cmd_iterator,
1924 Command::Write {
1925 ack_exp: Ack::Ack,
1926 ack_check_en: true,
1927 length: 1,
1928 },
1929 )?;
1930 }
1931
1932 if initial_len > 0 {
1933 if cfg!(any(esp32, esp32s2)) {
1934 if initial_len < 2 || start {
1936 add_cmd(
1937 cmd_iterator,
1938 Command::Read {
1939 ack_value: Ack::Ack,
1940 length: initial_len as u8,
1941 },
1942 )?;
1943 } else if !will_continue {
1944 add_cmd(
1945 cmd_iterator,
1946 Command::Read {
1947 ack_value: Ack::Ack,
1948 length: (initial_len as u8) - 1,
1949 },
1950 )?;
1951 add_cmd(
1952 cmd_iterator,
1953 Command::Read {
1954 ack_value: Ack::Ack,
1955 length: 1,
1956 },
1957 )?;
1958 } else {
1959 add_cmd(
1960 cmd_iterator,
1961 Command::Read {
1962 ack_value: Ack::Ack,
1963 length: (initial_len as u8) - 2,
1964 },
1965 )?;
1966 add_cmd(
1967 cmd_iterator,
1968 Command::Read {
1969 ack_value: Ack::Ack,
1970 length: 1,
1971 },
1972 )?;
1973 add_cmd(
1974 cmd_iterator,
1975 Command::Read {
1976 ack_value: Ack::Ack,
1977 length: 1,
1978 },
1979 )?;
1980 }
1981 } else {
1982 add_cmd(
1983 cmd_iterator,
1984 Command::Read {
1985 ack_value: Ack::Ack,
1986 length: initial_len as u8,
1987 },
1988 )?;
1989 }
1990 }
1991
1992 if !will_continue {
1993 add_cmd(
1996 cmd_iterator,
1997 Command::Read {
1998 ack_value: Ack::Nack,
1999 length: 1,
2000 },
2001 )?;
2002 }
2003
2004 self.update_registers();
2005
2006 if start {
2007 match addr {
2009 I2cAddress::SevenBit(addr) => {
2010 write_fifo(self.regs(), (addr << 1) | OperationType::Read as u8);
2011 }
2012 }
2013 }
2014 Ok(())
2015 }
2016
2017 fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> {
2019 if buffer.len() > I2C_FIFO_SIZE {
2021 return Err(Error::FifoExceeded);
2022 }
2023
2024 if self.regs().sr().read().rxfifo_cnt().bits() < buffer.len() as u8 {
2025 return Err(Error::ExecutionIncomplete);
2026 }
2027
2028 for byte in buffer.iter_mut() {
2030 *byte = read_fifo(self.regs());
2031 }
2032
2033 Ok(())
2034 }
2035
2036 fn clear_all_interrupts(&self) {
2038 self.regs()
2039 .int_clr()
2040 .write(|w| unsafe { w.bits(I2C_LL_INTR_MASK) });
2041 }
2042
2043 async fn wait_for_completion(&self, deadline: Option<Instant>) -> Result<(), Error> {
2044 I2cFuture::new(Event::TxComplete | Event::EndDetect, *self, deadline).await?;
2045 self.check_all_commands_done(deadline).await
2046 }
2047
2048 fn wait_for_completion_blocking(&self, deadline: Option<Instant>) -> Result<(), Error> {
2050 let mut future =
2051 I2cFuture::new_blocking(Event::TxComplete | Event::EndDetect, *self, deadline);
2052 loop {
2053 if let Poll::Ready(result) = future.poll_completion() {
2054 result?;
2055 return self.check_all_commands_done_blocking(deadline);
2056 }
2057 }
2058 }
2059
2060 fn all_commands_done(&self, deadline: Option<Instant>) -> Result<bool, Error> {
2061 let now = if deadline.is_some() {
2065 Instant::now()
2066 } else {
2067 Instant::EPOCH
2068 };
2069
2070 for cmd_reg in self.regs().comd_iter() {
2071 let cmd = cmd_reg.read();
2072
2073 if cmd.bits() != 0x0 && !cmd.opcode().is_end() && !cmd.command_done().bit_is_set() {
2075 if let Some(deadline) = deadline {
2077 if now > deadline {
2078 return Err(Error::ExecutionIncomplete);
2079 }
2080 }
2081 return Ok(false);
2082 }
2083
2084 if cmd.opcode().is_end() {
2086 break;
2087 }
2088 if cmd.opcode().is_stop() {
2089 #[cfg(esp32)]
2090 if self.regs().sr().read().scl_state_last() == 6 {
2093 self.check_errors()?;
2094 } else {
2095 continue;
2096 }
2097 break;
2098 }
2099 }
2100 Ok(true)
2101 }
2102
2103 fn check_all_commands_done_blocking(&self, deadline: Option<Instant>) -> Result<(), Error> {
2105 while !self.all_commands_done(deadline)? {}
2107
2108 Ok(())
2109 }
2110
2111 async fn check_all_commands_done(&self, deadline: Option<Instant>) -> Result<(), Error> {
2113 while !self.all_commands_done(deadline)? {
2115 embassy_futures::yield_now().await;
2116 }
2117
2118 Ok(())
2119 }
2120
2121 fn check_errors(&self) -> Result<(), Error> {
2129 let r = self.regs().int_raw().read();
2130
2131 if r.time_out().bit_is_set() {
2136 return Err(Error::Timeout);
2137 }
2138 if r.nack().bit_is_set() {
2139 return Err(Error::AcknowledgeCheckFailed(estimate_ack_failed_reason(
2140 self.regs(),
2141 )));
2142 }
2143 if r.arbitration_lost().bit_is_set() {
2144 return Err(Error::ArbitrationLost);
2145 }
2146
2147 #[cfg(not(any(esp32, esp32s2)))]
2148 {
2149 if r.scl_st_to().bit_is_set() {
2150 return Err(Error::Timeout);
2151 }
2152 if r.scl_main_st_to().bit_is_set() {
2153 return Err(Error::Timeout);
2154 }
2155 }
2156
2157 #[cfg(not(esp32))]
2158 if r.trans_complete().bit_is_set() && self.regs().sr().read().resp_rec().bit_is_clear() {
2159 return Err(Error::AcknowledgeCheckFailed(
2160 AcknowledgeCheckFailedReason::Data,
2161 ));
2162 }
2163
2164 Ok(())
2165 }
2166
2167 fn update_registers(&self) {
2177 #[cfg(not(any(esp32, esp32s2)))]
2180 self.regs().ctr().modify(|_, w| w.conf_upgate().set_bit());
2181 }
2182
2183 fn start_transmission(&self) {
2185 self.regs().ctr().modify(|_, w| w.trans_start().set_bit());
2187 }
2188
2189 #[cfg(not(esp32))]
2191 fn reset_fifo(&self) {
2192 self.regs().fifo_conf().modify(|_, w| unsafe {
2194 w.tx_fifo_rst().set_bit();
2195 w.rx_fifo_rst().set_bit();
2196 w.nonfifo_en().clear_bit();
2197 w.fifo_prt_en().set_bit();
2198 w.rxfifo_wm_thrhd().bits(1);
2199 w.txfifo_wm_thrhd().bits(8)
2200 });
2201
2202 self.regs().fifo_conf().modify(|_, w| {
2203 w.tx_fifo_rst().clear_bit();
2204 w.rx_fifo_rst().clear_bit()
2205 });
2206
2207 self.regs().int_clr().write(|w| {
2208 w.rxfifo_wm().clear_bit_by_one();
2209 w.txfifo_wm().clear_bit_by_one()
2210 });
2211
2212 self.update_registers();
2213 }
2214
2215 #[cfg(esp32)]
2217 fn reset_fifo(&self) {
2218 self.regs().fifo_conf().modify(|_, w| unsafe {
2220 w.tx_fifo_rst().set_bit();
2221 w.rx_fifo_rst().set_bit();
2222 w.nonfifo_en().clear_bit();
2223 w.nonfifo_rx_thres().bits(1);
2224 w.nonfifo_tx_thres().bits(32)
2225 });
2226
2227 self.regs().fifo_conf().modify(|_, w| {
2228 w.tx_fifo_rst().clear_bit();
2229 w.rx_fifo_rst().clear_bit()
2230 });
2231
2232 self.regs()
2233 .int_clr()
2234 .write(|w| w.rxfifo_full().clear_bit_by_one());
2235 }
2236
2237 fn start_write_operation(
2238 &self,
2239 address: I2cAddress,
2240 bytes: &[u8],
2241 start: bool,
2242 stop: bool,
2243 deadline: Deadline,
2244 ) -> Result<Option<Instant>, Error> {
2245 let cmd_iterator = &mut self.regs().comd_iter();
2246
2247 self.setup_write(address, bytes, start, cmd_iterator)?;
2248
2249 if stop {
2250 add_cmd(cmd_iterator, Command::Stop)?;
2251 } else {
2252 add_cmd(cmd_iterator, Command::End)?;
2253 }
2254 self.start_transmission();
2255 let deadline = deadline.start(bytes.len() + start as usize);
2256
2257 Ok(deadline)
2258 }
2259
2260 fn start_read_operation(
2271 &self,
2272 address: I2cAddress,
2273 buffer: &mut [u8],
2274 start: bool,
2275 will_continue: bool,
2276 stop: bool,
2277 deadline: Deadline,
2278 ) -> Result<Option<Instant>, Error> {
2279 let cmd_iterator = &mut self.regs().comd_iter();
2280
2281 self.setup_read(address, buffer, start, will_continue, cmd_iterator)?;
2282
2283 if stop {
2284 add_cmd(cmd_iterator, Command::Stop)?;
2285 } else {
2286 add_cmd(cmd_iterator, Command::End)?;
2287 }
2288 self.start_transmission();
2289 let deadline = deadline.start(buffer.len() + start as usize);
2290
2291 Ok(deadline)
2292 }
2293
2294 fn write_operation_blocking(
2303 &self,
2304 address: I2cAddress,
2305 bytes: &[u8],
2306 start: bool,
2307 stop: bool,
2308 deadline: Deadline,
2309 ) -> Result<(), Error> {
2310 address.validate()?;
2311 self.reset_before_transmission();
2312
2313 if bytes.is_empty() && !start && !stop {
2316 return Ok(());
2317 }
2318
2319 let deadline = self.start_write_operation(address, bytes, start, stop, deadline)?;
2320 self.wait_for_completion_blocking(deadline)?;
2321
2322 Ok(())
2323 }
2324
2325 fn read_operation_blocking(
2336 &self,
2337 address: I2cAddress,
2338 buffer: &mut [u8],
2339 start: bool,
2340 stop: bool,
2341 will_continue: bool,
2342 deadline: Deadline,
2343 ) -> Result<(), Error> {
2344 address.validate()?;
2345 self.reset_before_transmission();
2346
2347 if buffer.is_empty() {
2350 return Ok(());
2351 }
2352
2353 let deadline =
2354 self.start_read_operation(address, buffer, start, will_continue, stop, deadline)?;
2355 self.wait_for_completion_blocking(deadline)?;
2356 self.read_all_from_fifo(buffer)?;
2357
2358 Ok(())
2359 }
2360
2361 async fn write_operation(
2370 &self,
2371 address: I2cAddress,
2372 bytes: &[u8],
2373 start: bool,
2374 stop: bool,
2375 deadline: Deadline,
2376 ) -> Result<(), Error> {
2377 address.validate()?;
2378 self.reset_before_transmission();
2379
2380 if bytes.is_empty() && !start && !stop {
2383 return Ok(());
2384 }
2385
2386 let deadline = self.start_write_operation(address, bytes, start, stop, deadline)?;
2387 self.wait_for_completion(deadline).await?;
2388
2389 Ok(())
2390 }
2391
2392 async fn read_operation(
2403 &self,
2404 address: I2cAddress,
2405 buffer: &mut [u8],
2406 start: bool,
2407 stop: bool,
2408 will_continue: bool,
2409 deadline: Deadline,
2410 ) -> Result<(), Error> {
2411 address.validate()?;
2412 self.reset_before_transmission();
2413
2414 if buffer.is_empty() {
2417 return Ok(());
2418 }
2419
2420 let deadline =
2421 self.start_read_operation(address, buffer, start, will_continue, stop, deadline)?;
2422 self.wait_for_completion(deadline).await?;
2423 self.read_all_from_fifo(buffer)?;
2424
2425 Ok(())
2426 }
2427
2428 fn read_blocking(
2429 &self,
2430 address: I2cAddress,
2431 buffer: &mut [u8],
2432 start: bool,
2433 stop: bool,
2434 will_continue: bool,
2435 deadline: Deadline,
2436 ) -> Result<(), Error> {
2437 let chunk_count = VariableChunkIterMut::new(buffer).count();
2438 for (idx, chunk) in VariableChunkIterMut::new(buffer).enumerate() {
2439 self.read_operation_blocking(
2440 address,
2441 chunk,
2442 start && idx == 0,
2443 stop && idx == chunk_count - 1,
2444 will_continue || idx < chunk_count - 1,
2445 deadline,
2446 )?;
2447 }
2448
2449 Ok(())
2450 }
2451
2452 fn write_blocking(
2453 &self,
2454 address: I2cAddress,
2455 buffer: &[u8],
2456 start: bool,
2457 stop: bool,
2458 deadline: Deadline,
2459 ) -> Result<(), Error> {
2460 if buffer.is_empty() {
2461 return self.write_operation_blocking(address, &[], start, stop, deadline);
2462 }
2463
2464 let chunk_count = VariableChunkIter::new(buffer).count();
2465 for (idx, chunk) in VariableChunkIter::new(buffer).enumerate() {
2466 self.write_operation_blocking(
2467 address,
2468 chunk,
2469 start && idx == 0,
2470 stop && idx == chunk_count - 1,
2471 deadline,
2472 )?;
2473 }
2474
2475 Ok(())
2476 }
2477
2478 async fn read(
2479 &self,
2480 address: I2cAddress,
2481 buffer: &mut [u8],
2482 start: bool,
2483 stop: bool,
2484 will_continue: bool,
2485 deadline: Deadline,
2486 ) -> Result<(), Error> {
2487 let chunk_count = VariableChunkIterMut::new(buffer).count();
2488 for (idx, chunk) in VariableChunkIterMut::new(buffer).enumerate() {
2489 self.read_operation(
2490 address,
2491 chunk,
2492 start && idx == 0,
2493 stop && idx == chunk_count - 1,
2494 will_continue || idx < chunk_count - 1,
2495 deadline,
2496 )
2497 .await?;
2498 }
2499
2500 Ok(())
2501 }
2502
2503 async fn write(
2504 &self,
2505 address: I2cAddress,
2506 buffer: &[u8],
2507 start: bool,
2508 stop: bool,
2509 deadline: Deadline,
2510 ) -> Result<(), Error> {
2511 if buffer.is_empty() {
2512 return self
2513 .write_operation(address, &[], start, stop, deadline)
2514 .await;
2515 }
2516
2517 let chunk_count = VariableChunkIter::new(buffer).count();
2518 for (idx, chunk) in VariableChunkIter::new(buffer).enumerate() {
2519 self.write_operation(
2520 address,
2521 chunk,
2522 start && idx == 0,
2523 stop && idx == chunk_count - 1,
2524 deadline,
2525 )
2526 .await?;
2527 }
2528
2529 Ok(())
2530 }
2531
2532 fn transaction_impl<'a>(
2533 &self,
2534 address: I2cAddress,
2535 operations: impl Iterator<Item = Operation<'a>>,
2536 ) -> Result<(), Error> {
2537 address.validate()?;
2538 self.ensure_idle_blocking();
2539
2540 let mut deadline = Deadline::None;
2541
2542 if let SoftwareTimeout::Transaction(timeout) = self.config.config.software_timeout {
2543 deadline = Deadline::Fixed(Instant::now() + timeout);
2544 }
2545
2546 let mut last_op: Option<OpKind> = None;
2547 let mut op_iter = operations
2549 .filter(|op| op.is_write() || !op.is_empty())
2550 .peekable();
2551
2552 while let Some(op) = op_iter.next() {
2553 let next_op = op_iter.peek().map(|v| v.kind());
2554 let kind = op.kind();
2555 match op {
2556 Operation::Write(buffer) => {
2557 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
2561 deadline = Deadline::PerByte(timeout);
2562 }
2563 self.write_blocking(
2564 address,
2565 buffer,
2566 !matches!(last_op, Some(OpKind::Write)),
2567 next_op.is_none(),
2568 deadline,
2569 )?;
2570 }
2571 Operation::Read(buffer) => {
2572 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
2573 deadline = Deadline::PerByte(timeout);
2574 }
2575 self.read_blocking(
2580 address,
2581 buffer,
2582 !matches!(last_op, Some(OpKind::Read)),
2583 next_op.is_none(),
2584 matches!(next_op, Some(OpKind::Read)),
2585 deadline,
2586 )?;
2587 }
2588 }
2589
2590 last_op = Some(kind);
2591 }
2592
2593 Ok(())
2594 }
2595
2596 async fn transaction_impl_async<'a>(
2597 &self,
2598 address: I2cAddress,
2599 operations: impl Iterator<Item = Operation<'a>>,
2600 ) -> Result<(), Error> {
2601 address.validate()?;
2602 self.ensure_idle().await;
2603
2604 let mut deadline = Deadline::None;
2605
2606 if let SoftwareTimeout::Transaction(timeout) = self.config.config.software_timeout {
2607 deadline = Deadline::Fixed(Instant::now() + timeout);
2608 }
2609
2610 let mut last_op: Option<OpKind> = None;
2611 let mut op_iter = operations
2613 .filter(|op| op.is_write() || !op.is_empty())
2614 .peekable();
2615
2616 while let Some(op) = op_iter.next() {
2617 let next_op = op_iter.peek().map(|v| v.kind());
2618 let kind = op.kind();
2619 match op {
2620 Operation::Write(buffer) => {
2621 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
2622 deadline = Deadline::PerByte(timeout);
2623 }
2624 self.write(
2628 address,
2629 buffer,
2630 !matches!(last_op, Some(OpKind::Write)),
2631 next_op.is_none(),
2632 deadline,
2633 )
2634 .await?;
2635 }
2636 Operation::Read(buffer) => {
2637 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
2638 deadline = Deadline::PerByte(timeout);
2639 }
2640 self.read(
2645 address,
2646 buffer,
2647 !matches!(last_op, Some(OpKind::Read)),
2648 next_op.is_none(),
2649 matches!(next_op, Some(OpKind::Read)),
2650 deadline,
2651 )
2652 .await?;
2653 }
2654 }
2655
2656 last_op = Some(kind);
2657 }
2658
2659 Ok(())
2660 }
2661}
2662
2663fn check_timeout(v: u32, max: u32) -> Result<u32, ConfigError> {
2664 if v <= max {
2665 Ok(v)
2666 } else {
2667 Err(ConfigError::TimeoutInvalid)
2668 }
2669}
2670
2671struct VariableChunkIterMut<'a, T> {
2674 buffer: &'a mut [T],
2675}
2676
2677impl<'a, T> VariableChunkIterMut<'a, T> {
2678 fn new(buffer: &'a mut [T]) -> Self {
2679 Self { buffer }
2680 }
2681}
2682
2683impl<'a, T> Iterator for VariableChunkIterMut<'a, T> {
2684 type Item = &'a mut [T];
2685
2686 fn next(&mut self) -> Option<Self::Item> {
2687 if self.buffer.is_empty() {
2688 return None;
2689 }
2690
2691 let s = calculate_chunk_size(self.buffer.len());
2692 let (chunk, remaining) = core::mem::take(&mut self.buffer).split_at_mut(s);
2693 self.buffer = remaining;
2694 Some(chunk)
2695 }
2696}
2697
2698struct VariableChunkIter<'a, T> {
2701 buffer: &'a [T],
2702}
2703
2704impl<'a, T> VariableChunkIter<'a, T> {
2705 fn new(buffer: &'a [T]) -> Self {
2706 Self { buffer }
2707 }
2708}
2709
2710impl<'a, T> Iterator for VariableChunkIter<'a, T> {
2711 type Item = &'a [T];
2712
2713 fn next(&mut self) -> Option<Self::Item> {
2714 if self.buffer.is_empty() {
2715 return None;
2716 }
2717
2718 let s = calculate_chunk_size(self.buffer.len());
2719 let (chunk, remaining) = core::mem::take(&mut self.buffer).split_at(s);
2720 self.buffer = remaining;
2721 Some(chunk)
2722 }
2723}
2724
2725fn calculate_chunk_size(remaining: usize) -> usize {
2726 if remaining <= I2C_CHUNK_SIZE {
2727 remaining
2728 } else if remaining > I2C_CHUNK_SIZE + 2 {
2729 I2C_CHUNK_SIZE
2730 } else {
2731 I2C_CHUNK_SIZE - 2
2732 }
2733}
2734
2735#[cfg(not(any(esp32, esp32s2)))]
2736mod bus_clear {
2737 use super::*;
2738
2739 pub struct ClearBusFuture<'a> {
2740 driver: Driver<'a>,
2741 }
2742
2743 impl<'a> ClearBusFuture<'a> {
2744 const BUS_CLEAR_BITS: u8 = 9;
2746
2747 pub fn new(driver: Driver<'a>) -> Self {
2748 let mut this = Self { driver };
2749 this.configure(Self::BUS_CLEAR_BITS);
2750 this
2751 }
2752
2753 fn configure(&mut self, bits: u8) {
2754 self.driver.regs().scl_sp_conf().modify(|_, w| {
2755 unsafe { w.scl_rst_slv_num().bits(bits) };
2756 w.scl_rst_slv_en().bit(bits > 0)
2757 });
2758 self.driver.update_registers();
2759 }
2760
2761 pub fn poll_completion(&mut self) -> Poll<()> {
2762 if self
2763 .driver
2764 .regs()
2765 .scl_sp_conf()
2766 .read()
2767 .scl_rst_slv_en()
2768 .bit_is_set()
2769 {
2770 Poll::Pending
2771 } else {
2772 Poll::Ready(())
2773 }
2774 }
2775 }
2776
2777 impl Drop for ClearBusFuture<'_> {
2778 fn drop(&mut self) {
2779 self.configure(0);
2780 self.driver.clear_all_interrupts();
2782 }
2783 }
2784}
2785
2786#[cfg(any(esp32, esp32s2))]
2787mod bus_clear {
2788 use super::*;
2789 use crate::gpio::AnyPin;
2790
2791 enum State {
2797 Idle,
2798 SendStop,
2799
2800 SendClock(u8, bool),
2804 }
2805
2806 pub struct ClearBusFuture<'a> {
2807 driver: Driver<'a>,
2808 wait: Instant,
2809 state: State,
2810 sda: Option<AnyPin<'static>>,
2811 scl: Option<AnyPin<'static>>,
2812 }
2813
2814 impl<'a> ClearBusFuture<'a> {
2815 const BUS_CLEAR_BITS: u8 = 9;
2817 const SCL_DELAY: Duration = Duration::from_micros(5);
2819
2820 pub fn new(driver: Driver<'a>) -> Self {
2821 let sda = driver
2825 .config
2826 .sda_pin
2827 .pin_number()
2828 .map(|n| unsafe { AnyPin::steal(n) });
2829 let scl = driver
2830 .config
2831 .scl_pin
2832 .pin_number()
2833 .map(|n| unsafe { AnyPin::steal(n) });
2834
2835 let (Some(sda), Some(scl)) = (sda, scl) else {
2836 return Self {
2838 driver,
2839 wait: Instant::now(),
2840 state: State::Idle,
2841 sda: None,
2842 scl: None,
2843 };
2844 };
2845
2846 driver.info.scl_output.disconnect_from(&scl);
2847 driver.info.sda_output.disconnect_from(&sda);
2848
2849 sda.set_output_high(true);
2850 scl.set_output_high(false);
2851
2852 let state = State::SendClock(Self::BUS_CLEAR_BITS, false);
2858
2859 Self {
2860 driver,
2861 wait: Instant::now() + Self::SCL_DELAY,
2862 state,
2863 sda: Some(sda),
2864 scl: Some(scl),
2865 }
2866 }
2867 }
2868
2869 impl ClearBusFuture<'_> {
2870 pub fn poll_completion(&mut self) -> Poll<()> {
2871 let now = Instant::now();
2872
2873 match self.state {
2874 State::Idle => return Poll::Ready(()),
2875 _ if now < self.wait => {
2876 return Poll::Pending;
2878 }
2879 State::SendStop => {
2880 if let Some(sda) = self.sda.as_ref() {
2881 sda.set_output_high(true); }
2883 self.state = State::Idle;
2884 return Poll::Ready(());
2885 }
2886 State::SendClock(0, false) => {
2887 if let (Some(scl), Some(sda)) = (self.scl.as_ref(), self.sda.as_ref()) {
2888 sda.set_output_high(false);
2890 scl.set_output_high(true);
2891 }
2892 self.state = State::SendStop;
2893 }
2894 State::SendClock(n, false) => {
2895 if let Some(scl) = self.scl.as_ref() {
2896 scl.set_output_high(true);
2897 }
2898 self.state = State::SendClock(n - 1, true);
2899 }
2900 State::SendClock(n, true) => {
2901 if let Some(scl) = self.scl.as_ref() {
2902 scl.set_output_high(false);
2903 }
2904 self.state = State::SendClock(n, false);
2905 }
2906 }
2907 self.wait = Instant::now() + Self::SCL_DELAY;
2908
2909 Poll::Pending
2910 }
2911 }
2912
2913 impl Drop for ClearBusFuture<'_> {
2914 fn drop(&mut self) {
2915 if let (Some(sda), Some(scl)) = (self.sda.take(), self.scl.take()) {
2916 scl.set_output_high(true);
2918 sda.set_output_high(true);
2919
2920 self.driver.info.sda_output.connect_to(&sda);
2921 self.driver.info.scl_output.connect_to(&scl);
2922
2923 self.driver.clear_all_interrupts();
2926 }
2927 }
2928 }
2929}
2930
2931use bus_clear::ClearBusFuture;
2932
2933impl Future for ClearBusFuture<'_> {
2934 type Output = ();
2935
2936 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
2937 let pending = self.poll_completion();
2938 if pending.is_pending() {
2939 ctx.waker().wake_by_ref();
2940 }
2941 pending
2942 }
2943}
2944
2945#[doc(hidden)]
2947#[non_exhaustive]
2948pub struct State {
2949 pub waker: AtomicWaker,
2951}
2952
2953pub trait Instance: crate::private::Sealed + super::IntoAnyI2c {
2955 #[doc(hidden)]
2956 fn parts(&self) -> (&Info, &State);
2958
2959 #[doc(hidden)]
2961 #[inline(always)]
2962 fn info(&self) -> &Info {
2963 self.parts().0
2964 }
2965
2966 #[doc(hidden)]
2968 #[inline(always)]
2969 fn state(&self) -> &State {
2970 self.parts().1
2971 }
2972}
2973
2974fn add_cmd<'a, I>(cmd_iterator: &mut I, command: Command) -> Result<(), Error>
2979where
2980 I: Iterator<Item = &'a COMD>,
2981{
2982 let cmd = cmd_iterator.next().ok_or(Error::CommandNumberExceeded)?;
2983
2984 cmd.write(|w| match command {
2985 Command::Start => w.opcode().rstart(),
2986 Command::Stop => w.opcode().stop(),
2987 Command::End => w.opcode().end(),
2988 Command::Write {
2989 ack_exp,
2990 ack_check_en,
2991 length,
2992 } => unsafe {
2993 w.opcode().write();
2994 w.ack_exp().bit(ack_exp == Ack::Nack);
2995 w.ack_check_en().bit(ack_check_en);
2996 w.byte_num().bits(length);
2997 w
2998 },
2999 Command::Read { ack_value, length } => unsafe {
3000 w.opcode().read();
3001 w.ack_value().bit(ack_value == Ack::Nack);
3002 w.byte_num().bits(length);
3003 w
3004 },
3005 });
3006
3007 Ok(())
3008}
3009
3010#[cfg(not(esp32s2))]
3011fn read_fifo(register_block: &RegisterBlock) -> u8 {
3012 register_block.data().read().fifo_rdata().bits()
3013}
3014
3015#[cfg(not(esp32))]
3016fn write_fifo(register_block: &RegisterBlock, data: u8) {
3017 register_block
3018 .data()
3019 .write(|w| unsafe { w.fifo_rdata().bits(data) });
3020}
3021
3022#[cfg(esp32s2)]
3023fn read_fifo(register_block: &RegisterBlock) -> u8 {
3024 let base_addr = register_block.scl_low_period().as_ptr();
3025 let fifo_ptr = (if base_addr as u32 == 0x3f413000 {
3026 0x6001301c
3027 } else {
3028 0x6002701c
3029 }) as *mut u32;
3030 unsafe { (fifo_ptr.read_volatile() & 0xff) as u8 }
3031}
3032
3033#[cfg(esp32)]
3034fn write_fifo(register_block: &RegisterBlock, data: u8) {
3035 let base_addr = register_block.scl_low_period().as_ptr();
3036 let fifo_ptr = (if base_addr as u32 == 0x3FF53000 {
3037 0x6001301c
3038 } else {
3039 0x6002701c
3040 }) as *mut u32;
3041 unsafe {
3042 fifo_ptr.write_volatile(data as u32);
3043 }
3044}
3045
3046fn estimate_ack_failed_reason(_register_block: &RegisterBlock) -> AcknowledgeCheckFailedReason {
3049 cfg_if::cfg_if! {
3050 if #[cfg(any(esp32, esp32s2, esp32c2, esp32c3))] {
3051 AcknowledgeCheckFailedReason::Unknown
3052 } else {
3053 if _register_block.fifo_st().read().txfifo_raddr().bits() <= 1 {
3055 AcknowledgeCheckFailedReason::Address
3056 } else {
3057 AcknowledgeCheckFailedReason::Data
3058 }
3059 }
3060 }
3061}
3062
3063macro_rules! instance {
3064 ($inst:ident, $peri:ident, $scl:ident, $sda:ident, $interrupt:ident) => {
3065 impl Instance for crate::peripherals::$inst<'_> {
3066 fn parts(&self) -> (&Info, &State) {
3067 #[crate::handler]
3068 pub(super) fn irq_handler() {
3069 async_handler(&PERIPHERAL, &STATE);
3070 }
3071
3072 static STATE: State = State {
3073 waker: AtomicWaker::new(),
3074 };
3075
3076 static PERIPHERAL: Info = Info {
3077 register_block: crate::peripherals::$inst::ptr(),
3078 peripheral: crate::system::Peripheral::$peri,
3079 async_handler: irq_handler,
3080 interrupt: Interrupt::$interrupt,
3081 scl_output: OutputSignal::$scl,
3082 scl_input: InputSignal::$scl,
3083 sda_output: OutputSignal::$sda,
3084 sda_input: InputSignal::$sda,
3085 };
3086 (&PERIPHERAL, &STATE)
3087 }
3088 }
3089 };
3090}
3091
3092#[cfg(i2c0)]
3093instance!(I2C0, I2cExt0, I2CEXT0_SCL, I2CEXT0_SDA, I2C_EXT0);
3094#[cfg(i2c1)]
3095instance!(I2C1, I2cExt1, I2CEXT1_SCL, I2CEXT1_SDA, I2C_EXT1);
3096
3097impl Instance for AnyI2c<'_> {
3098 delegate::delegate! {
3099 to match &self.0 {
3100 AnyI2cInner::I2c0(i2c) => i2c,
3101 #[cfg(i2c1)]
3102 AnyI2cInner::I2c1(i2c) => i2c,
3103 } {
3104 fn parts(&self) -> (&Info, &State);
3105 }
3106 }
3107}