1use core::marker::PhantomData;
24#[cfg(not(esp32))]
25use core::{
26 pin::Pin,
27 task::{Context, Poll},
28};
29
30use embedded_hal::i2c::Operation as EhalOperation;
31use enumset::{EnumSet, EnumSetType};
32
33use crate::{
34 asynch::AtomicWaker,
35 clock::Clocks,
36 gpio::{
37 interconnect::{OutputConnection, PeripheralOutput},
38 InputSignal,
39 OutputSignal,
40 PinGuard,
41 Pull,
42 },
43 interrupt::InterruptHandler,
44 pac::i2c0::{RegisterBlock, COMD},
45 peripheral::{Peripheral, PeripheralRef},
46 peripherals::Interrupt,
47 private,
48 system::{PeripheralClockControl, PeripheralGuard},
49 time::Rate,
50 Async,
51 Blocking,
52 DriverMode,
53};
54
55cfg_if::cfg_if! {
56 if #[cfg(esp32s2)] {
57 const I2C_LL_INTR_MASK: u32 = 0x1ffff;
58 } else {
59 const I2C_LL_INTR_MASK: u32 = 0x3ffff;
60 }
61}
62
63#[cfg(any(esp32, esp32s2))]
65const I2C_CHUNK_SIZE: usize = 32;
66
67#[cfg(not(any(esp32, esp32s2)))]
68const I2C_CHUNK_SIZE: usize = 254;
69
70const MAX_ITERATIONS: u32 = 1_000_000;
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
75#[cfg_attr(feature = "defmt", derive(defmt::Format))]
76#[non_exhaustive]
77pub enum I2cAddress {
78 SevenBit(u8),
89}
90
91impl From<u8> for I2cAddress {
92 fn from(value: u8) -> Self {
93 I2cAddress::SevenBit(value)
94 }
95}
96
97#[doc = ""]
104#[cfg_attr(
105 not(esp32),
106 doc = "Note that the effective timeout may be longer than the value configured here."
107)]
108#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, strum::Display)]
109#[cfg_attr(feature = "defmt", derive(defmt::Format))]
110#[non_exhaustive]
111pub enum BusTimeout {
114 Maximum,
116
117 #[cfg(not(any(esp32, esp32s2)))]
119 Disabled,
120
121 BusCycles(u32),
123}
124
125impl BusTimeout {
126 fn cycles(&self) -> u32 {
127 match self {
128 #[cfg(esp32)]
129 BusTimeout::Maximum => 0xF_FFFF,
130
131 #[cfg(esp32s2)]
132 BusTimeout::Maximum => 0xFF_FFFF,
133
134 #[cfg(not(any(esp32, esp32s2)))]
135 BusTimeout::Maximum => 0x1F,
136
137 #[cfg(not(any(esp32, esp32s2)))]
138 BusTimeout::Disabled => 1,
139
140 BusTimeout::BusCycles(cycles) => *cycles,
141 }
142 }
143
144 #[cfg(not(esp32))]
145 fn is_set(&self) -> bool {
146 matches!(self, BusTimeout::BusCycles(_) | BusTimeout::Maximum)
147 }
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152#[cfg_attr(feature = "defmt", derive(defmt::Format))]
153#[non_exhaustive]
154pub enum Error {
155 FifoExceeded,
157 AcknowledgeCheckFailed(AcknowledgeCheckFailedReason),
159 Timeout,
161 ArbitrationLost,
163 ExecutionIncomplete,
165 CommandNumberExceeded,
167 ZeroLengthInvalid,
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
175#[cfg_attr(feature = "defmt", derive(defmt::Format))]
176#[non_exhaustive]
177pub enum AcknowledgeCheckFailedReason {
178 Address,
180
181 Data,
184
185 Unknown,
188}
189
190impl core::fmt::Display for AcknowledgeCheckFailedReason {
191 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
192 match self {
193 AcknowledgeCheckFailedReason::Address => write!(f, "Address"),
194 AcknowledgeCheckFailedReason::Data => write!(f, "Data"),
195 AcknowledgeCheckFailedReason::Unknown => write!(f, "Unknown"),
196 }
197 }
198}
199
200impl From<&AcknowledgeCheckFailedReason> for embedded_hal::i2c::NoAcknowledgeSource {
201 fn from(value: &AcknowledgeCheckFailedReason) -> Self {
202 match value {
203 AcknowledgeCheckFailedReason::Address => {
204 embedded_hal::i2c::NoAcknowledgeSource::Address
205 }
206 AcknowledgeCheckFailedReason::Data => embedded_hal::i2c::NoAcknowledgeSource::Data,
207 AcknowledgeCheckFailedReason::Unknown => {
208 embedded_hal::i2c::NoAcknowledgeSource::Unknown
209 }
210 }
211 }
212}
213
214impl core::error::Error for Error {}
215
216impl core::fmt::Display for Error {
217 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
218 match self {
219 Error::FifoExceeded => write!(f, "The transmission exceeded the FIFO size"),
220 Error::AcknowledgeCheckFailed(reason) => {
221 write!(f, "The acknowledgment check failed. Reason: {}", reason)
222 }
223 Error::Timeout => write!(f, "A timeout occurred during transmission"),
224 Error::ArbitrationLost => write!(f, "The arbitration for the bus was lost"),
225 Error::ExecutionIncomplete => {
226 write!(f, "The execution of the I2C command was incomplete")
227 }
228 Error::CommandNumberExceeded => {
229 write!(f, "The number of commands issued exceeded the limit")
230 }
231 Error::ZeroLengthInvalid => write!(f, "Zero length read or write operation"),
232 }
233 }
234}
235
236#[derive(Debug, Clone, Copy, PartialEq)]
238#[cfg_attr(feature = "defmt", derive(defmt::Format))]
239#[non_exhaustive]
240pub enum ConfigError {
241 FrequencyInvalid,
243 TimeoutInvalid,
245}
246
247impl core::error::Error for ConfigError {}
248
249impl core::fmt::Display for ConfigError {
250 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
251 match self {
252 ConfigError::FrequencyInvalid => write!(
253 f,
254 "Provided bus frequency is invalid for the current configuration"
255 ),
256 ConfigError::TimeoutInvalid => write!(
257 f,
258 "Provided timeout is invalid for the current configuration"
259 ),
260 }
261 }
262}
263
264#[derive(PartialEq)]
270enum OpKind {
271 Write,
272 Read,
273}
274
275#[derive(Debug, PartialEq, Eq, Hash, strum::Display)]
279pub enum Operation<'a> {
280 Write(&'a [u8]),
282
283 Read(&'a mut [u8]),
285}
286
287impl<'a, 'b> From<&'a mut embedded_hal::i2c::Operation<'b>> for Operation<'a> {
288 fn from(value: &'a mut embedded_hal::i2c::Operation<'b>) -> Self {
289 match value {
290 embedded_hal::i2c::Operation::Write(buffer) => Operation::Write(buffer),
291 embedded_hal::i2c::Operation::Read(buffer) => Operation::Read(buffer),
292 }
293 }
294}
295
296impl<'a, 'b> From<&'a mut Operation<'b>> for Operation<'a> {
297 fn from(value: &'a mut Operation<'b>) -> Self {
298 match value {
299 Operation::Write(buffer) => Operation::Write(buffer),
300 Operation::Read(buffer) => Operation::Read(buffer),
301 }
302 }
303}
304
305impl Operation<'_> {
306 fn is_write(&self) -> bool {
307 matches!(self, Operation::Write(_))
308 }
309
310 fn kind(&self) -> OpKind {
311 match self {
312 Operation::Write(_) => OpKind::Write,
313 Operation::Read(_) => OpKind::Read,
314 }
315 }
316
317 fn is_empty(&self) -> bool {
318 match self {
319 Operation::Write(buffer) => buffer.is_empty(),
320 Operation::Read(buffer) => buffer.is_empty(),
321 }
322 }
323}
324
325impl embedded_hal::i2c::Error for Error {
326 fn kind(&self) -> embedded_hal::i2c::ErrorKind {
327 use embedded_hal::i2c::ErrorKind;
328
329 match self {
330 Self::FifoExceeded => ErrorKind::Overrun,
331 Self::ArbitrationLost => ErrorKind::ArbitrationLoss,
332 Self::AcknowledgeCheckFailed(reason) => ErrorKind::NoAcknowledge(reason.into()),
333 _ => ErrorKind::Other,
334 }
335 }
336}
337
338#[cfg_attr(feature = "debug", derive(Debug))]
340enum Command {
341 Start,
342 Stop,
343 End,
344 Write {
345 ack_exp: Ack,
347 ack_check_en: bool,
349 length: u8,
352 },
353 Read {
354 ack_value: Ack,
357 length: u8,
360 },
361}
362
363enum OperationType {
364 Write = 0,
365 Read = 1,
366}
367
368#[derive(Eq, PartialEq, Copy, Clone)]
369#[cfg_attr(feature = "debug", derive(Debug))]
370enum Ack {
371 Ack = 0,
372 Nack = 1,
373}
374
375impl From<u32> for Ack {
376 fn from(ack: u32) -> Self {
377 match ack {
378 0 => Ack::Ack,
379 1 => Ack::Nack,
380 _ => unreachable!(),
381 }
382 }
383}
384
385impl From<Ack> for u32 {
386 fn from(ack: Ack) -> u32 {
387 ack as u32
388 }
389}
390
391#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, procmacros::BuilderLite)]
393#[cfg_attr(feature = "defmt", derive(defmt::Format))]
394#[non_exhaustive]
395pub struct Config {
396 frequency: Rate,
398
399 timeout: BusTimeout,
401}
402
403impl Default for Config {
404 fn default() -> Self {
405 Config {
406 frequency: Rate::from_khz(100),
407 timeout: BusTimeout::BusCycles(10),
408 }
409 }
410}
411
412#[doc = crate::before_snippet!()]
417#[derive(Debug)]
432#[cfg_attr(feature = "defmt", derive(defmt::Format))]
433pub struct I2c<'d, Dm: DriverMode> {
434 i2c: PeripheralRef<'d, AnyI2c>,
435 phantom: PhantomData<Dm>,
436 config: Config,
437 guard: PeripheralGuard,
438 sda_pin: PinGuard,
439 scl_pin: PinGuard,
440}
441
442#[instability::unstable]
443impl<Dm: DriverMode> embassy_embedded_hal::SetConfig for I2c<'_, Dm> {
444 type Config = Config;
445 type ConfigError = ConfigError;
446
447 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
448 self.apply_config(config)
449 }
450}
451
452impl<Dm: DriverMode> embedded_hal::i2c::ErrorType for I2c<'_, Dm> {
453 type Error = Error;
454}
455
456impl<Dm: DriverMode> embedded_hal::i2c::I2c for I2c<'_, Dm> {
457 fn transaction(
458 &mut self,
459 address: u8,
460 operations: &mut [embedded_hal::i2c::Operation<'_>],
461 ) -> Result<(), Self::Error> {
462 self.transaction_impl(
463 I2cAddress::SevenBit(address),
464 operations.iter_mut().map(Operation::from),
465 )
466 .inspect_err(|_| self.internal_recover())
467 }
468}
469
470impl<'d, Dm> I2c<'d, Dm>
471where
472 Dm: DriverMode,
473{
474 fn driver(&self) -> Driver<'_> {
475 Driver {
476 info: self.i2c.info(),
477 state: self.i2c.state(),
478 }
479 }
480
481 fn internal_recover(&self) {
482 PeripheralClockControl::disable(self.driver().info.peripheral);
483 PeripheralClockControl::enable(self.driver().info.peripheral);
484 PeripheralClockControl::reset(self.driver().info.peripheral);
485
486 _ = self.driver().setup(&self.config);
488 }
489
490 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
497 self.driver().setup(config)?;
498 self.config = *config;
499 Ok(())
500 }
501
502 fn transaction_impl<'a>(
503 &mut self,
504 address: I2cAddress,
505 operations: impl Iterator<Item = Operation<'a>>,
506 ) -> Result<(), Error> {
507 let mut last_op: Option<OpKind> = None;
508 let mut op_iter = operations
510 .filter(|op| op.is_write() || !op.is_empty())
511 .peekable();
512
513 while let Some(op) = op_iter.next() {
514 let next_op = op_iter.peek().map(|v| v.kind());
515 let kind = op.kind();
516 match op {
517 Operation::Write(buffer) => {
518 self.driver().write_blocking(
522 address,
523 buffer,
524 !matches!(last_op, Some(OpKind::Write)),
525 next_op.is_none(),
526 )?;
527 }
528 Operation::Read(buffer) => {
529 self.driver().read_blocking(
534 address,
535 buffer,
536 !matches!(last_op, Some(OpKind::Read)),
537 next_op.is_none(),
538 matches!(next_op, Some(OpKind::Read)),
539 )?;
540 }
541 }
542
543 last_op = Some(kind);
544 }
545
546 Ok(())
547 }
548
549 pub fn with_sda(mut self, sda: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
553 let info = self.driver().info;
554 let input = info.sda_input;
555 let output = info.sda_output;
556 Self::connect_pin(sda, input, output, &mut self.sda_pin);
557
558 self
559 }
560
561 pub fn with_scl(mut self, scl: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
565 let info = self.driver().info;
566 let input = info.scl_input;
567 let output = info.scl_output;
568 Self::connect_pin(scl, input, output, &mut self.scl_pin);
569
570 self
571 }
572
573 fn connect_pin(
574 pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
575 input: InputSignal,
576 output: OutputSignal,
577 guard: &mut PinGuard,
578 ) {
579 crate::into_mapped_ref!(pin);
580 pin.set_output_high(true);
582
583 pin.set_to_open_drain_output();
584 pin.enable_input(true);
585 pin.pull_direction(Pull::Up);
586
587 input.connect_to(pin.reborrow());
588
589 *guard = OutputConnection::connect_with_guard(pin, output);
590 }
591
592 #[doc = crate::before_snippet!()]
595 pub fn write<A: Into<I2cAddress>>(&mut self, address: A, buffer: &[u8]) -> Result<(), Error> {
606 self.driver()
607 .write_blocking(address.into(), buffer, true, true)
608 .inspect_err(|_| self.internal_recover())
609 }
610
611 #[doc = crate::before_snippet!()]
614 pub fn read<A: Into<I2cAddress>>(
630 &mut self,
631 address: A,
632 buffer: &mut [u8],
633 ) -> Result<(), Error> {
634 self.driver()
635 .read_blocking(address.into(), buffer, true, true, false)
636 .inspect_err(|_| self.internal_recover())
637 }
638
639 #[doc = crate::before_snippet!()]
643 pub fn write_read<A: Into<I2cAddress>>(
659 &mut self,
660 address: A,
661 write_buffer: &[u8],
662 read_buffer: &mut [u8],
663 ) -> Result<(), Error> {
664 let address = address.into();
665
666 self.driver()
667 .write_blocking(address, write_buffer, true, read_buffer.is_empty())
668 .inspect_err(|_| self.internal_recover())?;
669
670 self.driver()
671 .read_blocking(address, read_buffer, true, true, false)
672 .inspect_err(|_| self.internal_recover())?;
673
674 Ok(())
675 }
676
677 #[doc = crate::before_snippet!()]
698 pub fn transaction<'a, A: Into<I2cAddress>>(
717 &mut self,
718 address: A,
719 operations: impl IntoIterator<Item = &'a mut Operation<'a>>,
720 ) -> Result<(), Error> {
721 self.transaction_impl(address.into(), operations.into_iter().map(Operation::from))
722 .inspect_err(|_| self.internal_recover())
723 }
724}
725
726impl<'d> I2c<'d, Blocking> {
727 pub fn new(
734 i2c: impl Peripheral<P = impl Instance> + 'd,
735 config: Config,
736 ) -> Result<Self, ConfigError> {
737 crate::into_mapped_ref!(i2c);
738
739 let guard = PeripheralGuard::new(i2c.info().peripheral);
740
741 let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output);
742 let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output);
743
744 let i2c = I2c {
745 i2c,
746 phantom: PhantomData,
747 config,
748 guard,
749 sda_pin,
750 scl_pin,
751 };
752
753 i2c.driver().setup(&i2c.config)?;
754
755 Ok(i2c)
756 }
757
758 #[cfg_attr(
759 not(multi_core),
760 doc = "Registers an interrupt handler for the peripheral."
761 )]
762 #[cfg_attr(
763 multi_core,
764 doc = "Registers an interrupt handler for the peripheral on the current core."
765 )]
766 #[doc = ""]
767 #[instability::unstable]
778 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
779 self.i2c.info().set_interrupt_handler(handler);
780 }
781
782 #[instability::unstable]
784 pub fn listen(&mut self, interrupts: impl Into<EnumSet<Event>>) {
785 self.i2c.info().enable_listen(interrupts.into(), true)
786 }
787
788 #[instability::unstable]
790 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<Event>>) {
791 self.i2c.info().enable_listen(interrupts.into(), false)
792 }
793
794 #[instability::unstable]
796 pub fn interrupts(&mut self) -> EnumSet<Event> {
797 self.i2c.info().interrupts()
798 }
799
800 #[instability::unstable]
802 pub fn clear_interrupts(&mut self, interrupts: EnumSet<Event>) {
803 self.i2c.info().clear_interrupts(interrupts)
804 }
805
806 pub fn into_async(mut self) -> I2c<'d, Async> {
808 self.set_interrupt_handler(self.driver().info.async_handler);
809
810 I2c {
811 i2c: self.i2c,
812 phantom: PhantomData,
813 config: self.config,
814 guard: self.guard,
815 sda_pin: self.sda_pin,
816 scl_pin: self.scl_pin,
817 }
818 }
819}
820
821impl private::Sealed for I2c<'_, Blocking> {}
822
823#[instability::unstable]
824impl crate::interrupt::InterruptConfigurable for I2c<'_, Blocking> {
825 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
826 self.i2c.info().set_interrupt_handler(handler);
827 }
828}
829
830#[cfg_attr(esp32, allow(dead_code))]
831#[derive(Debug, EnumSetType)]
832#[cfg_attr(feature = "defmt", derive(defmt::Format))]
833#[non_exhaustive]
834#[instability::unstable]
835pub enum Event {
836 EndDetect,
839
840 TxComplete,
842
843 #[cfg(not(any(esp32, esp32s2)))]
846 TxFifoWatermark,
847}
848
849#[cfg(not(esp32))]
850#[must_use = "futures do nothing unless you `.await` or poll them"]
851struct I2cFuture<'a> {
852 event: Event,
853 info: &'a Info,
854 state: &'a State,
855}
856
857#[cfg(not(esp32))]
858impl<'a> I2cFuture<'a> {
859 pub fn new(event: Event, info: &'a Info, state: &'a State) -> Self {
860 info.regs().int_ena().modify(|_, w| {
861 let w = match event {
862 Event::EndDetect => w.end_detect().set_bit(),
863 Event::TxComplete => w.trans_complete().set_bit(),
864 #[cfg(not(any(esp32, esp32s2)))]
865 Event::TxFifoWatermark => w.txfifo_wm().set_bit(),
866 };
867
868 w.arbitration_lost().set_bit();
869 w.time_out().set_bit();
870 w.nack().set_bit();
871
872 w
873 });
874
875 Self { event, state, info }
876 }
877
878 fn event_bit_is_clear(&self) -> bool {
879 let r = self.info.regs().int_ena().read();
880
881 match self.event {
882 Event::EndDetect => r.end_detect().bit_is_clear(),
883 Event::TxComplete => r.trans_complete().bit_is_clear(),
884 #[cfg(not(any(esp32, esp32s2)))]
885 Event::TxFifoWatermark => r.txfifo_wm().bit_is_clear(),
886 }
887 }
888
889 fn check_error(&self) -> Result<(), Error> {
890 let r = self.info.regs().int_raw().read();
891
892 if r.arbitration_lost().bit_is_set() {
893 return Err(Error::ArbitrationLost);
894 }
895
896 if r.time_out().bit_is_set() {
897 return Err(Error::Timeout);
898 }
899
900 if r.nack().bit_is_set() {
901 return Err(Error::AcknowledgeCheckFailed(estimate_ack_failed_reason(
902 self.info.regs(),
903 )));
904 }
905
906 #[cfg(not(esp32))]
907 if r.trans_complete().bit_is_set() && self.info.regs().sr().read().resp_rec().bit_is_clear()
908 {
909 return Err(Error::AcknowledgeCheckFailed(
910 AcknowledgeCheckFailedReason::Data,
911 ));
912 }
913
914 Ok(())
915 }
916}
917
918#[cfg(not(esp32))]
919impl core::future::Future for I2cFuture<'_> {
920 type Output = Result<(), Error>;
921
922 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
923 self.state.waker.register(ctx.waker());
924
925 let error = self.check_error();
926
927 if error.is_err() {
928 return Poll::Ready(error);
929 }
930
931 if self.event_bit_is_clear() {
932 Poll::Ready(Ok(()))
933 } else {
934 Poll::Pending
935 }
936 }
937}
938
939impl<'d> I2c<'d, Async> {
940 pub fn into_blocking(self) -> I2c<'d, Blocking> {
942 self.i2c.info().disable_interrupts();
943
944 I2c {
945 i2c: self.i2c,
946 phantom: PhantomData,
947 config: self.config,
948 guard: self.guard,
949 sda_pin: self.sda_pin,
950 scl_pin: self.scl_pin,
951 }
952 }
953
954 pub async fn write_async<A: Into<I2cAddress>>(
956 &mut self,
957 address: A,
958 buffer: &[u8],
959 ) -> Result<(), Error> {
960 self.driver()
961 .write(address.into(), buffer, true, true)
962 .await
963 .inspect_err(|_| self.internal_recover())
964 }
965
966 pub async fn read_async<A: Into<I2cAddress>>(
973 &mut self,
974 address: A,
975 buffer: &mut [u8],
976 ) -> Result<(), Error> {
977 self.driver()
978 .read(address.into(), buffer, true, true, false)
979 .await
980 .inspect_err(|_| self.internal_recover())
981 }
982
983 pub async fn write_read_async<A: Into<I2cAddress>>(
991 &mut self,
992 address: A,
993 write_buffer: &[u8],
994 read_buffer: &mut [u8],
995 ) -> Result<(), Error> {
996 let address = address.into();
997
998 self.driver()
999 .write(address, write_buffer, true, read_buffer.is_empty())
1000 .await
1001 .inspect_err(|_| self.internal_recover())?;
1002
1003 self.driver()
1004 .read(address, read_buffer, true, true, false)
1005 .await
1006 .inspect_err(|_| self.internal_recover())?;
1007
1008 Ok(())
1009 }
1010
1011 pub async fn transaction_async<'a, A: Into<I2cAddress>>(
1036 &mut self,
1037 address: A,
1038 operations: impl IntoIterator<Item = &'a mut Operation<'a>>,
1039 ) -> Result<(), Error> {
1040 self.transaction_impl_async(address.into(), operations.into_iter().map(Operation::from))
1041 .await
1042 .inspect_err(|_| self.internal_recover())
1043 }
1044
1045 async fn transaction_impl_async<'a>(
1046 &mut self,
1047 address: I2cAddress,
1048 operations: impl Iterator<Item = Operation<'a>>,
1049 ) -> Result<(), Error> {
1050 let mut last_op: Option<OpKind> = None;
1051 let mut op_iter = operations
1053 .filter(|op| op.is_write() || !op.is_empty())
1054 .peekable();
1055
1056 while let Some(op) = op_iter.next() {
1057 let next_op = op_iter.peek().map(|v| v.kind());
1058 let kind = op.kind();
1059 match op {
1060 Operation::Write(buffer) => {
1061 self.driver()
1065 .write(
1066 address,
1067 buffer,
1068 !matches!(last_op, Some(OpKind::Write)),
1069 next_op.is_none(),
1070 )
1071 .await?;
1072 }
1073 Operation::Read(buffer) => {
1074 self.driver()
1079 .read(
1080 address,
1081 buffer,
1082 !matches!(last_op, Some(OpKind::Read)),
1083 next_op.is_none(),
1084 matches!(next_op, Some(OpKind::Read)),
1085 )
1086 .await?;
1087 }
1088 }
1089
1090 last_op = Some(kind);
1091 }
1092
1093 Ok(())
1094 }
1095}
1096
1097impl embedded_hal_async::i2c::I2c for I2c<'_, Async> {
1098 async fn transaction(
1099 &mut self,
1100 address: u8,
1101 operations: &mut [EhalOperation<'_>],
1102 ) -> Result<(), Self::Error> {
1103 self.transaction_impl_async(address.into(), operations.iter_mut().map(Operation::from))
1104 .await
1105 .inspect_err(|_| self.internal_recover())
1106 }
1107}
1108
1109fn async_handler(info: &Info, state: &State) {
1110 let regs = info.regs();
1111 regs.int_ena().modify(|_, w| {
1112 w.end_detect().clear_bit();
1113 w.trans_complete().clear_bit();
1114 w.arbitration_lost().clear_bit();
1115 w.time_out().clear_bit();
1116
1117 #[cfg(not(any(esp32, esp32s2)))]
1118 w.txfifo_wm().clear_bit();
1119
1120 w.nack().clear_bit()
1121 });
1122
1123 state.waker.wake();
1124}
1125
1126fn set_filter(
1129 register_block: &RegisterBlock,
1130 sda_threshold: Option<u8>,
1131 scl_threshold: Option<u8>,
1132) {
1133 cfg_if::cfg_if! {
1134 if #[cfg(any(esp32, esp32s2))] {
1135 register_block.sda_filter_cfg().modify(|_, w| {
1136 if let Some(threshold) = sda_threshold {
1137 unsafe { w.sda_filter_thres().bits(threshold) };
1138 }
1139 w.sda_filter_en().bit(sda_threshold.is_some())
1140 });
1141 register_block.scl_filter_cfg().modify(|_, w| {
1142 if let Some(threshold) = scl_threshold {
1143 unsafe { w.scl_filter_thres().bits(threshold) };
1144 }
1145 w.scl_filter_en().bit(scl_threshold.is_some())
1146 });
1147 } else {
1148 register_block.filter_cfg().modify(|_, w| {
1149 if let Some(threshold) = sda_threshold {
1150 unsafe { w.sda_filter_thres().bits(threshold) };
1151 }
1152 if let Some(threshold) = scl_threshold {
1153 unsafe { w.scl_filter_thres().bits(threshold) };
1154 }
1155 w.sda_filter_en().bit(sda_threshold.is_some());
1156 w.scl_filter_en().bit(scl_threshold.is_some())
1157 });
1158 }
1159 }
1160}
1161
1162#[allow(clippy::too_many_arguments, unused)]
1163fn configure_clock(
1165 register_block: &RegisterBlock,
1166 sclk_div: u32,
1167 scl_low_period: u32,
1168 scl_high_period: u32,
1169 scl_wait_high_period: u32,
1170 sda_hold_time: u32,
1171 sda_sample_time: u32,
1172 scl_rstart_setup_time: u32,
1173 scl_stop_setup_time: u32,
1174 scl_start_hold_time: u32,
1175 scl_stop_hold_time: u32,
1176 timeout: BusTimeout,
1177) -> Result<(), ConfigError> {
1178 unsafe {
1179 #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
1181 register_block.clk_conf().modify(|_, w| {
1182 w.sclk_sel().clear_bit();
1183 w.sclk_div_num().bits((sclk_div - 1) as u8)
1184 });
1185
1186 register_block
1188 .scl_low_period()
1189 .write(|w| w.scl_low_period().bits(scl_low_period as u16));
1190
1191 #[cfg(not(esp32))]
1192 let scl_wait_high_period = scl_wait_high_period
1193 .try_into()
1194 .map_err(|_| ConfigError::FrequencyInvalid)?;
1195
1196 register_block.scl_high_period().write(|w| {
1197 #[cfg(not(esp32))] w.scl_wait_high_period().bits(scl_wait_high_period);
1199 w.scl_high_period().bits(scl_high_period as u16)
1200 });
1201
1202 register_block
1204 .sda_hold()
1205 .write(|w| w.time().bits(sda_hold_time as u16));
1206 register_block
1207 .sda_sample()
1208 .write(|w| w.time().bits(sda_sample_time as u16));
1209
1210 register_block
1212 .scl_rstart_setup()
1213 .write(|w| w.time().bits(scl_rstart_setup_time as u16));
1214 register_block
1215 .scl_stop_setup()
1216 .write(|w| w.time().bits(scl_stop_setup_time as u16));
1217
1218 register_block
1220 .scl_start_hold()
1221 .write(|w| w.time().bits(scl_start_hold_time as u16));
1222 register_block
1223 .scl_stop_hold()
1224 .write(|w| w.time().bits(scl_stop_hold_time as u16));
1225
1226 cfg_if::cfg_if! {
1229 if #[cfg(esp32)] {
1230 register_block
1231 .to()
1232 .write(|w| w.time_out().bits(timeout.cycles()));
1233 } else {
1234 register_block
1235 .to()
1236 .write(|w| w.time_out_en().bit(timeout.is_set())
1237 .time_out_value()
1238 .bits(timeout.cycles() as _)
1239 );
1240 }
1241 }
1242 }
1243 Ok(())
1244}
1245
1246#[doc(hidden)]
1248#[derive(Debug)]
1249#[non_exhaustive]
1250pub struct Info {
1251 pub register_block: *const RegisterBlock,
1255
1256 pub peripheral: crate::system::Peripheral,
1258
1259 pub async_handler: InterruptHandler,
1261
1262 pub interrupt: Interrupt,
1264
1265 pub scl_output: OutputSignal,
1267
1268 pub scl_input: InputSignal,
1270
1271 pub sda_output: OutputSignal,
1273
1274 pub sda_input: InputSignal,
1276}
1277
1278impl Info {
1279 pub fn regs(&self) -> &RegisterBlock {
1281 unsafe { &*self.register_block }
1282 }
1283
1284 fn enable_listen(&self, interrupts: EnumSet<Event>, enable: bool) {
1286 let reg_block = self.regs();
1287
1288 reg_block.int_ena().modify(|_, w| {
1289 for interrupt in interrupts {
1290 match interrupt {
1291 Event::EndDetect => w.end_detect().bit(enable),
1292 Event::TxComplete => w.trans_complete().bit(enable),
1293 #[cfg(not(any(esp32, esp32s2)))]
1294 Event::TxFifoWatermark => w.txfifo_wm().bit(enable),
1295 };
1296 }
1297 w
1298 });
1299 }
1300
1301 fn interrupts(&self) -> EnumSet<Event> {
1302 let mut res = EnumSet::new();
1303 let reg_block = self.regs();
1304
1305 let ints = reg_block.int_raw().read();
1306
1307 if ints.end_detect().bit_is_set() {
1308 res.insert(Event::EndDetect);
1309 }
1310 if ints.trans_complete().bit_is_set() {
1311 res.insert(Event::TxComplete);
1312 }
1313 #[cfg(not(any(esp32, esp32s2)))]
1314 if ints.txfifo_wm().bit_is_set() {
1315 res.insert(Event::TxFifoWatermark);
1316 }
1317
1318 res
1319 }
1320
1321 fn clear_interrupts(&self, interrupts: EnumSet<Event>) {
1322 let reg_block = self.regs();
1323
1324 reg_block.int_clr().write(|w| {
1325 for interrupt in interrupts {
1326 match interrupt {
1327 Event::EndDetect => w.end_detect().clear_bit_by_one(),
1328 Event::TxComplete => w.trans_complete().clear_bit_by_one(),
1329 #[cfg(not(any(esp32, esp32s2)))]
1330 Event::TxFifoWatermark => w.txfifo_wm().clear_bit_by_one(),
1331 };
1332 }
1333 w
1334 });
1335 }
1336
1337 fn set_interrupt_handler(&self, handler: InterruptHandler) {
1338 for core in crate::system::Cpu::other() {
1339 crate::interrupt::disable(core, self.interrupt);
1340 }
1341 self.enable_listen(EnumSet::all(), false);
1342 self.clear_interrupts(EnumSet::all());
1343 unsafe { crate::interrupt::bind_interrupt(self.interrupt, handler.handler()) };
1344 unwrap!(crate::interrupt::enable(self.interrupt, handler.priority()));
1345 }
1346
1347 fn disable_interrupts(&self) {
1348 crate::interrupt::disable(crate::system::Cpu::current(), self.interrupt);
1349 }
1350}
1351
1352impl PartialEq for Info {
1353 fn eq(&self, other: &Self) -> bool {
1354 self.register_block == other.register_block
1355 }
1356}
1357
1358unsafe impl Sync for Info {}
1359
1360#[allow(dead_code)] struct Driver<'a> {
1362 info: &'a Info,
1363 state: &'a State,
1364}
1365
1366impl Driver<'_> {
1367 fn regs(&self) -> &RegisterBlock {
1368 self.info.regs()
1369 }
1370
1371 fn setup(&self, config: &Config) -> Result<(), ConfigError> {
1374 self.regs().ctr().write(|w| {
1375 w.ms_mode().set_bit();
1377 w.sda_force_out().set_bit();
1379 w.scl_force_out().set_bit();
1380 w.tx_lsb_first().clear_bit();
1382 w.rx_lsb_first().clear_bit();
1383 w.clk_en().set_bit()
1385 });
1386
1387 #[cfg(esp32s2)]
1388 self.regs().ctr().modify(|_, w| w.ref_always_on().set_bit());
1389
1390 set_filter(self.regs(), Some(7), Some(7));
1393
1394 self.set_frequency(config, config.timeout)?;
1396
1397 self.update_config();
1398
1399 self.reset();
1401
1402 Ok(())
1403 }
1404
1405 fn reset(&self) {
1407 #[cfg(not(esp32))]
1411 self.regs().ctr().modify(|_, w| w.fsm_rst().set_bit());
1412
1413 self.regs()
1415 .int_clr()
1416 .write(|w| unsafe { w.bits(I2C_LL_INTR_MASK) });
1417
1418 self.reset_fifo();
1420
1421 self.reset_command_list();
1423 }
1424
1425 fn reset_command_list(&self) {
1427 for cmd in self.regs().comd_iter() {
1429 cmd.reset();
1430 }
1431 }
1432
1433 #[cfg(esp32)]
1434 fn set_frequency(&self, clock_config: &Config, timeout: BusTimeout) -> Result<(), ConfigError> {
1438 let clocks = Clocks::get();
1439 let source_clk = clocks.i2c_clock.as_hz();
1440 let bus_freq = clock_config.frequency.as_hz();
1441
1442 let half_cycle: u32 = source_clk / bus_freq / 2;
1443 let scl_low = half_cycle;
1444 let scl_high = half_cycle;
1445 let sda_hold = half_cycle / 2;
1446 let sda_sample = scl_high / 2;
1447 let setup = half_cycle;
1448 let hold = half_cycle;
1449 let timeout = BusTimeout::BusCycles(match timeout {
1450 BusTimeout::Maximum => 0xF_FFFF,
1451 BusTimeout::BusCycles(cycles) => check_timeout(cycles * 2 * half_cycle, 0xF_FFFF)?,
1452 });
1453
1454 let scl_low = scl_low - 1;
1457 let mut scl_high = scl_high;
1463 scl_high -= 7 + 6;
1469
1470 let scl_high_period = scl_high;
1482 let scl_low_period = scl_low;
1483 let sda_hold_time = sda_hold;
1485 let sda_sample_time = sda_sample;
1486 let scl_rstart_setup_time = setup;
1488 let scl_stop_setup_time = setup;
1489 let scl_start_hold_time = hold;
1491 let scl_stop_hold_time = hold;
1492
1493 configure_clock(
1494 self.regs(),
1495 0,
1496 scl_low_period,
1497 scl_high_period,
1498 0,
1499 sda_hold_time,
1500 sda_sample_time,
1501 scl_rstart_setup_time,
1502 scl_stop_setup_time,
1503 scl_start_hold_time,
1504 scl_stop_hold_time,
1505 timeout,
1506 )?;
1507
1508 Ok(())
1509 }
1510
1511 #[cfg(esp32s2)]
1512 fn set_frequency(&self, clock_config: &Config, timeout: BusTimeout) -> Result<(), ConfigError> {
1516 let clocks = Clocks::get();
1517 let source_clk = clocks.apb_clock.as_hz();
1518 let bus_freq = clock_config.frequency.as_hz();
1519
1520 let half_cycle: u32 = source_clk / bus_freq / 2;
1521 let scl_low = half_cycle;
1523 let scl_high = half_cycle / 2 + 2;
1525 let scl_wait_high = half_cycle - scl_high;
1526 let sda_hold = half_cycle / 2;
1527 let sda_sample = half_cycle / 2 - 1;
1529 let setup = half_cycle;
1530 let hold = half_cycle;
1531
1532 let scl_low_period = scl_low - 1;
1534 let scl_high_period = scl_high;
1535 let scl_wait_high_period = scl_wait_high;
1536 let sda_hold_time = sda_hold;
1538 let sda_sample_time = sda_sample;
1539 let scl_rstart_setup_time = setup;
1541 let scl_stop_setup_time = setup;
1542 let scl_start_hold_time = hold - 1;
1544 let scl_stop_hold_time = hold;
1545
1546 let timeout = BusTimeout::BusCycles(match timeout {
1547 BusTimeout::Maximum => 0xFF_FFFF,
1548 BusTimeout::BusCycles(cycles) => check_timeout(cycles * 2 * half_cycle, 0xFF_FFFF)?,
1549 });
1550
1551 configure_clock(
1552 self.regs(),
1553 0,
1554 scl_low_period,
1555 scl_high_period,
1556 scl_wait_high_period,
1557 sda_hold_time,
1558 sda_sample_time,
1559 scl_rstart_setup_time,
1560 scl_stop_setup_time,
1561 scl_start_hold_time,
1562 scl_stop_hold_time,
1563 timeout,
1564 )?;
1565
1566 Ok(())
1567 }
1568
1569 #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
1570 fn set_frequency(&self, clock_config: &Config, timeout: BusTimeout) -> Result<(), ConfigError> {
1574 let clocks = Clocks::get();
1575 let source_clk = clocks.xtal_clock.as_hz();
1576 let bus_freq = clock_config.frequency.as_hz();
1577
1578 let clkm_div: u32 = source_clk / (bus_freq * 1024) + 1;
1579 let sclk_freq: u32 = source_clk / clkm_div;
1580 let half_cycle: u32 = sclk_freq / bus_freq / 2;
1581 let scl_low = half_cycle;
1583 let scl_wait_high = if bus_freq >= 80 * 1000 {
1588 half_cycle / 2 - 2
1589 } else {
1590 half_cycle / 4
1591 };
1592 let scl_high = half_cycle - scl_wait_high;
1593 let sda_hold = half_cycle / 4;
1594 let sda_sample = half_cycle / 2 + scl_wait_high;
1595 let setup = half_cycle;
1596 let hold = half_cycle;
1597
1598 let scl_low_period = scl_low - 1;
1606 let scl_high_period = scl_high;
1607 let scl_wait_high_period = scl_wait_high;
1608 let sda_hold_time = sda_hold - 1;
1610 let sda_sample_time = sda_sample - 1;
1611 let scl_rstart_setup_time = setup - 1;
1613 let scl_stop_setup_time = setup - 1;
1614 let scl_start_hold_time = hold - 1;
1616 let scl_stop_hold_time = hold - 1;
1617
1618 let timeout = match timeout {
1619 BusTimeout::Maximum => BusTimeout::BusCycles(0x1F),
1620 BusTimeout::Disabled => BusTimeout::Disabled,
1621 BusTimeout::BusCycles(cycles) => {
1622 let to_peri = (cycles * 2 * half_cycle).max(1);
1623 let log2 = to_peri.ilog2();
1624 let raw = if to_peri != 1 << log2 { log2 + 1 } else { log2 };
1626 BusTimeout::BusCycles(check_timeout(raw, 0x1F)?)
1627 }
1628 };
1629
1630 configure_clock(
1631 self.regs(),
1632 clkm_div,
1633 scl_low_period,
1634 scl_high_period,
1635 scl_wait_high_period,
1636 sda_hold_time,
1637 sda_sample_time,
1638 scl_rstart_setup_time,
1639 scl_stop_setup_time,
1640 scl_start_hold_time,
1641 scl_stop_hold_time,
1642 timeout,
1643 )?;
1644
1645 Ok(())
1646 }
1647
1648 #[cfg(any(esp32, esp32s2))]
1649 async fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> {
1650 if buffer.len() > 32 {
1651 return Err(Error::FifoExceeded);
1652 }
1653
1654 self.wait_for_completion(false).await?;
1655
1656 for byte in buffer.iter_mut() {
1657 *byte = read_fifo(self.regs());
1658 }
1659
1660 Ok(())
1661 }
1662
1663 #[cfg(not(any(esp32, esp32s2)))]
1664 async fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> {
1665 self.read_all_from_fifo_blocking(buffer)
1666 }
1667
1668 fn setup_write<'a, I>(
1675 &self,
1676 addr: I2cAddress,
1677 bytes: &[u8],
1678 start: bool,
1679 cmd_iterator: &mut I,
1680 ) -> Result<(), Error>
1681 where
1682 I: Iterator<Item = &'a COMD>,
1683 {
1684 let max_len = if start { 254usize } else { 255usize };
1687 if bytes.len() > max_len {
1688 return Err(Error::FifoExceeded);
1690 }
1691
1692 let write_len = if start { bytes.len() + 1 } else { bytes.len() };
1693 if write_len > 0 {
1695 add_cmd(
1697 cmd_iterator,
1698 Command::Write {
1699 ack_exp: Ack::Ack,
1700 ack_check_en: true,
1701 length: write_len as u8,
1702 },
1703 )?;
1704 }
1705
1706 self.update_config();
1707
1708 if start {
1709 match addr {
1711 I2cAddress::SevenBit(addr) => {
1712 write_fifo(self.regs(), (addr << 1) | OperationType::Write as u8);
1713 }
1714 }
1715 }
1716 Ok(())
1717 }
1718
1719 fn setup_read<'a, I>(
1728 &self,
1729 addr: I2cAddress,
1730 buffer: &mut [u8],
1731 start: bool,
1732 will_continue: bool,
1733 cmd_iterator: &mut I,
1734 ) -> Result<(), Error>
1735 where
1736 I: Iterator<Item = &'a COMD>,
1737 {
1738 if buffer.is_empty() {
1739 return Err(Error::ZeroLengthInvalid);
1740 }
1741 let (max_len, initial_len) = if will_continue {
1742 (255usize, buffer.len())
1743 } else {
1744 (254usize, buffer.len() - 1)
1745 };
1746 if buffer.len() > max_len {
1747 return Err(Error::FifoExceeded);
1749 }
1750
1751 if start {
1752 add_cmd(
1754 cmd_iterator,
1755 Command::Write {
1756 ack_exp: Ack::Ack,
1757 ack_check_en: true,
1758 length: 1,
1759 },
1760 )?;
1761 }
1762
1763 if initial_len > 0 {
1764 add_cmd(
1766 cmd_iterator,
1767 Command::Read {
1768 ack_value: Ack::Ack,
1769 length: initial_len as u8,
1770 },
1771 )?;
1772 }
1773
1774 if !will_continue {
1775 add_cmd(
1778 cmd_iterator,
1779 Command::Read {
1780 ack_value: Ack::Nack,
1781 length: 1,
1782 },
1783 )?;
1784 }
1785
1786 self.update_config();
1787
1788 if start {
1789 match addr {
1791 I2cAddress::SevenBit(addr) => {
1792 write_fifo(self.regs(), (addr << 1) | OperationType::Read as u8);
1793 }
1794 }
1795 }
1796 Ok(())
1797 }
1798
1799 #[cfg(not(any(esp32, esp32s2)))]
1800 fn read_all_from_fifo_blocking(&self, buffer: &mut [u8]) -> Result<(), Error> {
1802 for byte in buffer.iter_mut() {
1806 loop {
1807 self.check_errors()?;
1808
1809 let reg = self.regs().fifo_st().read();
1810 if reg.rxfifo_raddr().bits() != reg.rxfifo_waddr().bits() {
1811 break;
1812 }
1813 }
1814
1815 *byte = read_fifo(self.regs());
1816 }
1817
1818 Ok(())
1819 }
1820
1821 #[cfg(any(esp32, esp32s2))]
1822 fn read_all_from_fifo_blocking(&self, buffer: &mut [u8]) -> Result<(), Error> {
1824 if buffer.len() > 32 {
1829 return Err(Error::FifoExceeded);
1830 }
1831
1832 self.wait_for_completion_blocking(false)?;
1836
1837 for byte in buffer.iter_mut() {
1841 *byte = read_fifo(self.regs());
1842 }
1843
1844 Ok(())
1845 }
1846
1847 fn clear_all_interrupts(&self) {
1849 self.regs()
1850 .int_clr()
1851 .write(|w| unsafe { w.bits(I2C_LL_INTR_MASK) });
1852 }
1853
1854 #[cfg(any(esp32, esp32s2))]
1855 async fn write_remaining_tx_fifo(&self, start_index: usize, bytes: &[u8]) -> Result<(), Error> {
1856 if start_index >= bytes.len() {
1857 return Ok(());
1858 }
1859
1860 for b in bytes {
1861 write_fifo(self.regs(), *b);
1862 self.check_errors()?;
1863 }
1864
1865 Ok(())
1866 }
1867
1868 #[cfg(not(any(esp32, esp32s2)))]
1869 async fn write_remaining_tx_fifo(&self, start_index: usize, bytes: &[u8]) -> Result<(), Error> {
1870 let mut index = start_index;
1871 loop {
1872 self.check_errors()?;
1873
1874 I2cFuture::new(Event::TxFifoWatermark, self.info, self.state).await?;
1875
1876 self.regs()
1877 .int_clr()
1878 .write(|w| w.txfifo_wm().clear_bit_by_one());
1879
1880 I2cFuture::new(Event::TxFifoWatermark, self.info, self.state).await?;
1881
1882 if index >= bytes.len() {
1883 break Ok(());
1884 }
1885
1886 write_fifo(self.regs(), bytes[index]);
1887 index += 1;
1888 }
1889 }
1890
1891 #[cfg(not(esp32))]
1892 async fn wait_for_completion(&self, end_only: bool) -> Result<(), Error> {
1893 self.check_errors()?;
1894
1895 if end_only {
1896 I2cFuture::new(Event::EndDetect, self.info, self.state).await?;
1897 } else {
1898 let res = embassy_futures::select::select(
1899 I2cFuture::new(Event::TxComplete, self.info, self.state),
1900 I2cFuture::new(Event::EndDetect, self.info, self.state),
1901 )
1902 .await;
1903
1904 match res {
1905 embassy_futures::select::Either::First(res) => res?,
1906 embassy_futures::select::Either::Second(res) => res?,
1907 }
1908 }
1909 self.check_all_commands_done()?;
1910
1911 Ok(())
1912 }
1913
1914 #[cfg(esp32)]
1915 async fn wait_for_completion(&self, end_only: bool) -> Result<(), Error> {
1916 let mut tout = MAX_ITERATIONS / 10; loop {
1921 let interrupts = self.regs().int_raw().read();
1922
1923 self.check_errors()?;
1924
1925 if (!end_only && interrupts.trans_complete().bit_is_set())
1929 || interrupts.end_detect().bit_is_set()
1930 {
1931 break;
1932 }
1933
1934 tout -= 1;
1935 if tout == 0 {
1936 return Err(Error::Timeout);
1937 }
1938
1939 embassy_futures::yield_now().await;
1940 }
1941 self.check_all_commands_done()?;
1942 Ok(())
1943 }
1944
1945 fn wait_for_completion_blocking(&self, end_only: bool) -> Result<(), Error> {
1947 let mut tout = MAX_ITERATIONS;
1948 loop {
1949 let interrupts = self.regs().int_raw().read();
1950
1951 self.check_errors()?;
1952
1953 if (!end_only && interrupts.trans_complete().bit_is_set())
1957 || interrupts.end_detect().bit_is_set()
1958 {
1959 break;
1960 }
1961
1962 tout -= 1;
1963 if tout == 0 {
1964 return Err(Error::Timeout);
1965 }
1966 }
1967 self.check_all_commands_done()?;
1968 Ok(())
1969 }
1970
1971 fn check_all_commands_done(&self) -> Result<(), Error> {
1973 for cmd_reg in self.regs().comd_iter() {
1977 let cmd = cmd_reg.read();
1978
1979 if cmd.bits() != 0x0 && !cmd.opcode().is_end() && !cmd.command_done().bit_is_set() {
1980 return Err(Error::ExecutionIncomplete);
1981 }
1982 }
1983
1984 Ok(())
1985 }
1986
1987 fn check_errors(&self) -> Result<(), Error> {
1995 let interrupts = self.regs().int_raw().read();
1996
1997 cfg_if::cfg_if! {
2000 if #[cfg(esp32)] {
2001 let retval = if interrupts.time_out().bit_is_set() {
2003 Err(Error::Timeout)
2004 } else if interrupts.nack().bit_is_set() {
2005 Err(Error::AcknowledgeCheckFailed(estimate_ack_failed_reason(self.regs())))
2006 } else if interrupts.arbitration_lost().bit_is_set() {
2007 Err(Error::ArbitrationLost)
2008 } else {
2009 Ok(())
2010 };
2011 } else {
2012 let retval = if interrupts.time_out().bit_is_set() {
2014 Err(Error::Timeout)
2015 } else if interrupts.nack().bit_is_set() {
2016 Err(Error::AcknowledgeCheckFailed(estimate_ack_failed_reason(self.regs())))
2017 } else if interrupts.arbitration_lost().bit_is_set() {
2018 Err(Error::ArbitrationLost)
2019 } else if interrupts.trans_complete().bit_is_set() && self.regs().sr().read().resp_rec().bit_is_clear() {
2020 Err(Error::AcknowledgeCheckFailed(AcknowledgeCheckFailedReason::Data))
2021 } else {
2022 Ok(())
2023 };
2024 }
2025 }
2026
2027 if retval.is_err() {
2028 self.reset();
2029 }
2030
2031 retval
2032 }
2033
2034 fn update_config(&self) {
2044 #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
2047 self.regs().ctr().modify(|_, w| w.conf_upgate().set_bit());
2048 }
2049
2050 fn start_transmission(&self) {
2052 self.regs().ctr().modify(|_, w| w.trans_start().set_bit());
2054 }
2055
2056 #[cfg(not(any(esp32, esp32s2)))]
2057 fn fill_tx_fifo(&self, bytes: &[u8]) -> Result<usize, Error> {
2059 let mut index = 0;
2060 while index < bytes.len() && !self.regs().int_raw().read().txfifo_ovf().bit_is_set() {
2061 write_fifo(self.regs(), bytes[index]);
2062 index += 1;
2063 }
2064 if self.regs().int_raw().read().txfifo_ovf().bit_is_set() {
2065 index -= 1;
2066 self.regs()
2067 .int_clr()
2068 .write(|w| w.txfifo_ovf().clear_bit_by_one());
2069 }
2070 Ok(index)
2071 }
2072
2073 #[cfg(not(any(esp32, esp32s2)))]
2074 fn write_remaining_tx_fifo_blocking(
2077 &self,
2078 start_index: usize,
2079 bytes: &[u8],
2080 ) -> Result<(), Error> {
2081 let mut index = start_index;
2082 loop {
2083 self.check_errors()?;
2084
2085 while !self.regs().int_raw().read().txfifo_wm().bit_is_set() {
2086 self.check_errors()?;
2087 }
2088
2089 self.regs()
2090 .int_clr()
2091 .write(|w| w.txfifo_wm().clear_bit_by_one());
2092
2093 while !self.regs().int_raw().read().txfifo_wm().bit_is_set() {
2094 self.check_errors()?;
2095 }
2096
2097 if index >= bytes.len() {
2098 break Ok(());
2099 }
2100
2101 write_fifo(self.regs(), bytes[index]);
2102 index += 1;
2103 }
2104 }
2105
2106 #[cfg(any(esp32, esp32s2))]
2107 fn fill_tx_fifo(&self, bytes: &[u8]) -> Result<usize, Error> {
2109 if bytes.len() > 31 {
2114 return Err(Error::FifoExceeded);
2115 }
2116
2117 for b in bytes {
2118 write_fifo(self.regs(), *b);
2119 }
2120
2121 Ok(bytes.len())
2122 }
2123
2124 #[cfg(any(esp32, esp32s2))]
2125 fn write_remaining_tx_fifo_blocking(
2128 &self,
2129 start_index: usize,
2130 bytes: &[u8],
2131 ) -> Result<(), Error> {
2132 if start_index >= bytes.len() {
2137 return Ok(());
2138 }
2139
2140 for b in bytes {
2143 write_fifo(self.regs(), *b);
2144 self.check_errors()?;
2145 }
2146
2147 Ok(())
2148 }
2149
2150 #[cfg(not(esp32))]
2152 fn reset_fifo(&self) {
2153 self.regs().fifo_conf().modify(|_, w| unsafe {
2155 w.tx_fifo_rst().set_bit();
2156 w.rx_fifo_rst().set_bit();
2157 w.nonfifo_en().clear_bit();
2158 w.fifo_prt_en().set_bit();
2159 w.rxfifo_wm_thrhd().bits(1);
2160 w.txfifo_wm_thrhd().bits(8)
2161 });
2162
2163 self.regs().fifo_conf().modify(|_, w| {
2164 w.tx_fifo_rst().clear_bit();
2165 w.rx_fifo_rst().clear_bit()
2166 });
2167
2168 self.regs().int_clr().write(|w| {
2169 w.rxfifo_wm().clear_bit_by_one();
2170 w.txfifo_wm().clear_bit_by_one()
2171 });
2172
2173 self.update_config();
2174 }
2175
2176 #[cfg(esp32)]
2178 fn reset_fifo(&self) {
2179 self.regs().fifo_conf().modify(|_, w| unsafe {
2181 w.tx_fifo_rst().set_bit();
2182 w.rx_fifo_rst().set_bit();
2183 w.nonfifo_en().clear_bit();
2184 w.nonfifo_rx_thres().bits(1);
2185 w.nonfifo_tx_thres().bits(32)
2186 });
2187
2188 self.regs().fifo_conf().modify(|_, w| {
2189 w.tx_fifo_rst().clear_bit();
2190 w.rx_fifo_rst().clear_bit()
2191 });
2192
2193 self.regs()
2194 .int_clr()
2195 .write(|w| w.rxfifo_full().clear_bit_by_one());
2196 }
2197
2198 fn start_write_operation(
2199 &self,
2200 address: I2cAddress,
2201 bytes: &[u8],
2202 start: bool,
2203 stop: bool,
2204 ) -> Result<usize, Error> {
2205 self.reset_fifo();
2206 self.reset_command_list();
2207 let cmd_iterator = &mut self.regs().comd_iter();
2208
2209 if start {
2210 add_cmd(cmd_iterator, Command::Start)?;
2211 }
2212
2213 self.setup_write(address, bytes, start, cmd_iterator)?;
2214
2215 add_cmd(
2216 cmd_iterator,
2217 if stop { Command::Stop } else { Command::End },
2218 )?;
2219 let index = self.fill_tx_fifo(bytes)?;
2220 self.start_transmission();
2221
2222 Ok(index)
2223 }
2224
2225 fn start_read_operation(
2236 &self,
2237 address: I2cAddress,
2238 buffer: &mut [u8],
2239 start: bool,
2240 stop: bool,
2241 will_continue: bool,
2242 ) -> Result<(), Error> {
2243 self.reset_fifo();
2244 self.reset_command_list();
2245
2246 let cmd_iterator = &mut self.regs().comd_iter();
2247
2248 if start {
2249 add_cmd(cmd_iterator, Command::Start)?;
2250 }
2251
2252 self.setup_read(address, buffer, start, will_continue, cmd_iterator)?;
2253
2254 add_cmd(
2255 cmd_iterator,
2256 if stop { Command::Stop } else { Command::End },
2257 )?;
2258 self.start_transmission();
2259 Ok(())
2260 }
2261
2262 fn write_operation_blocking(
2271 &self,
2272 address: I2cAddress,
2273 bytes: &[u8],
2274 start: bool,
2275 stop: bool,
2276 ) -> Result<(), Error> {
2277 self.clear_all_interrupts();
2278
2279 if bytes.is_empty() && !start && !stop {
2282 return Ok(());
2283 }
2284
2285 let index = self.start_write_operation(address, bytes, start, stop)?;
2286 self.write_remaining_tx_fifo_blocking(index, bytes)?;
2288 self.wait_for_completion_blocking(!stop)?;
2289 Ok(())
2290 }
2291
2292 fn read_operation_blocking(
2303 &self,
2304 address: I2cAddress,
2305 buffer: &mut [u8],
2306 start: bool,
2307 stop: bool,
2308 will_continue: bool,
2309 ) -> Result<(), Error> {
2310 self.clear_all_interrupts();
2311
2312 if buffer.is_empty() {
2315 return Ok(());
2316 }
2317
2318 self.start_read_operation(address, buffer, start, stop, will_continue)?;
2319 self.read_all_from_fifo_blocking(buffer)?;
2320 self.wait_for_completion_blocking(!stop)?;
2321 Ok(())
2322 }
2323
2324 async fn write_operation(
2333 &self,
2334 address: I2cAddress,
2335 bytes: &[u8],
2336 start: bool,
2337 stop: bool,
2338 ) -> Result<(), Error> {
2339 self.clear_all_interrupts();
2340
2341 if bytes.is_empty() && !start && !stop {
2344 return Ok(());
2345 }
2346
2347 let index = self.start_write_operation(address, bytes, start, stop)?;
2348 self.write_remaining_tx_fifo(index, bytes).await?;
2350 self.wait_for_completion(!stop).await?;
2351 Ok(())
2352 }
2353
2354 async fn read_operation(
2365 &self,
2366 address: I2cAddress,
2367 buffer: &mut [u8],
2368 start: bool,
2369 stop: bool,
2370 will_continue: bool,
2371 ) -> Result<(), Error> {
2372 self.clear_all_interrupts();
2373
2374 if buffer.is_empty() {
2377 return Ok(());
2378 }
2379
2380 self.start_read_operation(address, buffer, start, stop, will_continue)?;
2381 self.read_all_from_fifo(buffer).await?;
2382 self.wait_for_completion(!stop).await?;
2383 Ok(())
2384 }
2385
2386 fn read_blocking(
2387 &self,
2388 address: I2cAddress,
2389 buffer: &mut [u8],
2390 start: bool,
2391 stop: bool,
2392 will_continue: bool,
2393 ) -> Result<(), Error> {
2394 let chunk_count = buffer.len().div_ceil(I2C_CHUNK_SIZE);
2395 for (idx, chunk) in buffer.chunks_mut(I2C_CHUNK_SIZE).enumerate() {
2396 self.read_operation_blocking(
2397 address,
2398 chunk,
2399 start && idx == 0,
2400 stop && idx == chunk_count - 1,
2401 will_continue || idx < chunk_count - 1,
2402 )?;
2403 }
2404
2405 Ok(())
2406 }
2407
2408 fn write_blocking(
2409 &self,
2410 address: I2cAddress,
2411 buffer: &[u8],
2412 start: bool,
2413 stop: bool,
2414 ) -> Result<(), Error> {
2415 if buffer.is_empty() {
2416 return self.write_operation_blocking(address, &[], start, stop);
2417 }
2418 let chunk_count = buffer.len().div_ceil(I2C_CHUNK_SIZE);
2419 for (idx, chunk) in buffer.chunks(I2C_CHUNK_SIZE).enumerate() {
2420 self.write_operation_blocking(
2421 address,
2422 chunk,
2423 start && idx == 0,
2424 stop && idx == chunk_count - 1,
2425 )?;
2426 }
2427
2428 Ok(())
2429 }
2430
2431 async fn read(
2432 &self,
2433 address: I2cAddress,
2434 buffer: &mut [u8],
2435 start: bool,
2436 stop: bool,
2437 will_continue: bool,
2438 ) -> Result<(), Error> {
2439 let chunk_count = buffer.len().div_ceil(I2C_CHUNK_SIZE);
2440 for (idx, chunk) in buffer.chunks_mut(I2C_CHUNK_SIZE).enumerate() {
2441 self.read_operation(
2442 address,
2443 chunk,
2444 start && idx == 0,
2445 stop && idx == chunk_count - 1,
2446 will_continue || idx < chunk_count - 1,
2447 )
2448 .await?;
2449 }
2450
2451 Ok(())
2452 }
2453
2454 async fn write(
2455 &self,
2456 address: I2cAddress,
2457 buffer: &[u8],
2458 start: bool,
2459 stop: bool,
2460 ) -> Result<(), Error> {
2461 if buffer.is_empty() {
2462 return self.write_operation(address, &[], start, stop).await;
2463 }
2464 let chunk_count = buffer.len().div_ceil(I2C_CHUNK_SIZE);
2465 for (idx, chunk) in buffer.chunks(I2C_CHUNK_SIZE).enumerate() {
2466 self.write_operation(
2467 address,
2468 chunk,
2469 start && idx == 0,
2470 stop && idx == chunk_count - 1,
2471 )
2472 .await?;
2473 }
2474
2475 Ok(())
2476 }
2477}
2478
2479fn check_timeout(v: u32, max: u32) -> Result<u32, ConfigError> {
2480 if v <= max {
2481 Ok(v)
2482 } else {
2483 Err(ConfigError::TimeoutInvalid)
2484 }
2485}
2486
2487#[doc(hidden)]
2489#[non_exhaustive]
2490pub struct State {
2491 pub waker: AtomicWaker,
2493}
2494
2495#[doc(hidden)]
2497pub trait Instance: Peripheral<P = Self> + Into<AnyI2c> + 'static {
2498 fn parts(&self) -> (&Info, &State);
2500
2501 #[inline(always)]
2503 fn info(&self) -> &Info {
2504 self.parts().0
2505 }
2506
2507 #[inline(always)]
2509 fn state(&self) -> &State {
2510 self.parts().1
2511 }
2512}
2513
2514fn add_cmd<'a, I>(cmd_iterator: &mut I, command: Command) -> Result<(), Error>
2516where
2517 I: Iterator<Item = &'a COMD>,
2518{
2519 let cmd = cmd_iterator.next().ok_or(Error::CommandNumberExceeded)?;
2520
2521 cmd.write(|w| match command {
2522 Command::Start => w.opcode().rstart(),
2523 Command::Stop => w.opcode().stop(),
2524 Command::End => w.opcode().end(),
2525 Command::Write {
2526 ack_exp,
2527 ack_check_en,
2528 length,
2529 } => unsafe {
2530 w.opcode().write();
2531 w.ack_exp().bit(ack_exp == Ack::Nack);
2532 w.ack_check_en().bit(ack_check_en);
2533 w.byte_num().bits(length);
2534 w
2535 },
2536 Command::Read { ack_value, length } => unsafe {
2537 w.opcode().read();
2538 w.ack_value().bit(ack_value == Ack::Nack);
2539 w.byte_num().bits(length);
2540 w
2541 },
2542 });
2543
2544 Ok(())
2545}
2546
2547#[cfg(not(esp32s2))]
2548fn read_fifo(register_block: &RegisterBlock) -> u8 {
2549 register_block.data().read().fifo_rdata().bits()
2550}
2551
2552#[cfg(not(esp32))]
2553fn write_fifo(register_block: &RegisterBlock, data: u8) {
2554 register_block
2555 .data()
2556 .write(|w| unsafe { w.fifo_rdata().bits(data) });
2557}
2558
2559#[cfg(esp32s2)]
2560fn read_fifo(register_block: &RegisterBlock) -> u8 {
2561 let base_addr = register_block.scl_low_period().as_ptr();
2562 let fifo_ptr = (if base_addr as u32 == 0x3f413000 {
2563 0x6001301c
2564 } else {
2565 0x6002701c
2566 }) as *mut u32;
2567 unsafe { (fifo_ptr.read_volatile() & 0xff) as u8 }
2568}
2569
2570#[cfg(esp32)]
2571fn write_fifo(register_block: &RegisterBlock, data: u8) {
2572 let base_addr = register_block.scl_low_period().as_ptr();
2573 let fifo_ptr = (if base_addr as u32 == 0x3FF53000 {
2574 0x6001301c
2575 } else {
2576 0x6002701c
2577 }) as *mut u32;
2578 unsafe {
2579 fifo_ptr.write_volatile(data as u32);
2580 }
2581}
2582
2583fn estimate_ack_failed_reason(_register_block: &RegisterBlock) -> AcknowledgeCheckFailedReason {
2586 cfg_if::cfg_if! {
2587 if #[cfg(any(esp32, esp32s2, esp32c2, esp32c3))] {
2588 AcknowledgeCheckFailedReason::Unknown
2589 } else {
2590 if _register_block.fifo_st().read().txfifo_raddr().bits() <= 1 {
2592 AcknowledgeCheckFailedReason::Address
2593 } else {
2594 AcknowledgeCheckFailedReason::Data
2595 }
2596 }
2597 }
2598}
2599
2600macro_rules! instance {
2601 ($inst:ident, $peri:ident, $scl:ident, $sda:ident, $interrupt:ident) => {
2602 impl Instance for crate::peripherals::$inst {
2603 fn parts(&self) -> (&Info, &State) {
2604 #[crate::handler]
2605 pub(super) fn irq_handler() {
2606 async_handler(&PERIPHERAL, &STATE);
2607 }
2608
2609 static STATE: State = State {
2610 waker: AtomicWaker::new(),
2611 };
2612
2613 static PERIPHERAL: Info = Info {
2614 register_block: crate::peripherals::$inst::ptr(),
2615 peripheral: crate::system::Peripheral::$peri,
2616 async_handler: irq_handler,
2617 interrupt: Interrupt::$interrupt,
2618 scl_output: OutputSignal::$scl,
2619 scl_input: InputSignal::$scl,
2620 sda_output: OutputSignal::$sda,
2621 sda_input: InputSignal::$sda,
2622 };
2623 (&PERIPHERAL, &STATE)
2624 }
2625 }
2626 };
2627}
2628
2629#[cfg(i2c0)]
2630instance!(I2C0, I2cExt0, I2CEXT0_SCL, I2CEXT0_SDA, I2C_EXT0);
2631#[cfg(i2c1)]
2632instance!(I2C1, I2cExt1, I2CEXT1_SCL, I2CEXT1_SDA, I2C_EXT1);
2633
2634crate::any_peripheral! {
2635 pub peripheral AnyI2c {
2637 #[cfg(i2c0)]
2638 I2c0(crate::peripherals::I2C0),
2639 #[cfg(i2c1)]
2640 I2c1(crate::peripherals::I2C1),
2641 }
2642}
2643
2644impl Instance for AnyI2c {
2645 delegate::delegate! {
2646 to match &self.0 {
2647 AnyI2cInner::I2c0(i2c) => i2c,
2648 #[cfg(i2c1)]
2649 AnyI2cInner::I2c1(i2c) => i2c,
2650 } {
2651 fn parts(&self) -> (&Info, &State);
2652 }
2653 }
2654}