1#![macro_use]
4
5use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::mem::size_of;
8use core::ops::{Deref, DerefMut};
9use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
10use core::task::Poll;
11
12use embassy_hal_internal::drop::OnDrop;
13use embassy_hal_internal::{Peri, PeripheralType};
14use embassy_sync::waitqueue::AtomicWaker;
15
16use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
17use crate::interrupt::typelevel::Interrupt;
18use crate::pac::i2s::vals;
19use crate::util::slice_in_ram_or;
20use crate::{interrupt, pac, EASY_DMA_SIZE};
21
22pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>;
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27#[cfg_attr(feature = "defmt", derive(defmt::Format))]
28#[non_exhaustive]
29pub enum Error {
30 BufferTooLong,
32 BufferZeroLength,
34 BufferNotInRAM,
36 BufferMisaligned,
38 BufferLengthMisaligned,
40}
41
42#[derive(Clone)]
44#[non_exhaustive]
45pub struct Config {
46 pub sample_width: SampleWidth,
48 pub align: Align,
50 pub format: Format,
52 pub channels: Channels,
54}
55
56impl Default for Config {
57 fn default() -> Self {
58 Self {
59 sample_width: SampleWidth::_16bit,
60 align: Align::Left,
61 format: Format::I2S,
62 channels: Channels::Stereo,
63 }
64 }
65}
66
67#[derive(Debug, Eq, PartialEq, Clone, Copy)]
69pub struct MasterClock {
70 freq: MckFreq,
71 ratio: Ratio,
72}
73
74impl MasterClock {
75 pub fn new(freq: MckFreq, ratio: Ratio) -> Self {
77 Self { freq, ratio }
78 }
79}
80
81impl MasterClock {
82 pub fn sample_rate(&self) -> u32 {
84 self.freq.to_frequency() / self.ratio.to_divisor()
85 }
86}
87
88#[derive(Debug, Eq, PartialEq, Clone, Copy)]
90pub enum MckFreq {
91 _32MDiv8,
93 _32MDiv10,
95 _32MDiv11,
97 _32MDiv15,
99 _32MDiv16,
101 _32MDiv21,
103 _32MDiv23,
105 _32MDiv30,
107 _32MDiv31,
109 _32MDiv32,
111 _32MDiv42,
113 _32MDiv63,
115 _32MDiv125,
117}
118
119impl MckFreq {
120 const REGISTER_VALUES: &'static [vals::Mckfreq] = &[
121 vals::Mckfreq::_32MDIV8,
122 vals::Mckfreq::_32MDIV10,
123 vals::Mckfreq::_32MDIV11,
124 vals::Mckfreq::_32MDIV15,
125 vals::Mckfreq::_32MDIV16,
126 vals::Mckfreq::_32MDIV21,
127 vals::Mckfreq::_32MDIV23,
128 vals::Mckfreq::_32MDIV30,
129 vals::Mckfreq::_32MDIV31,
130 vals::Mckfreq::_32MDIV32,
131 vals::Mckfreq::_32MDIV42,
132 vals::Mckfreq::_32MDIV63,
133 vals::Mckfreq::_32MDIV125,
134 ];
135
136 const FREQUENCIES: &'static [u32] = &[
137 4000000, 3200000, 2909090, 2133333, 2000000, 1523809, 1391304, 1066666, 1032258, 1000000, 761904, 507936,
138 256000,
139 ];
140
141 pub fn to_register_value(&self) -> vals::Mckfreq {
143 Self::REGISTER_VALUES[usize::from(*self)]
144 }
145
146 pub fn to_frequency(&self) -> u32 {
148 Self::FREQUENCIES[usize::from(*self)]
149 }
150}
151
152impl From<MckFreq> for usize {
153 fn from(variant: MckFreq) -> Self {
154 variant as _
155 }
156}
157
158#[derive(Debug, Eq, PartialEq, Clone, Copy)]
163pub enum Ratio {
164 _32x,
166 _48x,
168 _64x,
170 _96x,
172 _128x,
174 _192x,
176 _256x,
178 _384x,
180 _512x,
182}
183
184impl Ratio {
185 const RATIOS: &'static [u32] = &[32, 48, 64, 96, 128, 192, 256, 384, 512];
186
187 pub fn to_register_value(&self) -> vals::Ratio {
189 vals::Ratio::from_bits(*self as u8)
190 }
191
192 pub fn to_divisor(&self) -> u32 {
194 Self::RATIOS[usize::from(*self)]
195 }
196}
197
198impl From<Ratio> for usize {
199 fn from(variant: Ratio) -> Self {
200 variant as _
201 }
202}
203
204#[derive(Clone, Copy)]
210pub enum ApproxSampleRate {
211 _11025,
213 _16000,
215 _22050,
217 _32000,
219 _44100,
221 _48000,
223}
224
225impl From<ApproxSampleRate> for MasterClock {
226 fn from(value: ApproxSampleRate) -> Self {
227 match value {
228 ApproxSampleRate::_11025 => MasterClock::new(MckFreq::_32MDiv15, Ratio::_192x),
230 ApproxSampleRate::_16000 => MasterClock::new(MckFreq::_32MDiv21, Ratio::_96x),
232 ApproxSampleRate::_22050 => MasterClock::new(MckFreq::_32MDiv15, Ratio::_96x),
234 ApproxSampleRate::_32000 => MasterClock::new(MckFreq::_32MDiv21, Ratio::_48x),
236 ApproxSampleRate::_44100 => MasterClock::new(MckFreq::_32MDiv15, Ratio::_48x),
238 ApproxSampleRate::_48000 => MasterClock::new(MckFreq::_32MDiv21, Ratio::_32x),
240 }
241 }
242}
243
244impl ApproxSampleRate {
245 pub fn sample_rate(&self) -> u32 {
247 MasterClock::from(*self).sample_rate()
248 }
249}
250
251#[derive(Clone, Copy)]
257pub enum ExactSampleRate {
258 _8000,
260 _10582,
262 _12500,
264 _15625,
266 _15873,
268 _25000,
270 _31250,
272 _50000,
274 _62500,
276 _100000,
278 _125000,
280}
281
282impl ExactSampleRate {
283 pub fn sample_rate(&self) -> u32 {
285 MasterClock::from(*self).sample_rate()
286 }
287}
288
289impl From<ExactSampleRate> for MasterClock {
290 fn from(value: ExactSampleRate) -> Self {
291 match value {
292 ExactSampleRate::_8000 => MasterClock::new(MckFreq::_32MDiv125, Ratio::_32x),
293 ExactSampleRate::_10582 => MasterClock::new(MckFreq::_32MDiv63, Ratio::_48x),
294 ExactSampleRate::_12500 => MasterClock::new(MckFreq::_32MDiv10, Ratio::_256x),
295 ExactSampleRate::_15625 => MasterClock::new(MckFreq::_32MDiv32, Ratio::_64x),
296 ExactSampleRate::_15873 => MasterClock::new(MckFreq::_32MDiv63, Ratio::_32x),
297 ExactSampleRate::_25000 => MasterClock::new(MckFreq::_32MDiv10, Ratio::_128x),
298 ExactSampleRate::_31250 => MasterClock::new(MckFreq::_32MDiv32, Ratio::_32x),
299 ExactSampleRate::_50000 => MasterClock::new(MckFreq::_32MDiv10, Ratio::_64x),
300 ExactSampleRate::_62500 => MasterClock::new(MckFreq::_32MDiv16, Ratio::_32x),
301 ExactSampleRate::_100000 => MasterClock::new(MckFreq::_32MDiv10, Ratio::_32x),
302 ExactSampleRate::_125000 => MasterClock::new(MckFreq::_32MDiv8, Ratio::_32x),
303 }
304 }
305}
306
307#[derive(Debug, Eq, PartialEq, Clone, Copy)]
309pub enum SampleWidth {
310 _8bit,
312 _16bit,
314 _24bit,
316}
317
318impl From<SampleWidth> for vals::Swidth {
319 fn from(variant: SampleWidth) -> Self {
320 vals::Swidth::from_bits(variant as u8)
321 }
322}
323
324#[derive(Debug, Eq, PartialEq, Clone, Copy)]
326pub enum Align {
327 Left,
329 Right,
331}
332
333impl From<Align> for vals::Align {
334 fn from(variant: Align) -> Self {
335 match variant {
336 Align::Left => vals::Align::LEFT,
337 Align::Right => vals::Align::RIGHT,
338 }
339 }
340}
341
342#[derive(Debug, Eq, PartialEq, Clone, Copy)]
344pub enum Format {
345 I2S,
347 Aligned,
349}
350
351impl From<Format> for vals::Format {
352 fn from(variant: Format) -> Self {
353 match variant {
354 Format::I2S => vals::Format::I2S,
355 Format::Aligned => vals::Format::ALIGNED,
356 }
357 }
358}
359
360#[derive(Debug, Eq, PartialEq, Clone, Copy)]
362pub enum Channels {
363 Stereo,
365 MonoLeft,
367 MonoRight,
369}
370
371impl From<Channels> for vals::Channels {
372 fn from(variant: Channels) -> Self {
373 vals::Channels::from_bits(variant as u8)
374 }
375}
376
377pub struct InterruptHandler<T: Instance> {
379 _phantom: PhantomData<T>,
380}
381
382impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
383 unsafe fn on_interrupt() {
384 let device = Device::<T>::new();
385 let s = T::state();
386
387 if device.is_tx_ptr_updated() {
388 trace!("TX INT");
389 s.tx_waker.wake();
390 device.disable_tx_ptr_interrupt();
391 }
392
393 if device.is_rx_ptr_updated() {
394 trace!("RX INT");
395 s.rx_waker.wake();
396 device.disable_rx_ptr_interrupt();
397 }
398
399 if device.is_stopped() {
400 trace!("STOPPED INT");
401 s.stop_waker.wake();
402 device.disable_stopped_interrupt();
403 }
404 }
405}
406
407pub struct I2S<'d, T: Instance> {
409 i2s: Peri<'d, T>,
410 mck: Option<Peri<'d, AnyPin>>,
411 sck: Peri<'d, AnyPin>,
412 lrck: Peri<'d, AnyPin>,
413 sdin: Option<Peri<'d, AnyPin>>,
414 sdout: Option<Peri<'d, AnyPin>>,
415 master_clock: Option<MasterClock>,
416 config: Config,
417}
418
419impl<'d, T: Instance> I2S<'d, T> {
420 pub fn new_master(
422 i2s: Peri<'d, T>,
423 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
424 mck: Peri<'d, impl GpioPin>,
425 sck: Peri<'d, impl GpioPin>,
426 lrck: Peri<'d, impl GpioPin>,
427 master_clock: MasterClock,
428 config: Config,
429 ) -> Self {
430 Self {
431 i2s,
432 mck: Some(mck.into()),
433 sck: sck.into(),
434 lrck: lrck.into(),
435 sdin: None,
436 sdout: None,
437 master_clock: Some(master_clock),
438 config,
439 }
440 }
441
442 pub fn new_slave(
444 i2s: Peri<'d, T>,
445 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
446 sck: Peri<'d, impl GpioPin>,
447 lrck: Peri<'d, impl GpioPin>,
448 config: Config,
449 ) -> Self {
450 Self {
451 i2s,
452 mck: None,
453 sck: sck.into(),
454 lrck: lrck.into(),
455 sdin: None,
456 sdout: None,
457 master_clock: None,
458 config,
459 }
460 }
461
462 pub fn output<S: Sample, const NB: usize, const NS: usize>(
464 mut self,
465 sdout: Peri<'d, impl GpioPin>,
466 buffers: MultiBuffering<S, NB, NS>,
467 ) -> OutputStream<'d, T, S, NB, NS> {
468 self.sdout = Some(sdout.into());
469 OutputStream {
470 _p: self.build(),
471 buffers,
472 }
473 }
474
475 pub fn input<S: Sample, const NB: usize, const NS: usize>(
477 mut self,
478 sdin: Peri<'d, impl GpioPin>,
479 buffers: MultiBuffering<S, NB, NS>,
480 ) -> InputStream<'d, T, S, NB, NS> {
481 self.sdin = Some(sdin.into());
482 InputStream {
483 _p: self.build(),
484 buffers,
485 }
486 }
487
488 pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>(
490 mut self,
491 sdin: Peri<'d, impl GpioPin>,
492 sdout: Peri<'d, impl GpioPin>,
493 buffers_out: MultiBuffering<S, NB, NS>,
494 buffers_in: MultiBuffering<S, NB, NS>,
495 ) -> FullDuplexStream<'d, T, S, NB, NS> {
496 self.sdout = Some(sdout.into());
497 self.sdin = Some(sdin.into());
498
499 FullDuplexStream {
500 _p: self.build(),
501 buffers_out,
502 buffers_in,
503 }
504 }
505
506 fn build(self) -> Peri<'d, T> {
507 self.apply_config();
508 self.select_pins();
509 self.setup_interrupt();
510
511 let device = Device::<T>::new();
512 device.enable();
513
514 self.i2s
515 }
516
517 fn apply_config(&self) {
518 let c = T::regs().config();
519 match &self.master_clock {
520 Some(MasterClock { freq, ratio }) => {
521 c.mode().write(|w| w.set_mode(vals::Mode::MASTER));
522 c.mcken().write(|w| w.set_mcken(true));
523 c.mckfreq().write(|w| w.set_mckfreq(freq.to_register_value()));
524 c.ratio().write(|w| w.set_ratio(ratio.to_register_value()));
525 }
526 None => {
527 c.mode().write(|w| w.set_mode(vals::Mode::SLAVE));
528 }
529 };
530
531 c.swidth().write(|w| w.set_swidth(self.config.sample_width.into()));
532 c.align().write(|w| w.set_align(self.config.align.into()));
533 c.format().write(|w| w.set_format(self.config.format.into()));
534 c.channels().write(|w| w.set_channels(self.config.channels.into()));
535 }
536
537 fn select_pins(&self) {
538 let psel = T::regs().psel();
539 psel.mck().write_value(self.mck.psel_bits());
540 psel.sck().write_value(self.sck.psel_bits());
541 psel.lrck().write_value(self.lrck.psel_bits());
542 psel.sdin().write_value(self.sdin.psel_bits());
543 psel.sdout().write_value(self.sdout.psel_bits());
544 }
545
546 fn setup_interrupt(&self) {
547 T::Interrupt::unpend();
548 unsafe { T::Interrupt::enable() };
549
550 let device = Device::<T>::new();
551 device.disable_tx_ptr_interrupt();
552 device.disable_rx_ptr_interrupt();
553 device.disable_stopped_interrupt();
554
555 device.reset_tx_ptr_event();
556 device.reset_rx_ptr_event();
557 device.reset_stopped_event();
558
559 device.enable_tx_ptr_interrupt();
560 device.enable_rx_ptr_interrupt();
561 device.enable_stopped_interrupt();
562 }
563
564 async fn stop() {
565 compiler_fence(Ordering::SeqCst);
566
567 let device = Device::<T>::new();
568 device.stop();
569
570 T::state().started.store(false, Ordering::Relaxed);
571
572 poll_fn(|cx| {
573 T::state().stop_waker.register(cx.waker());
574
575 if device.is_stopped() {
576 trace!("STOP: Ready");
577 device.reset_stopped_event();
578 Poll::Ready(())
579 } else {
580 trace!("STOP: Pending");
581 Poll::Pending
582 }
583 })
584 .await;
585
586 device.disable();
587 }
588
589 async fn send_from_ram<S>(buffer_ptr: *const [S]) -> Result<(), Error>
590 where
591 S: Sample,
592 {
593 trace!("SEND: {}", buffer_ptr as *const S as u32);
594
595 slice_in_ram_or(buffer_ptr, Error::BufferNotInRAM)?;
596
597 compiler_fence(Ordering::SeqCst);
598
599 let device = Device::<T>::new();
600
601 device.update_tx(buffer_ptr)?;
602
603 Self::wait_tx_ptr_update().await;
604
605 compiler_fence(Ordering::SeqCst);
606
607 Ok(())
608 }
609
610 async fn wait_tx_ptr_update() {
611 let drop = OnDrop::new(move || {
612 trace!("TX DROP: Stopping");
613
614 let device = Device::<T>::new();
615 device.disable_tx_ptr_interrupt();
616 device.reset_tx_ptr_event();
617 device.disable_tx();
618
619 while !device.is_tx_ptr_updated() {}
621
622 trace!("TX DROP: Stopped");
623 });
624
625 poll_fn(|cx| {
626 T::state().tx_waker.register(cx.waker());
627
628 let device = Device::<T>::new();
629 if device.is_tx_ptr_updated() {
630 trace!("TX POLL: Ready");
631 device.reset_tx_ptr_event();
632 device.enable_tx_ptr_interrupt();
633 Poll::Ready(())
634 } else {
635 trace!("TX POLL: Pending");
636 Poll::Pending
637 }
638 })
639 .await;
640
641 drop.defuse();
642 }
643
644 async fn receive_from_ram<S>(buffer_ptr: *mut [S]) -> Result<(), Error>
645 where
646 S: Sample,
647 {
648 trace!("RECEIVE: {}", buffer_ptr as *const S as u32);
649
650 compiler_fence(Ordering::SeqCst);
654
655 let device = Device::<T>::new();
656
657 device.update_rx(buffer_ptr)?;
658
659 Self::wait_rx_ptr_update().await;
660
661 compiler_fence(Ordering::SeqCst);
662
663 Ok(())
664 }
665
666 async fn wait_rx_ptr_update() {
667 let drop = OnDrop::new(move || {
668 trace!("RX DROP: Stopping");
669
670 let device = Device::<T>::new();
671 device.disable_rx_ptr_interrupt();
672 device.reset_rx_ptr_event();
673 device.disable_rx();
674
675 while !device.is_rx_ptr_updated() {}
677
678 trace!("RX DROP: Stopped");
679 });
680
681 poll_fn(|cx| {
682 T::state().rx_waker.register(cx.waker());
683
684 let device = Device::<T>::new();
685 if device.is_rx_ptr_updated() {
686 trace!("RX POLL: Ready");
687 device.reset_rx_ptr_event();
688 device.enable_rx_ptr_interrupt();
689 Poll::Ready(())
690 } else {
691 trace!("RX POLL: Pending");
692 Poll::Pending
693 }
694 })
695 .await;
696
697 drop.defuse();
698 }
699}
700
701pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
703 _p: Peri<'d, T>,
704 buffers: MultiBuffering<S, NB, NS>,
705}
706
707impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream<'d, T, S, NB, NS> {
708 pub fn buffer(&mut self) -> &mut [S] {
710 self.buffers.get_mut()
711 }
712
713 pub async fn start(&mut self) -> Result<(), Error>
715 where
716 S: Sample,
717 {
718 let device = Device::<T>::new();
719
720 let s = T::state();
721 if s.started.load(Ordering::Relaxed) {
722 self.stop().await;
723 }
724
725 device.enable();
726 device.enable_tx();
727
728 device.update_tx(self.buffers.switch())?;
729
730 s.started.store(true, Ordering::Relaxed);
731
732 device.start();
733
734 I2S::<T>::wait_tx_ptr_update().await;
735
736 Ok(())
737 }
738
739 #[inline(always)]
741 pub async fn stop(&self) {
742 I2S::<T>::stop().await
743 }
744
745 pub async fn send(&mut self) -> Result<(), Error>
748 where
749 S: Sample,
750 {
751 I2S::<T>::send_from_ram(self.buffers.switch()).await
752 }
753}
754
755pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
757 _p: Peri<'d, T>,
758 buffers: MultiBuffering<S, NB, NS>,
759}
760
761impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<'d, T, S, NB, NS> {
762 pub fn buffer(&mut self) -> &mut [S] {
764 self.buffers.get_mut()
765 }
766
767 pub async fn start(&mut self) -> Result<(), Error>
769 where
770 S: Sample,
771 {
772 let device = Device::<T>::new();
773
774 let s = T::state();
775 if s.started.load(Ordering::Relaxed) {
776 self.stop().await;
777 }
778
779 device.enable();
780 device.enable_rx();
781
782 device.update_rx(self.buffers.switch())?;
783
784 s.started.store(true, Ordering::Relaxed);
785
786 device.start();
787
788 I2S::<T>::wait_rx_ptr_update().await;
789
790 Ok(())
791 }
792
793 #[inline(always)]
795 pub async fn stop(&self) {
796 I2S::<T>::stop().await
797 }
798
799 #[allow(unused_mut)]
802 pub async fn receive(&mut self) -> Result<(), Error>
803 where
804 S: Sample,
805 {
806 I2S::<T>::receive_from_ram(self.buffers.switch_mut()).await
807 }
808}
809
810pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
812 _p: Peri<'d, T>,
813 buffers_out: MultiBuffering<S, NB, NS>,
814 buffers_in: MultiBuffering<S, NB, NS>,
815}
816
817impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStream<'d, T, S, NB, NS> {
818 pub fn buffers(&mut self) -> (&mut [S], &[S]) {
820 (self.buffers_out.get_mut(), self.buffers_in.get())
821 }
822
823 pub async fn start(&mut self) -> Result<(), Error>
825 where
826 S: Sample,
827 {
828 let device = Device::<T>::new();
829
830 let s = T::state();
831 if s.started.load(Ordering::Relaxed) {
832 self.stop().await;
833 }
834
835 device.enable();
836 device.enable_tx();
837 device.enable_rx();
838
839 device.update_tx(self.buffers_out.switch())?;
840 device.update_rx(self.buffers_in.switch_mut())?;
841
842 s.started.store(true, Ordering::Relaxed);
843
844 device.start();
845
846 I2S::<T>::wait_tx_ptr_update().await;
847 I2S::<T>::wait_rx_ptr_update().await;
848
849 Ok(())
850 }
851
852 #[inline(always)]
854 pub async fn stop(&self) {
855 I2S::<T>::stop().await
856 }
857
858 pub async fn send_and_receive(&mut self) -> Result<(), Error>
861 where
862 S: Sample,
863 {
864 I2S::<T>::send_from_ram(self.buffers_out.switch()).await?;
865 I2S::<T>::receive_from_ram(self.buffers_in.switch_mut()).await?;
866 Ok(())
867 }
868}
869
870struct Device<T>(pac::i2s::I2s, PhantomData<T>);
872
873impl<T: Instance> Device<T> {
874 fn new() -> Self {
875 Self(T::regs(), PhantomData)
876 }
877
878 #[inline(always)]
879 pub fn enable(&self) {
880 trace!("ENABLED");
881 self.0.enable().write(|w| w.set_enable(true));
882 }
883
884 #[inline(always)]
885 pub fn disable(&self) {
886 trace!("DISABLED");
887 self.0.enable().write(|w| w.set_enable(false));
888 }
889
890 #[inline(always)]
891 fn enable_tx(&self) {
892 trace!("TX ENABLED");
893 self.0.config().txen().write(|w| w.set_txen(true));
894 }
895
896 #[inline(always)]
897 fn disable_tx(&self) {
898 trace!("TX DISABLED");
899 self.0.config().txen().write(|w| w.set_txen(false));
900 }
901
902 #[inline(always)]
903 fn enable_rx(&self) {
904 trace!("RX ENABLED");
905 self.0.config().rxen().write(|w| w.set_rxen(true));
906 }
907
908 #[inline(always)]
909 fn disable_rx(&self) {
910 trace!("RX DISABLED");
911 self.0.config().rxen().write(|w| w.set_rxen(false));
912 }
913
914 #[inline(always)]
915 fn start(&self) {
916 trace!("START");
917 self.0.tasks_start().write_value(1);
918 }
919
920 #[inline(always)]
921 fn stop(&self) {
922 self.0.tasks_stop().write_value(1);
923 }
924
925 #[inline(always)]
926 fn is_stopped(&self) -> bool {
927 self.0.events_stopped().read() != 0
928 }
929
930 #[inline(always)]
931 fn reset_stopped_event(&self) {
932 trace!("STOPPED EVENT: Reset");
933 self.0.events_stopped().write_value(0);
934 }
935
936 #[inline(always)]
937 fn disable_stopped_interrupt(&self) {
938 trace!("STOPPED INTERRUPT: Disabled");
939 self.0.intenclr().write(|w| w.set_stopped(true));
940 }
941
942 #[inline(always)]
943 fn enable_stopped_interrupt(&self) {
944 trace!("STOPPED INTERRUPT: Enabled");
945 self.0.intenset().write(|w| w.set_stopped(true));
946 }
947
948 #[inline(always)]
949 fn reset_tx_ptr_event(&self) {
950 trace!("TX PTR EVENT: Reset");
951 self.0.events_txptrupd().write_value(0);
952 }
953
954 #[inline(always)]
955 fn reset_rx_ptr_event(&self) {
956 trace!("RX PTR EVENT: Reset");
957 self.0.events_rxptrupd().write_value(0);
958 }
959
960 #[inline(always)]
961 fn disable_tx_ptr_interrupt(&self) {
962 trace!("TX PTR INTERRUPT: Disabled");
963 self.0.intenclr().write(|w| w.set_txptrupd(true));
964 }
965
966 #[inline(always)]
967 fn disable_rx_ptr_interrupt(&self) {
968 trace!("RX PTR INTERRUPT: Disabled");
969 self.0.intenclr().write(|w| w.set_rxptrupd(true));
970 }
971
972 #[inline(always)]
973 fn enable_tx_ptr_interrupt(&self) {
974 trace!("TX PTR INTERRUPT: Enabled");
975 self.0.intenset().write(|w| w.set_txptrupd(true));
976 }
977
978 #[inline(always)]
979 fn enable_rx_ptr_interrupt(&self) {
980 trace!("RX PTR INTERRUPT: Enabled");
981 self.0.intenset().write(|w| w.set_rxptrupd(true));
982 }
983
984 #[inline(always)]
985 fn is_tx_ptr_updated(&self) -> bool {
986 self.0.events_txptrupd().read() != 0
987 }
988
989 #[inline(always)]
990 fn is_rx_ptr_updated(&self) -> bool {
991 self.0.events_rxptrupd().read() != 0
992 }
993
994 #[inline]
995 fn update_tx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> {
996 let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?;
997 self.0.rxtxd().maxcnt().write(|w| w.0 = maxcnt);
998 self.0.txd().ptr().write_value(ptr);
999 Ok(())
1000 }
1001
1002 #[inline]
1003 fn update_rx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> {
1004 let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?;
1005 self.0.rxtxd().maxcnt().write(|w| w.0 = maxcnt);
1006 self.0.rxd().ptr().write_value(ptr);
1007 Ok(())
1008 }
1009
1010 fn validated_dma_parts<S>(buffer_ptr: *const [S]) -> Result<(u32, u32), Error> {
1011 let ptr = buffer_ptr as *const S as u32;
1012 let bytes_len = buffer_ptr.len() * size_of::<S>();
1013 let maxcnt = (bytes_len / size_of::<u32>()) as u32;
1014
1015 trace!("PTR={}, MAXCNT={}", ptr, maxcnt);
1016
1017 if ptr % 4 != 0 {
1018 Err(Error::BufferMisaligned)
1019 } else if bytes_len % 4 != 0 {
1020 Err(Error::BufferLengthMisaligned)
1021 } else if maxcnt as usize > EASY_DMA_SIZE {
1022 Err(Error::BufferTooLong)
1023 } else {
1024 Ok((ptr, maxcnt))
1025 }
1026 }
1027}
1028
1029pub trait Sample: Sized + Copy + Default {
1031 const WIDTH: usize;
1033
1034 const SCALE: Self;
1036}
1037
1038impl Sample for i8 {
1039 const WIDTH: usize = 8;
1040 const SCALE: Self = 1 << (Self::WIDTH - 1);
1041}
1042
1043impl Sample for i16 {
1044 const WIDTH: usize = 16;
1045 const SCALE: Self = 1 << (Self::WIDTH - 1);
1046}
1047
1048impl Sample for i32 {
1049 const WIDTH: usize = 24;
1050 const SCALE: Self = 1 << (Self::WIDTH - 1);
1051}
1052
1053#[derive(Clone, Copy)]
1055#[repr(align(4))]
1056pub struct AlignedBuffer<T: Sample, const N: usize>([T; N]);
1057
1058impl<T: Sample, const N: usize> AlignedBuffer<T, N> {
1059 pub fn new(array: [T; N]) -> Self {
1061 Self(array)
1062 }
1063}
1064
1065impl<T: Sample, const N: usize> Default for AlignedBuffer<T, N> {
1066 fn default() -> Self {
1067 Self([T::default(); N])
1068 }
1069}
1070
1071impl<T: Sample, const N: usize> Deref for AlignedBuffer<T, N> {
1072 type Target = [T];
1073 fn deref(&self) -> &Self::Target {
1074 self.0.as_slice()
1075 }
1076}
1077
1078impl<T: Sample, const N: usize> DerefMut for AlignedBuffer<T, N> {
1079 fn deref_mut(&mut self) -> &mut Self::Target {
1080 self.0.as_mut_slice()
1081 }
1082}
1083
1084pub struct MultiBuffering<S: Sample, const NB: usize, const NS: usize> {
1086 buffers: [AlignedBuffer<S, NS>; NB],
1087 index: usize,
1088}
1089
1090impl<S: Sample, const NB: usize, const NS: usize> MultiBuffering<S, NB, NS> {
1091 pub fn new() -> Self {
1093 assert!(NB > 1);
1094 Self {
1095 buffers: [AlignedBuffer::<S, NS>::default(); NB],
1096 index: 0,
1097 }
1098 }
1099
1100 fn get(&self) -> &[S] {
1101 &self.buffers[self.index]
1102 }
1103
1104 fn get_mut(&mut self) -> &mut [S] {
1105 &mut self.buffers[self.index]
1106 }
1107
1108 fn switch(&mut self) -> *const [S] {
1110 let prev_index = self.index;
1111 self.index = (self.index + 1) % NB;
1112 self.buffers[prev_index].deref() as *const [S]
1113 }
1114
1115 fn switch_mut(&mut self) -> *mut [S] {
1117 let prev_index = self.index;
1118 self.index = (self.index + 1) % NB;
1119 self.buffers[prev_index].deref_mut() as *mut [S]
1120 }
1121}
1122
1123pub(crate) struct State {
1125 started: AtomicBool,
1126 rx_waker: AtomicWaker,
1127 tx_waker: AtomicWaker,
1128 stop_waker: AtomicWaker,
1129}
1130
1131impl State {
1132 pub(crate) const fn new() -> Self {
1133 Self {
1134 started: AtomicBool::new(false),
1135 rx_waker: AtomicWaker::new(),
1136 tx_waker: AtomicWaker::new(),
1137 stop_waker: AtomicWaker::new(),
1138 }
1139 }
1140}
1141
1142pub(crate) trait SealedInstance {
1143 fn regs() -> pac::i2s::I2s;
1144 fn state() -> &'static State;
1145}
1146
1147#[allow(private_bounds)]
1149pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
1150 type Interrupt: interrupt::typelevel::Interrupt;
1152}
1153
1154macro_rules! impl_i2s {
1155 ($type:ident, $pac_type:ident, $irq:ident) => {
1156 impl crate::i2s::SealedInstance for peripherals::$type {
1157 fn regs() -> pac::i2s::I2s {
1158 pac::$pac_type
1159 }
1160 fn state() -> &'static crate::i2s::State {
1161 static STATE: crate::i2s::State = crate::i2s::State::new();
1162 &STATE
1163 }
1164 }
1165 impl crate::i2s::Instance for peripherals::$type {
1166 type Interrupt = crate::interrupt::typelevel::$irq;
1167 }
1168 };
1169}