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_hal_internal::{Peri, PeripheralType};
12use embassy_sync::waitqueue::AtomicWaker;
13#[cfg(feature = "time")]
14use embassy_time::{Duration, Instant};
15
16use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
17use crate::gpio::Pin as GpioPin;
18use crate::interrupt::typelevel::Interrupt;
19use crate::pac::gpio::vals as gpiovals;
20use crate::pac::twis::vals;
21use crate::util::slice_in_ram_or;
22use crate::{gpio, interrupt, pac};
23
24#[non_exhaustive]
26pub struct Config {
27 pub address0: u8,
29
30 pub address1: Option<u8>,
32
33 pub orc: u8,
38
39 pub sda_high_drive: bool,
41
42 pub sda_pullup: bool,
47
48 pub scl_high_drive: bool,
50
51 pub scl_pullup: bool,
56}
57
58impl Default for Config {
59 fn default() -> Self {
60 Self {
61 address0: 0x55,
62 address1: None,
63 orc: 0x00,
64 scl_high_drive: false,
65 sda_pullup: false,
66 sda_high_drive: false,
67 scl_pullup: false,
68 }
69 }
70}
71
72#[derive(Debug, Copy, Clone, Eq, PartialEq)]
73#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74enum Status {
75 Read,
76 Write,
77}
78
79#[derive(Debug, Copy, Clone, Eq, PartialEq)]
81#[cfg_attr(feature = "defmt", derive(defmt::Format))]
82#[non_exhaustive]
83pub enum Error {
84 TxBufferTooLong,
86 RxBufferTooLong,
88 DataNack,
90 Bus,
92 BufferNotInRAM,
94 Overflow,
96 OverRead,
98 Timeout,
100}
101
102#[derive(Debug, Copy, Clone, Eq, PartialEq)]
104#[cfg_attr(feature = "defmt", derive(defmt::Format))]
105pub enum Command {
106 Read,
108 WriteRead(usize),
110 Write(usize),
112}
113
114pub struct InterruptHandler<T: Instance> {
116 _phantom: PhantomData<T>,
117}
118
119impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
120 unsafe fn on_interrupt() {
121 let r = T::regs();
122 let s = T::state();
123
124 if r.events_read().read() != 0 || r.events_write().read() != 0 {
125 s.waker.wake();
126 r.intenclr().write(|w| {
127 w.set_read(true);
128 w.set_write(true);
129 });
130 }
131 if r.events_stopped().read() != 0 {
132 s.waker.wake();
133 r.intenclr().write(|w| w.set_stopped(true));
134 }
135 if r.events_error().read() != 0 {
136 s.waker.wake();
137 r.intenclr().write(|w| w.set_error(true));
138 }
139 }
140}
141
142pub struct Twis<'d> {
144 r: pac::twis::Twis,
145 state: &'static State,
146 _p: PhantomData<&'d ()>,
147}
148
149impl<'d> Twis<'d> {
150 pub fn new<T: Instance>(
152 _twis: Peri<'d, T>,
153 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
154 sda: Peri<'d, impl GpioPin>,
155 scl: Peri<'d, impl GpioPin>,
156 config: Config,
157 ) -> Self {
158 let r = T::regs();
159
160 sda.conf().write(|w| {
162 w.set_dir(gpiovals::Dir::INPUT);
163 w.set_input(gpiovals::Input::CONNECT);
164 w.set_drive(match config.sda_high_drive {
165 true => gpiovals::Drive::H0D1,
166 false => gpiovals::Drive::S0D1,
167 });
168 if config.sda_pullup {
169 w.set_pull(gpiovals::Pull::PULLUP);
170 }
171 });
172 scl.conf().write(|w| {
173 w.set_dir(gpiovals::Dir::INPUT);
174 w.set_input(gpiovals::Input::CONNECT);
175 w.set_drive(match config.scl_high_drive {
176 true => gpiovals::Drive::H0D1,
177 false => gpiovals::Drive::S0D1,
178 });
179 if config.sda_pullup {
180 w.set_pull(gpiovals::Pull::PULLUP);
181 }
182 });
183
184 r.psel().sda().write_value(sda.psel_bits());
186 r.psel().scl().write_value(scl.psel_bits());
187
188 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
190
191 r.intenclr().write(|w| w.0 = 0xFFFF_FFFF);
193
194 r.address(0).write(|w| w.set_address(config.address0));
196 r.config().write(|w| w.set_address0(true));
197 if let Some(address1) = config.address1 {
198 r.address(1).write(|w| w.set_address(address1));
199 r.config().modify(|w| w.set_address1(true));
200 }
201
202 r.orc().write(|w| w.set_orc(config.orc));
204
205 r.shorts().write(|w| w.set_read_suspend(true));
207
208 T::Interrupt::unpend();
209 unsafe { T::Interrupt::enable() };
210
211 Self {
212 r: T::regs(),
213 state: T::state(),
214 _p: PhantomData,
215 }
216 }
217
218 unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
220 slice_in_ram_or(buffer, Error::BufferNotInRAM)?;
221
222 if buffer.len() > EASY_DMA_SIZE {
223 return Err(Error::TxBufferTooLong);
224 }
225
226 let r = self.r;
227
228 r.txd().ptr().write_value(buffer.as_ptr() as u32);
232 r.txd().maxcnt().write(|w|
233 w.set_maxcnt(buffer.len() as _));
240
241 Ok(())
242 }
243
244 unsafe fn set_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
246 if buffer.len() > EASY_DMA_SIZE {
250 return Err(Error::RxBufferTooLong);
251 }
252
253 let r = self.r;
254
255 r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32);
259 r.rxd().maxcnt().write(|w|
260 w.set_maxcnt(buffer.len() as _));
270
271 Ok(())
272 }
273
274 fn clear_errorsrc(&mut self) {
275 let r = self.r;
276 r.errorsrc().write(|w| {
277 w.set_overflow(true);
278 w.set_overread(true);
279 w.set_dnack(true);
280 });
281 }
282
283 pub fn address_match(&self) -> u8 {
285 let r = self.r;
286 r.address(r.match_().read().0 as usize).read().address()
287 }
288
289 pub fn address_match_index(&self) -> usize {
291 self.r.match_().read().0 as _
292 }
293
294 fn blocking_listen_wait(&mut self) -> Result<Status, Error> {
296 let r = self.r;
297 loop {
298 if r.events_error().read() != 0 {
299 r.events_error().write_value(0);
300 r.tasks_stop().write_value(1);
301 while r.events_stopped().read() == 0 {}
302 return Err(Error::Overflow);
303 }
304 if r.events_stopped().read() != 0 {
305 r.events_stopped().write_value(0);
306 return Err(Error::Bus);
307 }
308 if r.events_read().read() != 0 {
309 r.events_read().write_value(0);
310 return Ok(Status::Read);
311 }
312 if r.events_write().read() != 0 {
313 r.events_write().write_value(0);
314 return Ok(Status::Write);
315 }
316 }
317 }
318
319 fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> {
321 let r = self.r;
322 loop {
323 if r.events_error().read() != 0 {
325 r.events_error().write_value(0);
326 r.tasks_stop().write_value(1);
327 return Err(Error::Overflow);
328 } else if r.events_stopped().read() != 0 {
329 r.events_stopped().write_value(0);
330 return match status {
331 Status::Read => Ok(Command::Read),
332 Status::Write => {
333 let n = r.rxd().amount().read().0 as usize;
334 Ok(Command::Write(n))
335 }
336 };
337 } else if r.events_read().read() != 0 {
338 r.events_read().write_value(0);
339 let n = r.rxd().amount().read().0 as usize;
340 return Ok(Command::WriteRead(n));
341 }
342 }
343 }
344
345 fn blocking_wait(&mut self) -> Result<usize, Error> {
347 let r = self.r;
348 loop {
349 if r.events_error().read() != 0 {
351 r.events_error().write_value(0);
352 r.tasks_stop().write_value(1);
353 let errorsrc = r.errorsrc().read();
354 if errorsrc.overread() {
355 return Err(Error::OverRead);
356 } else if errorsrc.dnack() {
357 return Err(Error::DataNack);
358 } else {
359 return Err(Error::Bus);
360 }
361 } else if r.events_stopped().read() != 0 {
362 r.events_stopped().write_value(0);
363 let n = r.txd().amount().read().0 as usize;
364 return Ok(n);
365 }
366 }
367 }
368
369 #[cfg(feature = "time")]
371 fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<usize, Error> {
372 let r = self.r;
373 let deadline = Instant::now() + timeout;
374 loop {
375 if r.events_error().read() != 0 {
377 r.events_error().write_value(0);
378 r.tasks_stop().write_value(1);
379 let errorsrc = r.errorsrc().read();
380 if errorsrc.overread() {
381 return Err(Error::OverRead);
382 } else if errorsrc.dnack() {
383 return Err(Error::DataNack);
384 } else {
385 return Err(Error::Bus);
386 }
387 } else if r.events_stopped().read() != 0 {
388 r.events_stopped().write_value(0);
389 let n = r.txd().amount().read().0 as usize;
390 return Ok(n);
391 } else if Instant::now() > deadline {
392 r.tasks_stop().write_value(1);
393 return Err(Error::Timeout);
394 }
395 }
396 }
397
398 #[cfg(feature = "time")]
400 fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> {
401 let r = self.r;
402 let deadline = Instant::now() + timeout;
403 loop {
404 if r.events_error().read() != 0 {
405 r.events_error().write_value(0);
406 r.tasks_stop().write_value(1);
407 while r.events_stopped().read() == 0 {}
408 return Err(Error::Overflow);
409 }
410 if r.events_stopped().read() != 0 {
411 r.events_stopped().write_value(0);
412 return Err(Error::Bus);
413 }
414 if r.events_read().read() != 0 {
415 r.events_read().write_value(0);
416 return Ok(Status::Read);
417 }
418 if r.events_write().read() != 0 {
419 r.events_write().write_value(0);
420 return Ok(Status::Write);
421 }
422 if Instant::now() > deadline {
423 r.tasks_stop().write_value(1);
424 return Err(Error::Timeout);
425 }
426 }
427 }
428
429 #[cfg(feature = "time")]
431 fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> {
432 let r = self.r;
433 let deadline = Instant::now() + timeout;
434 loop {
435 if r.events_error().read() != 0 {
437 r.events_error().write_value(0);
438 r.tasks_stop().write_value(1);
439 return Err(Error::Overflow);
440 } else if r.events_stopped().read() != 0 {
441 r.events_stopped().write_value(0);
442 return match status {
443 Status::Read => Ok(Command::Read),
444 Status::Write => {
445 let n = r.rxd().amount().read().0 as usize;
446 Ok(Command::Write(n))
447 }
448 };
449 } else if r.events_read().read() != 0 {
450 r.events_read().write_value(0);
451 let n = r.rxd().amount().read().0 as usize;
452 return Ok(Command::WriteRead(n));
453 } else if Instant::now() > deadline {
454 r.tasks_stop().write_value(1);
455 return Err(Error::Timeout);
456 }
457 }
458 }
459
460 fn async_wait(&mut self) -> impl Future<Output = Result<usize, Error>> {
462 let r = self.r;
463 let s = self.state;
464 poll_fn(move |cx| {
465 s.waker.register(cx.waker());
466
467 if r.events_error().read() != 0 {
469 r.events_error().write_value(0);
470 r.tasks_stop().write_value(1);
471 let errorsrc = r.errorsrc().read();
472 if errorsrc.overread() {
473 return Poll::Ready(Err(Error::OverRead));
474 } else if errorsrc.dnack() {
475 return Poll::Ready(Err(Error::DataNack));
476 } else {
477 return Poll::Ready(Err(Error::Bus));
478 }
479 } else if r.events_stopped().read() != 0 {
480 r.events_stopped().write_value(0);
481 let n = r.txd().amount().read().0 as usize;
482 return Poll::Ready(Ok(n));
483 }
484
485 Poll::Pending
486 })
487 }
488
489 fn async_listen_wait(&mut self) -> impl Future<Output = Result<Status, Error>> {
491 let r = self.r;
492 let s = self.state;
493 poll_fn(move |cx| {
494 s.waker.register(cx.waker());
495
496 if r.events_error().read() != 0 {
498 r.events_error().write_value(0);
499 r.tasks_stop().write_value(1);
500 return Poll::Ready(Err(Error::Overflow));
501 } else if r.events_read().read() != 0 {
502 r.events_read().write_value(0);
503 return Poll::Ready(Ok(Status::Read));
504 } else if r.events_write().read() != 0 {
505 r.events_write().write_value(0);
506 return Poll::Ready(Ok(Status::Write));
507 } else if r.events_stopped().read() != 0 {
508 r.events_stopped().write_value(0);
509 return Poll::Ready(Err(Error::Bus));
510 }
511 Poll::Pending
512 })
513 }
514
515 fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> {
517 let r = self.r;
518 let s = self.state;
519 poll_fn(move |cx| {
520 s.waker.register(cx.waker());
521
522 if r.events_error().read() != 0 {
524 r.events_error().write_value(0);
525 r.tasks_stop().write_value(1);
526 return Poll::Ready(Err(Error::Overflow));
527 } else if r.events_stopped().read() != 0 {
528 r.events_stopped().write_value(0);
529 return match status {
530 Status::Read => Poll::Ready(Ok(Command::Read)),
531 Status::Write => {
532 let n = r.rxd().amount().read().0 as usize;
533 Poll::Ready(Ok(Command::Write(n)))
534 }
535 };
536 } else if r.events_read().read() != 0 {
537 r.events_read().write_value(0);
538 let n = r.rxd().amount().read().0 as usize;
539 return Poll::Ready(Ok(Command::WriteRead(n)));
540 }
541 Poll::Pending
542 })
543 }
544
545 fn setup_respond_from_ram(&mut self, buffer: &[u8], inten: bool) -> Result<(), Error> {
546 let r = self.r;
547
548 compiler_fence(SeqCst);
549
550 unsafe { self.set_tx_buffer(buffer)? };
552
553 r.events_stopped().write_value(0);
555 r.events_error().write_value(0);
556 self.clear_errorsrc();
557
558 if inten {
559 r.intenset().write(|w| {
560 w.set_stopped(true);
561 w.set_error(true);
562 });
563 } else {
564 r.intenclr().write(|w| {
565 w.set_stopped(true);
566 w.set_error(true);
567 });
568 }
569
570 r.tasks_preparetx().write_value(1);
572 r.tasks_resume().write_value(1);
573 Ok(())
574 }
575
576 fn setup_respond(&mut self, wr_buffer: &[u8], inten: bool) -> Result<(), Error> {
577 match self.setup_respond_from_ram(wr_buffer, inten) {
578 Ok(_) => Ok(()),
579 Err(Error::BufferNotInRAM) => {
580 trace!("Copying TWIS tx buffer into RAM for DMA");
581 let tx_ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()];
582 tx_ram_buf.copy_from_slice(wr_buffer);
583 self.setup_respond_from_ram(tx_ram_buf, inten)
584 }
585 Err(error) => Err(error),
586 }
587 }
588
589 fn setup_listen(&mut self, buffer: &mut [u8], inten: bool) -> Result<(), Error> {
590 let r = self.r;
591 compiler_fence(SeqCst);
592
593 unsafe { self.set_rx_buffer(buffer)? };
595
596 r.events_read().write_value(0);
598 r.events_write().write_value(0);
599 r.events_stopped().write_value(0);
600 r.events_error().write_value(0);
601 self.clear_errorsrc();
602
603 if inten {
604 r.intenset().write(|w| {
605 w.set_stopped(true);
606 w.set_error(true);
607 w.set_read(true);
608 w.set_write(true);
609 });
610 } else {
611 r.intenclr().write(|w| {
612 w.set_stopped(true);
613 w.set_error(true);
614 w.set_read(true);
615 w.set_write(true);
616 });
617 }
618
619 r.tasks_preparerx().write_value(1);
621
622 Ok(())
623 }
624
625 fn setup_listen_end(&mut self, inten: bool) -> Result<(), Error> {
626 let r = self.r;
627 compiler_fence(SeqCst);
628
629 r.events_read().write_value(0);
631 r.events_write().write_value(0);
632 r.events_stopped().write_value(0);
633 r.events_error().write_value(0);
634 self.clear_errorsrc();
635
636 if inten {
637 r.intenset().write(|w| {
638 w.set_stopped(true);
639 w.set_error(true);
640 w.set_read(true);
641 });
642 } else {
643 r.intenclr().write(|w| {
644 w.set_stopped(true);
645 w.set_error(true);
646 w.set_read(true);
647 });
648 }
649
650 Ok(())
651 }
652
653 pub fn blocking_listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
659 self.setup_listen(buffer, false)?;
660 let status = self.blocking_listen_wait()?;
661 if status == Status::Write {
662 self.setup_listen_end(false)?;
663 let command = self.blocking_listen_wait_end(status)?;
664 return Ok(command);
665 }
666 Ok(Command::Read)
667 }
668
669 pub fn blocking_respond_to_read(&mut self, buffer: &[u8]) -> Result<usize, Error> {
674 self.setup_respond(buffer, false)?;
675 self.blocking_wait()
676 }
677
678 pub fn blocking_respond_to_read_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> {
681 self.setup_respond_from_ram(buffer, false)?;
682 self.blocking_wait()
683 }
684
685 #[cfg(feature = "time")]
693 pub fn blocking_listen_timeout(&mut self, buffer: &mut [u8], timeout: Duration) -> Result<Command, Error> {
694 self.setup_listen(buffer, false)?;
695 let status = self.blocking_listen_wait_timeout(timeout)?;
696 if status == Status::Write {
697 self.setup_listen_end(false)?;
698 let command = self.blocking_listen_wait_end_timeout(status, timeout)?;
699 return Ok(command);
700 }
701 Ok(Command::Read)
702 }
703
704 #[cfg(feature = "time")]
708 pub fn blocking_respond_to_read_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<usize, Error> {
709 self.setup_respond(buffer, false)?;
710 self.blocking_wait_timeout(timeout)
711 }
712
713 #[cfg(feature = "time")]
716 pub fn blocking_respond_to_read_from_ram_timeout(
717 &mut self,
718 buffer: &[u8],
719 timeout: Duration,
720 ) -> Result<usize, Error> {
721 self.setup_respond_from_ram(buffer, false)?;
722 self.blocking_wait_timeout(timeout)
723 }
724
725 pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
733 self.setup_listen(buffer, true)?;
734 let status = self.async_listen_wait().await?;
735 if status == Status::Write {
736 self.setup_listen_end(true)?;
737 let command = self.async_listen_wait_end(status).await?;
738 return Ok(command);
739 }
740 Ok(Command::Read)
741 }
742
743 pub async fn respond_to_read(&mut self, buffer: &[u8]) -> Result<usize, Error> {
748 self.setup_respond(buffer, true)?;
749 self.async_wait().await
750 }
751
752 pub async fn respond_to_read_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> {
754 self.setup_respond_from_ram(buffer, true)?;
755 self.async_wait().await
756 }
757}
758
759impl<'a> Drop for Twis<'a> {
760 fn drop(&mut self) {
761 trace!("twis drop");
762
763 let r = self.r;
767 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
768
769 gpio::deconfigure_pin(r.psel().sda().read());
770 gpio::deconfigure_pin(r.psel().scl().read());
771
772 trace!("twis drop: done");
773 }
774}
775
776pub(crate) struct State {
777 waker: AtomicWaker,
778}
779
780impl State {
781 pub(crate) const fn new() -> Self {
782 Self {
783 waker: AtomicWaker::new(),
784 }
785 }
786}
787
788pub(crate) trait SealedInstance {
789 fn regs() -> pac::twis::Twis;
790 fn state() -> &'static State;
791}
792
793#[allow(private_bounds)]
795pub trait Instance: SealedInstance + PeripheralType + 'static {
796 type Interrupt: interrupt::typelevel::Interrupt;
798}
799
800macro_rules! impl_twis {
801 ($type:ident, $pac_type:ident, $irq:ident) => {
802 impl crate::twis::SealedInstance for peripherals::$type {
803 fn regs() -> pac::twis::Twis {
804 pac::$pac_type
805 }
806 fn state() -> &'static crate::twis::State {
807 static STATE: crate::twis::State = crate::twis::State::new();
808 &STATE
809 }
810 }
811 impl crate::twis::Instance for peripherals::$type {
812 type Interrupt = crate::interrupt::typelevel::$irq;
813 }
814 };
815}