1#![macro_use]
4
5use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::sync::atomic::compiler_fence;
8use core::sync::atomic::Ordering::SeqCst;
9use core::task::Poll;
10
11use embassy_embedded_hal::SetConfig;
12use embassy_hal_internal::{Peri, PeripheralType};
13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant};
16use embedded_hal_1::i2c::Operation;
17pub use pac::twim::vals::Frequency;
18
19use crate::chip::EASY_DMA_SIZE;
20use crate::gpio::Pin as GpioPin;
21use crate::interrupt::typelevel::Interrupt;
22use crate::pac::gpio::vals as gpiovals;
23use crate::pac::twim::vals;
24use crate::util::slice_in_ram;
25use crate::{gpio, interrupt, pac};
26
27#[non_exhaustive]
29pub struct Config {
30 pub frequency: Frequency,
32
33 pub sda_high_drive: bool,
35
36 pub sda_pullup: bool,
41
42 pub scl_high_drive: bool,
44
45 pub scl_pullup: bool,
50}
51
52impl Default for Config {
53 fn default() -> Self {
54 Self {
55 frequency: Frequency::K100,
56 scl_high_drive: false,
57 sda_pullup: false,
58 sda_high_drive: false,
59 scl_pullup: false,
60 }
61 }
62}
63
64#[derive(Debug, Copy, Clone, Eq, PartialEq)]
66#[cfg_attr(feature = "defmt", derive(defmt::Format))]
67#[non_exhaustive]
68pub enum Error {
69 TxBufferTooLong,
71 RxBufferTooLong,
73 Transmit,
75 Receive,
77 RAMBufferTooSmall,
79 AddressNack,
81 DataNack,
83 Overrun,
85 Timeout,
87}
88
89pub struct InterruptHandler<T: Instance> {
91 _phantom: PhantomData<T>,
92}
93
94impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
95 unsafe fn on_interrupt() {
96 let r = T::regs();
97 let s = T::state();
98
99 if r.events_suspended().read() != 0 {
100 s.end_waker.wake();
101 r.intenclr().write(|w| w.set_suspended(true));
102 }
103 if r.events_stopped().read() != 0 {
104 s.end_waker.wake();
105 r.intenclr().write(|w| w.set_stopped(true));
106 }
107 if r.events_error().read() != 0 {
108 s.end_waker.wake();
109 r.intenclr().write(|w| w.set_error(true));
110 }
111 }
112}
113
114pub struct Twim<'d> {
116 r: pac::twim::Twim,
117 state: &'static State,
118 tx_ram_buffer: &'d mut [u8],
119 _p: PhantomData<&'d ()>,
120}
121
122impl<'d> Twim<'d> {
123 pub fn new<T: Instance>(
131 _twim: Peri<'d, T>,
132 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
133 sda: Peri<'d, impl GpioPin>,
134 scl: Peri<'d, impl GpioPin>,
135 config: Config,
136 tx_ram_buffer: &'d mut [u8],
137 ) -> Self {
138 let r = T::regs();
139
140 sda.conf().write(|w| {
142 w.set_dir(gpiovals::Dir::OUTPUT);
143 w.set_input(gpiovals::Input::CONNECT);
144 w.set_drive(match config.sda_high_drive {
145 true => gpiovals::Drive::H0D1,
146 false => gpiovals::Drive::S0D1,
147 });
148 if config.sda_pullup {
149 w.set_pull(gpiovals::Pull::PULLUP);
150 }
151 });
152 scl.conf().write(|w| {
153 w.set_dir(gpiovals::Dir::OUTPUT);
154 w.set_input(gpiovals::Input::CONNECT);
155 w.set_drive(match config.scl_high_drive {
156 true => gpiovals::Drive::H0D1,
157 false => gpiovals::Drive::S0D1,
158 });
159 if config.sda_pullup {
160 w.set_pull(gpiovals::Pull::PULLUP);
161 }
162 });
163
164 r.psel().sda().write_value(sda.psel_bits());
166 r.psel().scl().write_value(scl.psel_bits());
167
168 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
170
171 let mut twim = Self {
172 r: T::regs(),
173 state: T::state(),
174 tx_ram_buffer,
175 _p: PhantomData {},
176 };
177
178 Self::set_config(&mut twim, &config).unwrap();
180
181 r.intenclr().write(|w| w.0 = 0xFFFF_FFFF);
183
184 T::Interrupt::unpend();
185 unsafe { T::Interrupt::enable() };
186
187 twim
188 }
189
190 unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
192 let buffer = if slice_in_ram(buffer) {
193 buffer
194 } else {
195 if buffer.len() > self.tx_ram_buffer.len() {
196 return Err(Error::RAMBufferTooSmall);
197 }
198 trace!("Copying TWIM tx buffer into RAM for DMA");
199 let ram_buffer = &mut self.tx_ram_buffer[..buffer.len()];
200 ram_buffer.copy_from_slice(buffer);
201 &*ram_buffer
202 };
203
204 if buffer.len() > EASY_DMA_SIZE {
205 return Err(Error::TxBufferTooLong);
206 }
207
208 let r = self.r;
209
210 r.txd().ptr().write_value(buffer.as_ptr() as u32);
214 r.txd().maxcnt().write(|w|
215 w.set_maxcnt(buffer.len() as _));
222
223 Ok(())
224 }
225
226 unsafe fn set_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
228 if buffer.len() > EASY_DMA_SIZE {
232 return Err(Error::RxBufferTooLong);
233 }
234
235 let r = self.r;
236
237 r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32);
241 r.rxd().maxcnt().write(|w|
242 w.set_maxcnt(buffer.len() as _));
252
253 Ok(())
254 }
255
256 fn clear_errorsrc(&mut self) {
257 let r = self.r;
258 r.errorsrc().write(|w| {
259 w.set_anack(true);
260 w.set_dnack(true);
261 w.set_overrun(true);
262 });
263 }
264
265 fn check_errorsrc(&mut self) -> Result<(), Error> {
267 let r = self.r;
268
269 let err = r.errorsrc().read();
270 if err.anack() {
271 return Err(Error::AddressNack);
272 }
273 if err.dnack() {
274 return Err(Error::DataNack);
275 }
276 if err.overrun() {
277 return Err(Error::Overrun);
278 }
279 Ok(())
280 }
281
282 fn check_rx(&self, len: usize) -> Result<(), Error> {
283 let r = self.r;
284 if r.rxd().amount().read().0 != len as u32 {
285 Err(Error::Receive)
286 } else {
287 Ok(())
288 }
289 }
290
291 fn check_tx(&self, len: usize) -> Result<(), Error> {
292 let r = self.r;
293 if r.txd().amount().read().0 != len as u32 {
294 Err(Error::Transmit)
295 } else {
296 Ok(())
297 }
298 }
299
300 fn blocking_wait(&mut self) {
302 let r = self.r;
303 loop {
304 if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
305 r.events_suspended().write_value(0);
306 r.events_stopped().write_value(0);
307 break;
308 }
309 if r.events_error().read() != 0 {
310 r.events_error().write_value(0);
311 r.tasks_stop().write_value(1);
312 }
313 }
314 }
315
316 #[cfg(feature = "time")]
318 fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
319 let r = self.r;
320 let deadline = Instant::now() + timeout;
321 loop {
322 if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
323 r.events_stopped().write_value(0);
324 break;
325 }
326 if r.events_error().read() != 0 {
327 r.events_error().write_value(0);
328 r.tasks_stop().write_value(1);
329 }
330 if Instant::now() > deadline {
331 r.tasks_stop().write_value(1);
332 return Err(Error::Timeout);
333 }
334 }
335
336 Ok(())
337 }
338
339 async fn async_wait(&mut self) -> Result<(), Error> {
341 poll_fn(|cx| {
342 let r = self.r;
343 let s = self.state;
344
345 s.end_waker.register(cx.waker());
346 if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
347 r.events_stopped().write_value(0);
348
349 return Poll::Ready(Ok(()));
350 }
351
352 if r.events_error().read() != 0 {
354 r.events_error().write_value(0);
355 r.tasks_stop().write_value(1);
356 if let Err(e) = self.check_errorsrc() {
357 return Poll::Ready(Err(e));
358 } else {
359 return Poll::Ready(Err(Error::Timeout));
360 }
361 }
362
363 Poll::Pending
364 })
365 .await
366 }
367
368 fn setup_operations(
369 &mut self,
370 address: u8,
371 operations: &mut [Operation<'_>],
372 last_op: Option<&Operation<'_>>,
373 inten: bool,
374 ) -> Result<usize, Error> {
375 let r = self.r;
376
377 compiler_fence(SeqCst);
378
379 r.address().write(|w| w.set_address(address));
380
381 r.events_suspended().write_value(0);
382 r.events_stopped().write_value(0);
383 r.events_error().write_value(0);
384 self.clear_errorsrc();
385
386 if inten {
387 r.intenset().write(|w| {
388 w.set_suspended(true);
389 w.set_stopped(true);
390 w.set_error(true);
391 });
392 } else {
393 r.intenclr().write(|w| {
394 w.set_suspended(true);
395 w.set_stopped(true);
396 w.set_error(true);
397 });
398 }
399
400 assert!(!operations.is_empty());
401 match operations {
402 [Operation::Read(_), Operation::Read(_), ..] => {
403 panic!("Consecutive read operations are not supported!")
404 }
405 [Operation::Read(rd_buffer), Operation::Write(wr_buffer), rest @ ..] => {
406 let stop = rest.is_empty();
407
408 unsafe {
410 self.set_tx_buffer(wr_buffer)?;
411 self.set_rx_buffer(rd_buffer)?;
412 }
413
414 r.shorts().write(|w| {
415 w.set_lastrx_starttx(true);
416 if stop {
417 w.set_lasttx_stop(true);
418 } else {
419 w.set_lasttx_suspend(true);
420 }
421 });
422
423 r.tasks_startrx().write_value(1);
425 if last_op.is_some() {
426 r.tasks_resume().write_value(1);
427 }
428
429 if rd_buffer.is_empty() {
431 r.tasks_starttx().write_value(1);
433 }
434
435 Ok(2)
436 }
437 [Operation::Read(buffer)] => {
438 unsafe {
440 self.set_rx_buffer(buffer)?;
441 }
442
443 r.shorts().write(|w| w.set_lastrx_stop(true));
444
445 r.tasks_startrx().write_value(1);
447 if last_op.is_some() {
448 r.tasks_resume().write_value(1);
449 }
450
451 if buffer.is_empty() {
452 r.tasks_stop().write_value(1);
454 }
455
456 Ok(1)
457 }
458 [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]
459 if !wr_buffer.is_empty() && !rd_buffer.is_empty() =>
460 {
461 unsafe {
463 self.set_tx_buffer(wr_buffer)?;
464 self.set_rx_buffer(rd_buffer)?;
465 }
466
467 r.shorts().write(|w| {
469 w.set_lasttx_startrx(true);
470 w.set_lastrx_stop(true);
471 });
472
473 r.tasks_starttx().write_value(1);
474 if last_op.is_some() {
475 r.tasks_resume().write_value(1);
476 }
477
478 Ok(2)
479 }
480 [Operation::Write(buffer), rest @ ..] => {
481 let stop = rest.is_empty();
482
483 unsafe {
485 self.set_tx_buffer(buffer)?;
486 }
487
488 r.shorts().write(|w| {
490 if stop {
491 w.set_lasttx_stop(true);
492 } else {
493 w.set_lasttx_suspend(true);
494 }
495 });
496
497 r.tasks_starttx().write_value(1);
498 if last_op.is_some() {
499 r.tasks_resume().write_value(1);
500 }
501
502 if buffer.is_empty() {
503 if stop {
505 r.tasks_stop().write_value(1);
506 } else {
507 r.tasks_suspend().write_value(1);
508 }
509 }
510
511 Ok(1)
512 }
513 [] => unreachable!(),
514 }
515 }
516
517 fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> {
518 compiler_fence(SeqCst);
519 self.check_errorsrc()?;
520
521 assert!(operations.len() == 1 || operations.len() == 2);
522 match operations {
523 [Operation::Read(rd_buffer), Operation::Write(wr_buffer)]
524 | [Operation::Write(wr_buffer), Operation::Read(rd_buffer)] => {
525 self.check_rx(rd_buffer.len())?;
526 self.check_tx(wr_buffer.len())?;
527 }
528 [Operation::Read(buffer)] => {
529 self.check_rx(buffer.len())?;
530 }
531 [Operation::Write(buffer), ..] => {
532 self.check_tx(buffer.len())?;
533 }
534 _ => unreachable!(),
535 }
536 Ok(())
537 }
538
539 pub fn blocking_transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
552 let mut last_op = None;
553 while !operations.is_empty() {
554 let ops = self.setup_operations(address, operations, last_op, false)?;
555 let (in_progress, rest) = operations.split_at_mut(ops);
556 self.blocking_wait();
557 self.check_operations(in_progress)?;
558 last_op = in_progress.last();
559 operations = rest;
560 }
561 Ok(())
562 }
563
564 #[cfg(feature = "time")]
568 pub fn blocking_transaction_timeout(
569 &mut self,
570 address: u8,
571 mut operations: &mut [Operation<'_>],
572 timeout: Duration,
573 ) -> Result<(), Error> {
574 let mut last_op = None;
575 while !operations.is_empty() {
576 let ops = self.setup_operations(address, operations, last_op, false)?;
577 let (in_progress, rest) = operations.split_at_mut(ops);
578 self.blocking_wait_timeout(timeout)?;
579 self.check_operations(in_progress)?;
580 last_op = in_progress.last();
581 operations = rest;
582 }
583 Ok(())
584 }
585
586 pub async fn transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
597 let mut last_op = None;
598 while !operations.is_empty() {
599 let ops = self.setup_operations(address, operations, last_op, true)?;
600 let (in_progress, rest) = operations.split_at_mut(ops);
601 self.async_wait().await?;
602 self.check_operations(in_progress)?;
603 last_op = in_progress.last();
604 operations = rest;
605 }
606 Ok(())
607 }
608
609 pub fn blocking_write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
616 self.blocking_transaction(address, &mut [Operation::Write(buffer)])
617 }
618
619 pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
624 self.blocking_transaction(address, &mut [Operation::Read(buffer)])
625 }
626
627 pub fn blocking_write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
633 self.blocking_transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
634 }
635
636 #[cfg(feature = "time")]
642 pub fn blocking_write_timeout(&mut self, address: u8, buffer: &[u8], timeout: Duration) -> Result<(), Error> {
643 self.blocking_transaction_timeout(address, &mut [Operation::Write(buffer)], timeout)
644 }
645
646 #[cfg(feature = "time")]
651 pub fn blocking_read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> {
652 self.blocking_transaction_timeout(address, &mut [Operation::Read(buffer)], timeout)
653 }
654
655 #[cfg(feature = "time")]
661 pub fn blocking_write_read_timeout(
662 &mut self,
663 address: u8,
664 wr_buffer: &[u8],
665 rd_buffer: &mut [u8],
666 timeout: Duration,
667 ) -> Result<(), Error> {
668 self.blocking_transaction_timeout(
669 address,
670 &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)],
671 timeout,
672 )
673 }
674
675 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
682 self.transaction(address, &mut [Operation::Read(buffer)]).await
683 }
684
685 pub async fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
690 self.transaction(address, &mut [Operation::Write(buffer)]).await
691 }
692
693 pub async fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
699 self.transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
700 .await
701 }
702}
703
704impl<'a> Drop for Twim<'a> {
705 fn drop(&mut self) {
706 trace!("twim drop");
707
708 let r = self.r;
712 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
713
714 gpio::deconfigure_pin(r.psel().sda().read());
715 gpio::deconfigure_pin(r.psel().scl().read());
716
717 trace!("twim drop: done");
718 }
719}
720
721pub(crate) struct State {
722 end_waker: AtomicWaker,
723}
724
725impl State {
726 pub(crate) const fn new() -> Self {
727 Self {
728 end_waker: AtomicWaker::new(),
729 }
730 }
731}
732
733pub(crate) trait SealedInstance {
734 fn regs() -> pac::twim::Twim;
735 fn state() -> &'static State;
736}
737
738#[allow(private_bounds)]
740pub trait Instance: SealedInstance + PeripheralType + 'static {
741 type Interrupt: interrupt::typelevel::Interrupt;
743}
744
745macro_rules! impl_twim {
746 ($type:ident, $pac_type:ident, $irq:ident) => {
747 impl crate::twim::SealedInstance for peripherals::$type {
748 fn regs() -> pac::twim::Twim {
749 pac::$pac_type
750 }
751 fn state() -> &'static crate::twim::State {
752 static STATE: crate::twim::State = crate::twim::State::new();
753 &STATE
754 }
755 }
756 impl crate::twim::Instance for peripherals::$type {
757 type Interrupt = crate::interrupt::typelevel::$irq;
758 }
759 };
760}
761
762mod eh02 {
765 use super::*;
766
767 impl<'a> embedded_hal_02::blocking::i2c::Write for Twim<'a> {
768 type Error = Error;
769
770 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
771 self.blocking_write(addr, bytes)
772 }
773 }
774
775 impl<'a> embedded_hal_02::blocking::i2c::Read for Twim<'a> {
776 type Error = Error;
777
778 fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> {
779 self.blocking_read(addr, bytes)
780 }
781 }
782
783 impl<'a> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a> {
784 type Error = Error;
785
786 fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> {
787 self.blocking_write_read(addr, bytes, buffer)
788 }
789 }
790}
791
792impl embedded_hal_1::i2c::Error for Error {
793 fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
794 match *self {
795 Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
796 Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
797 Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other,
798 Self::Receive => embedded_hal_1::i2c::ErrorKind::Other,
799 Self::RAMBufferTooSmall => embedded_hal_1::i2c::ErrorKind::Other,
800 Self::AddressNack => {
801 embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
802 }
803 Self::DataNack => {
804 embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Data)
805 }
806 Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
807 Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
808 }
809 }
810}
811
812impl<'d> embedded_hal_1::i2c::ErrorType for Twim<'d> {
813 type Error = Error;
814}
815
816impl<'d> embedded_hal_1::i2c::I2c for Twim<'d> {
817 fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
818 self.blocking_transaction(address, operations)
819 }
820}
821
822impl<'d> embedded_hal_async::i2c::I2c for Twim<'d> {
823 async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
824 self.transaction(address, operations).await
825 }
826}
827
828impl<'d> SetConfig for Twim<'d> {
829 type Config = Config;
830 type ConfigError = ();
831 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
832 let r = self.r;
833 r.frequency().write(|w| w.set_frequency(config.frequency));
834
835 Ok(())
836 }
837}