1#![macro_use]
4
5use core::future::{poll_fn, Future};
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, T: Instance> {
116 _p: Peri<'d, T>,
117 tx_ram_buffer: &'d mut [u8],
118}
119
120impl<'d, T: Instance> Twim<'d, T> {
121 pub fn new(
129 twim: Peri<'d, T>,
130 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
131 sda: Peri<'d, impl GpioPin>,
132 scl: Peri<'d, impl GpioPin>,
133 config: Config,
134 tx_ram_buffer: &'d mut [u8],
135 ) -> Self {
136 let r = T::regs();
137
138 sda.conf().write(|w| {
140 w.set_dir(gpiovals::Dir::OUTPUT);
141 w.set_input(gpiovals::Input::CONNECT);
142 w.set_drive(match config.sda_high_drive {
143 true => gpiovals::Drive::H0D1,
144 false => gpiovals::Drive::S0D1,
145 });
146 if config.sda_pullup {
147 w.set_pull(gpiovals::Pull::PULLUP);
148 }
149 });
150 scl.conf().write(|w| {
151 w.set_dir(gpiovals::Dir::OUTPUT);
152 w.set_input(gpiovals::Input::CONNECT);
153 w.set_drive(match config.scl_high_drive {
154 true => gpiovals::Drive::H0D1,
155 false => gpiovals::Drive::S0D1,
156 });
157 if config.sda_pullup {
158 w.set_pull(gpiovals::Pull::PULLUP);
159 }
160 });
161
162 r.psel().sda().write_value(sda.psel_bits());
164 r.psel().scl().write_value(scl.psel_bits());
165
166 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
168
169 let mut twim = Self {
170 _p: twim,
171 tx_ram_buffer,
172 };
173
174 Self::set_config(&mut twim, &config).unwrap();
176
177 r.intenclr().write(|w| w.0 = 0xFFFF_FFFF);
179
180 T::Interrupt::unpend();
181 unsafe { T::Interrupt::enable() };
182
183 twim
184 }
185
186 unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
188 let buffer = if slice_in_ram(buffer) {
189 buffer
190 } else {
191 if buffer.len() > self.tx_ram_buffer.len() {
192 return Err(Error::RAMBufferTooSmall);
193 }
194 trace!("Copying TWIM tx buffer into RAM for DMA");
195 let ram_buffer = &mut self.tx_ram_buffer[..buffer.len()];
196 ram_buffer.copy_from_slice(buffer);
197 &*ram_buffer
198 };
199
200 if buffer.len() > EASY_DMA_SIZE {
201 return Err(Error::TxBufferTooLong);
202 }
203
204 let r = T::regs();
205
206 r.txd().ptr().write_value(buffer.as_ptr() as u32);
210 r.txd().maxcnt().write(|w|
211 w.set_maxcnt(buffer.len() as _));
218
219 Ok(())
220 }
221
222 unsafe fn set_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
224 if buffer.len() > EASY_DMA_SIZE {
228 return Err(Error::RxBufferTooLong);
229 }
230
231 let r = T::regs();
232
233 r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32);
237 r.rxd().maxcnt().write(|w|
238 w.set_maxcnt(buffer.len() as _));
248
249 Ok(())
250 }
251
252 fn clear_errorsrc(&mut self) {
253 let r = T::regs();
254 r.errorsrc().write(|w| {
255 w.set_anack(true);
256 w.set_dnack(true);
257 w.set_overrun(true);
258 });
259 }
260
261 fn check_errorsrc() -> Result<(), Error> {
263 let r = T::regs();
264
265 let err = r.errorsrc().read();
266 if err.anack() {
267 return Err(Error::AddressNack);
268 }
269 if err.dnack() {
270 return Err(Error::DataNack);
271 }
272 if err.overrun() {
273 return Err(Error::Overrun);
274 }
275 Ok(())
276 }
277
278 fn check_rx(&self, len: usize) -> Result<(), Error> {
279 let r = T::regs();
280 if r.rxd().amount().read().0 != len as u32 {
281 Err(Error::Receive)
282 } else {
283 Ok(())
284 }
285 }
286
287 fn check_tx(&self, len: usize) -> Result<(), Error> {
288 let r = T::regs();
289 if r.txd().amount().read().0 != len as u32 {
290 Err(Error::Transmit)
291 } else {
292 Ok(())
293 }
294 }
295
296 fn blocking_wait(&mut self) {
298 let r = T::regs();
299 loop {
300 if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
301 r.events_suspended().write_value(0);
302 r.events_stopped().write_value(0);
303 break;
304 }
305 if r.events_error().read() != 0 {
306 r.events_error().write_value(0);
307 r.tasks_stop().write_value(1);
308 }
309 }
310 }
311
312 #[cfg(feature = "time")]
314 fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
315 let r = T::regs();
316 let deadline = Instant::now() + timeout;
317 loop {
318 if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
319 r.events_stopped().write_value(0);
320 break;
321 }
322 if r.events_error().read() != 0 {
323 r.events_error().write_value(0);
324 r.tasks_stop().write_value(1);
325 }
326 if Instant::now() > deadline {
327 r.tasks_stop().write_value(1);
328 return Err(Error::Timeout);
329 }
330 }
331
332 Ok(())
333 }
334
335 fn async_wait(&mut self) -> impl Future<Output = Result<(), Error>> {
337 poll_fn(move |cx| {
338 let r = T::regs();
339 let s = T::state();
340
341 s.end_waker.register(cx.waker());
342 if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
343 r.events_stopped().write_value(0);
344
345 return Poll::Ready(Ok(()));
346 }
347
348 if r.events_error().read() != 0 {
350 r.events_error().write_value(0);
351 r.tasks_stop().write_value(1);
352 if let Err(e) = Self::check_errorsrc() {
353 return Poll::Ready(Err(e));
354 } else {
355 panic!("Found events_error bit without an error in errorsrc reg");
356 }
357 }
358
359 Poll::Pending
360 })
361 }
362
363 fn setup_operations(
364 &mut self,
365 address: u8,
366 operations: &mut [Operation<'_>],
367 last_op: Option<&Operation<'_>>,
368 inten: bool,
369 ) -> Result<usize, Error> {
370 let r = T::regs();
371
372 compiler_fence(SeqCst);
373
374 r.address().write(|w| w.set_address(address));
375
376 r.events_suspended().write_value(0);
377 r.events_stopped().write_value(0);
378 r.events_error().write_value(0);
379 self.clear_errorsrc();
380
381 if inten {
382 r.intenset().write(|w| {
383 w.set_suspended(true);
384 w.set_stopped(true);
385 w.set_error(true);
386 });
387 } else {
388 r.intenclr().write(|w| {
389 w.set_suspended(true);
390 w.set_stopped(true);
391 w.set_error(true);
392 });
393 }
394
395 assert!(!operations.is_empty());
396 match operations {
397 [Operation::Read(_), Operation::Read(_), ..] => {
398 panic!("Consecutive read operations are not supported!")
399 }
400 [Operation::Read(rd_buffer), Operation::Write(wr_buffer), rest @ ..] => {
401 let stop = rest.is_empty();
402
403 unsafe {
405 self.set_tx_buffer(wr_buffer)?;
406 self.set_rx_buffer(rd_buffer)?;
407 }
408
409 r.shorts().write(|w| {
410 w.set_lastrx_starttx(true);
411 if stop {
412 w.set_lasttx_stop(true);
413 } else {
414 w.set_lasttx_suspend(true);
415 }
416 });
417
418 r.tasks_startrx().write_value(1);
420 if last_op.is_some() {
421 r.tasks_resume().write_value(1);
422 }
423
424 if rd_buffer.is_empty() {
426 r.tasks_starttx().write_value(1);
428 }
429
430 Ok(2)
431 }
432 [Operation::Read(buffer)] => {
433 unsafe {
435 self.set_rx_buffer(buffer)?;
436 }
437
438 r.shorts().write(|w| w.set_lastrx_stop(true));
439
440 r.tasks_startrx().write_value(1);
442 if last_op.is_some() {
443 r.tasks_resume().write_value(1);
444 }
445
446 if buffer.is_empty() {
447 r.tasks_stop().write_value(1);
449 }
450
451 Ok(1)
452 }
453 [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]
454 if !wr_buffer.is_empty() && !rd_buffer.is_empty() =>
455 {
456 unsafe {
458 self.set_tx_buffer(wr_buffer)?;
459 self.set_rx_buffer(rd_buffer)?;
460 }
461
462 r.shorts().write(|w| {
464 w.set_lasttx_startrx(true);
465 w.set_lastrx_stop(true);
466 });
467
468 r.tasks_starttx().write_value(1);
469 if last_op.is_some() {
470 r.tasks_resume().write_value(1);
471 }
472
473 Ok(2)
474 }
475 [Operation::Write(buffer), rest @ ..] => {
476 let stop = rest.is_empty();
477
478 unsafe {
480 self.set_tx_buffer(buffer)?;
481 }
482
483 r.shorts().write(|w| {
485 if stop {
486 w.set_lasttx_stop(true);
487 } else {
488 w.set_lasttx_suspend(true);
489 }
490 });
491
492 r.tasks_starttx().write_value(1);
493 if last_op.is_some() {
494 r.tasks_resume().write_value(1);
495 }
496
497 if buffer.is_empty() {
498 if stop {
500 r.tasks_stop().write_value(1);
501 } else {
502 r.tasks_suspend().write_value(1);
503 }
504 }
505
506 Ok(1)
507 }
508 [] => unreachable!(),
509 }
510 }
511
512 fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> {
513 compiler_fence(SeqCst);
514 Self::check_errorsrc()?;
515
516 assert!(operations.len() == 1 || operations.len() == 2);
517 match operations {
518 [Operation::Read(rd_buffer), Operation::Write(wr_buffer)]
519 | [Operation::Write(wr_buffer), Operation::Read(rd_buffer)] => {
520 self.check_rx(rd_buffer.len())?;
521 self.check_tx(wr_buffer.len())?;
522 }
523 [Operation::Read(buffer)] => {
524 self.check_rx(buffer.len())?;
525 }
526 [Operation::Write(buffer), ..] => {
527 self.check_tx(buffer.len())?;
528 }
529 _ => unreachable!(),
530 }
531 Ok(())
532 }
533
534 pub fn blocking_transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
547 let mut last_op = None;
548 while !operations.is_empty() {
549 let ops = self.setup_operations(address, operations, last_op, false)?;
550 let (in_progress, rest) = operations.split_at_mut(ops);
551 self.blocking_wait();
552 self.check_operations(in_progress)?;
553 last_op = in_progress.last();
554 operations = rest;
555 }
556 Ok(())
557 }
558
559 #[cfg(feature = "time")]
563 pub fn blocking_transaction_timeout(
564 &mut self,
565 address: u8,
566 mut operations: &mut [Operation<'_>],
567 timeout: Duration,
568 ) -> Result<(), Error> {
569 let mut last_op = None;
570 while !operations.is_empty() {
571 let ops = self.setup_operations(address, operations, last_op, false)?;
572 let (in_progress, rest) = operations.split_at_mut(ops);
573 self.blocking_wait_timeout(timeout)?;
574 self.check_operations(in_progress)?;
575 last_op = in_progress.last();
576 operations = rest;
577 }
578 Ok(())
579 }
580
581 pub async fn transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
592 let mut last_op = None;
593 while !operations.is_empty() {
594 let ops = self.setup_operations(address, operations, last_op, true)?;
595 let (in_progress, rest) = operations.split_at_mut(ops);
596 self.async_wait().await?;
597 self.check_operations(in_progress)?;
598 last_op = in_progress.last();
599 operations = rest;
600 }
601 Ok(())
602 }
603
604 pub fn blocking_write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
611 self.blocking_transaction(address, &mut [Operation::Write(buffer)])
612 }
613
614 pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
619 self.blocking_transaction(address, &mut [Operation::Read(buffer)])
620 }
621
622 pub fn blocking_write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
628 self.blocking_transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
629 }
630
631 #[cfg(feature = "time")]
637 pub fn blocking_write_timeout(&mut self, address: u8, buffer: &[u8], timeout: Duration) -> Result<(), Error> {
638 self.blocking_transaction_timeout(address, &mut [Operation::Write(buffer)], timeout)
639 }
640
641 #[cfg(feature = "time")]
646 pub fn blocking_read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> {
647 self.blocking_transaction_timeout(address, &mut [Operation::Read(buffer)], timeout)
648 }
649
650 #[cfg(feature = "time")]
656 pub fn blocking_write_read_timeout(
657 &mut self,
658 address: u8,
659 wr_buffer: &[u8],
660 rd_buffer: &mut [u8],
661 timeout: Duration,
662 ) -> Result<(), Error> {
663 self.blocking_transaction_timeout(
664 address,
665 &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)],
666 timeout,
667 )
668 }
669
670 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
677 self.transaction(address, &mut [Operation::Read(buffer)]).await
678 }
679
680 pub async fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
685 self.transaction(address, &mut [Operation::Write(buffer)]).await
686 }
687
688 pub async fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
694 self.transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
695 .await
696 }
697}
698
699impl<'a, T: Instance> Drop for Twim<'a, T> {
700 fn drop(&mut self) {
701 trace!("twim drop");
702
703 let r = T::regs();
707 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
708
709 gpio::deconfigure_pin(r.psel().sda().read());
710 gpio::deconfigure_pin(r.psel().scl().read());
711
712 trace!("twim drop: done");
713 }
714}
715
716pub(crate) struct State {
717 end_waker: AtomicWaker,
718}
719
720impl State {
721 pub(crate) const fn new() -> Self {
722 Self {
723 end_waker: AtomicWaker::new(),
724 }
725 }
726}
727
728pub(crate) trait SealedInstance {
729 fn regs() -> pac::twim::Twim;
730 fn state() -> &'static State;
731}
732
733#[allow(private_bounds)]
735pub trait Instance: SealedInstance + PeripheralType + 'static {
736 type Interrupt: interrupt::typelevel::Interrupt;
738}
739
740macro_rules! impl_twim {
741 ($type:ident, $pac_type:ident, $irq:ident) => {
742 impl crate::twim::SealedInstance for peripherals::$type {
743 fn regs() -> pac::twim::Twim {
744 pac::$pac_type
745 }
746 fn state() -> &'static crate::twim::State {
747 static STATE: crate::twim::State = crate::twim::State::new();
748 &STATE
749 }
750 }
751 impl crate::twim::Instance for peripherals::$type {
752 type Interrupt = crate::interrupt::typelevel::$irq;
753 }
754 };
755}
756
757mod eh02 {
760 use super::*;
761
762 impl<'a, T: Instance> embedded_hal_02::blocking::i2c::Write for Twim<'a, T> {
763 type Error = Error;
764
765 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
766 self.blocking_write(addr, bytes)
767 }
768 }
769
770 impl<'a, T: Instance> embedded_hal_02::blocking::i2c::Read for Twim<'a, T> {
771 type Error = Error;
772
773 fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> {
774 self.blocking_read(addr, bytes)
775 }
776 }
777
778 impl<'a, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a, T> {
779 type Error = Error;
780
781 fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> {
782 self.blocking_write_read(addr, bytes, buffer)
783 }
784 }
785}
786
787impl embedded_hal_1::i2c::Error for Error {
788 fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
789 match *self {
790 Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
791 Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
792 Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other,
793 Self::Receive => embedded_hal_1::i2c::ErrorKind::Other,
794 Self::RAMBufferTooSmall => embedded_hal_1::i2c::ErrorKind::Other,
795 Self::AddressNack => {
796 embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
797 }
798 Self::DataNack => {
799 embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Data)
800 }
801 Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
802 Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
803 }
804 }
805}
806
807impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> {
808 type Error = Error;
809}
810
811impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> {
812 fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
813 self.blocking_transaction(address, operations)
814 }
815}
816
817impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
818 async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
819 self.transaction(address, operations).await
820 }
821}
822
823impl<'d, T: Instance> SetConfig for Twim<'d, T> {
824 type Config = Config;
825 type ConfigError = ();
826 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
827 let r = T::regs();
828 r.frequency().write(|w| w.set_frequency(config.frequency));
829
830 Ok(())
831 }
832}