embassy_nrf/
i2s.rs

1//! Inter-IC Sound (I2S) driver.
2
3#![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
22/// Type alias for `MultiBuffering` with 2 buffers.
23pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>;
24
25/// I2S transfer error.
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27#[cfg_attr(feature = "defmt", derive(defmt::Format))]
28#[non_exhaustive]
29pub enum Error {
30    /// The buffer is too long.
31    BufferTooLong,
32    /// The buffer is empty.
33    BufferZeroLength,
34    /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash.
35    BufferNotInRAM,
36    /// The buffer address is not aligned.
37    BufferMisaligned,
38    /// The buffer length is not a multiple of the alignment.
39    BufferLengthMisaligned,
40}
41
42/// I2S configuration.
43#[derive(Clone)]
44#[non_exhaustive]
45pub struct Config {
46    /// Sample width
47    pub sample_width: SampleWidth,
48    /// Alignment
49    pub align: Align,
50    /// Sample format
51    pub format: Format,
52    /// Channel configuration.
53    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/// I2S clock configuration.
68#[derive(Debug, Eq, PartialEq, Clone, Copy)]
69pub struct MasterClock {
70    freq: MckFreq,
71    ratio: Ratio,
72}
73
74impl MasterClock {
75    /// Create a new `MasterClock`.
76    pub fn new(freq: MckFreq, ratio: Ratio) -> Self {
77        Self { freq, ratio }
78    }
79}
80
81impl MasterClock {
82    /// Get the sample rate for this clock configuration.
83    pub fn sample_rate(&self) -> u32 {
84        self.freq.to_frequency() / self.ratio.to_divisor()
85    }
86}
87
88/// Master clock generator frequency.
89#[derive(Debug, Eq, PartialEq, Clone, Copy)]
90pub enum MckFreq {
91    /// 32 Mhz / 8 = 4000.00 kHz
92    _32MDiv8,
93    /// 32 Mhz / 10 = 3200.00 kHz
94    _32MDiv10,
95    /// 32 Mhz / 11 = 2909.09 kHz
96    _32MDiv11,
97    /// 32 Mhz / 15 = 2133.33 kHz
98    _32MDiv15,
99    /// 32 Mhz / 16 = 2000.00 kHz
100    _32MDiv16,
101    /// 32 Mhz / 21 = 1523.81 kHz
102    _32MDiv21,
103    /// 32 Mhz / 23 = 1391.30 kHz
104    _32MDiv23,
105    /// 32 Mhz / 30 = 1066.67 kHz
106    _32MDiv30,
107    /// 32 Mhz / 31 = 1032.26 kHz
108    _32MDiv31,
109    /// 32 Mhz / 32 = 1000.00 kHz
110    _32MDiv32,
111    /// 32 Mhz / 42 = 761.90 kHz
112    _32MDiv42,
113    /// 32 Mhz / 63 = 507.94 kHz
114    _32MDiv63,
115    /// 32 Mhz / 125 = 256.00 kHz
116    _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    /// Return the value that needs to be written to the register.
142    pub fn to_register_value(&self) -> vals::Mckfreq {
143        Self::REGISTER_VALUES[usize::from(*self)]
144    }
145
146    /// Return the master clock frequency.
147    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/// Master clock frequency ratio
159///
160/// Sample Rate = LRCK = MCK / Ratio
161///
162#[derive(Debug, Eq, PartialEq, Clone, Copy)]
163pub enum Ratio {
164    /// Divide by 32
165    _32x,
166    /// Divide by 48
167    _48x,
168    /// Divide by 64
169    _64x,
170    /// Divide by 96
171    _96x,
172    /// Divide by 128
173    _128x,
174    /// Divide by 192
175    _192x,
176    /// Divide by 256
177    _256x,
178    /// Divide by 384
179    _384x,
180    /// Divide by 512
181    _512x,
182}
183
184impl Ratio {
185    const RATIOS: &'static [u32] = &[32, 48, 64, 96, 128, 192, 256, 384, 512];
186
187    /// Return the value that needs to be written to the register.
188    pub fn to_register_value(&self) -> vals::Ratio {
189        vals::Ratio::from_bits(*self as u8)
190    }
191
192    /// Return the divisor for this ratio
193    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/// Approximate sample rates.
205///
206/// Those are common sample rates that can not be configured without an small error.
207///
208/// For custom master clock configuration, please refer to [MasterClock].
209#[derive(Clone, Copy)]
210pub enum ApproxSampleRate {
211    /// 11025 Hz
212    _11025,
213    /// 16000 Hz
214    _16000,
215    /// 22050 Hz
216    _22050,
217    /// 32000 Hz
218    _32000,
219    /// 44100 Hz
220    _44100,
221    /// 48000 Hz
222    _48000,
223}
224
225impl From<ApproxSampleRate> for MasterClock {
226    fn from(value: ApproxSampleRate) -> Self {
227        match value {
228            // error = 86
229            ApproxSampleRate::_11025 => MasterClock::new(MckFreq::_32MDiv15, Ratio::_192x),
230            // error = 127
231            ApproxSampleRate::_16000 => MasterClock::new(MckFreq::_32MDiv21, Ratio::_96x),
232            // error = 172
233            ApproxSampleRate::_22050 => MasterClock::new(MckFreq::_32MDiv15, Ratio::_96x),
234            // error = 254
235            ApproxSampleRate::_32000 => MasterClock::new(MckFreq::_32MDiv21, Ratio::_48x),
236            // error = 344
237            ApproxSampleRate::_44100 => MasterClock::new(MckFreq::_32MDiv15, Ratio::_48x),
238            // error = 381
239            ApproxSampleRate::_48000 => MasterClock::new(MckFreq::_32MDiv21, Ratio::_32x),
240        }
241    }
242}
243
244impl ApproxSampleRate {
245    /// Get the sample rate as an integer.
246    pub fn sample_rate(&self) -> u32 {
247        MasterClock::from(*self).sample_rate()
248    }
249}
250
251/// Exact sample rates.
252///
253/// Those are non standard sample rates that can be configured without error.
254///
255/// For custom master clock configuration, please refer to [vals::Mode].
256#[derive(Clone, Copy)]
257pub enum ExactSampleRate {
258    /// 8000 Hz
259    _8000,
260    /// 10582 Hz
261    _10582,
262    /// 12500 Hz
263    _12500,
264    /// 15625 Hz
265    _15625,
266    /// 15873 Hz
267    _15873,
268    /// 25000 Hz
269    _25000,
270    /// 31250 Hz
271    _31250,
272    /// 50000 Hz
273    _50000,
274    /// 62500 Hz
275    _62500,
276    /// 100000 Hz
277    _100000,
278    /// 125000 Hz
279    _125000,
280}
281
282impl ExactSampleRate {
283    /// Get the sample rate as an integer.
284    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/// Sample width.
308#[derive(Debug, Eq, PartialEq, Clone, Copy)]
309pub enum SampleWidth {
310    /// 8 bit samples.
311    _8bit,
312    /// 16 bit samples.
313    _16bit,
314    /// 24 bit samples.
315    _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/// Channel used for the most significant sample value in a frame.
325#[derive(Debug, Eq, PartialEq, Clone, Copy)]
326pub enum Align {
327    /// Left-align samples.
328    Left,
329    /// Right-align samples.
330    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/// Frame format.
343#[derive(Debug, Eq, PartialEq, Clone, Copy)]
344pub enum Format {
345    /// I2S frame format
346    I2S,
347    /// Aligned frame format
348    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/// Channels
361#[derive(Debug, Eq, PartialEq, Clone, Copy)]
362pub enum Channels {
363    /// Stereo (2 channels).
364    Stereo,
365    /// Mono, left channel only.
366    MonoLeft,
367    /// Mono, right channel only.
368    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
377/// Interrupt handler.
378pub 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::new(T::regs());
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
407/// I2S driver.
408pub struct I2S<'d> {
409    r: pac::i2s::I2s,
410    state: &'static State,
411    mck: Option<Peri<'d, AnyPin>>,
412    sck: Peri<'d, AnyPin>,
413    lrck: Peri<'d, AnyPin>,
414    sdin: Option<Peri<'d, AnyPin>>,
415    sdout: Option<Peri<'d, AnyPin>>,
416    master_clock: Option<MasterClock>,
417    config: Config,
418}
419
420impl<'d> I2S<'d> {
421    /// Create a new I2S in master mode
422    pub fn new_master<T: Instance>(
423        _i2s: Peri<'d, T>,
424        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
425        mck: Peri<'d, impl GpioPin>,
426        sck: Peri<'d, impl GpioPin>,
427        lrck: Peri<'d, impl GpioPin>,
428        master_clock: MasterClock,
429        config: Config,
430    ) -> Self {
431        T::Interrupt::unpend();
432        unsafe { T::Interrupt::enable() };
433
434        Self {
435            r: T::regs(),
436            state: T::state(),
437            mck: Some(mck.into()),
438            sck: sck.into(),
439            lrck: lrck.into(),
440            sdin: None,
441            sdout: None,
442            master_clock: Some(master_clock),
443            config,
444        }
445    }
446
447    /// Create a new I2S in slave mode
448    pub fn new_slave<T: Instance>(
449        _i2s: Peri<'d, T>,
450        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
451        sck: Peri<'d, impl GpioPin>,
452        lrck: Peri<'d, impl GpioPin>,
453        config: Config,
454    ) -> Self {
455        T::Interrupt::unpend();
456        unsafe { T::Interrupt::enable() };
457
458        Self {
459            r: T::regs(),
460            state: T::state(),
461            mck: None,
462            sck: sck.into(),
463            lrck: lrck.into(),
464            sdin: None,
465            sdout: None,
466            master_clock: None,
467            config,
468        }
469    }
470
471    /// I2S output only
472    pub fn output<S: Sample, const NB: usize, const NS: usize>(
473        mut self,
474        sdout: Peri<'d, impl GpioPin>,
475        buffers: MultiBuffering<S, NB, NS>,
476    ) -> OutputStream<'d, S, NB, NS> {
477        self.sdout = Some(sdout.into());
478        let p = self.build();
479        OutputStream {
480            r: p.0,
481            state: p.1,
482            _phantom: PhantomData,
483            buffers,
484        }
485    }
486
487    /// I2S input only
488    pub fn input<S: Sample, const NB: usize, const NS: usize>(
489        mut self,
490        sdin: Peri<'d, impl GpioPin>,
491        buffers: MultiBuffering<S, NB, NS>,
492    ) -> InputStream<'d, S, NB, NS> {
493        self.sdin = Some(sdin.into());
494        let p = self.build();
495        InputStream {
496            r: p.0,
497            state: p.1,
498            buffers,
499            _phantom: PhantomData,
500        }
501    }
502
503    /// I2S full duplex (input and output)
504    pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>(
505        mut self,
506        sdin: Peri<'d, impl GpioPin>,
507        sdout: Peri<'d, impl GpioPin>,
508        buffers_out: MultiBuffering<S, NB, NS>,
509        buffers_in: MultiBuffering<S, NB, NS>,
510    ) -> FullDuplexStream<'d, S, NB, NS> {
511        self.sdout = Some(sdout.into());
512        self.sdin = Some(sdin.into());
513        let p = self.build();
514
515        FullDuplexStream {
516            r: p.0,
517            state: p.1,
518            _phantom: PhantomData,
519            buffers_out,
520            buffers_in,
521        }
522    }
523
524    fn build(self) -> (pac::i2s::I2s, &'static State) {
525        self.apply_config();
526        self.select_pins();
527        self.setup_interrupt();
528
529        let device = Device::new(self.r);
530        device.enable();
531
532        (self.r, self.state)
533    }
534
535    fn apply_config(&self) {
536        let c = self.r.config();
537        match &self.master_clock {
538            Some(MasterClock { freq, ratio }) => {
539                c.mode().write(|w| w.set_mode(vals::Mode::MASTER));
540                c.mcken().write(|w| w.set_mcken(true));
541                c.mckfreq().write(|w| w.set_mckfreq(freq.to_register_value()));
542                c.ratio().write(|w| w.set_ratio(ratio.to_register_value()));
543            }
544            None => {
545                c.mode().write(|w| w.set_mode(vals::Mode::SLAVE));
546            }
547        };
548
549        c.swidth().write(|w| w.set_swidth(self.config.sample_width.into()));
550        c.align().write(|w| w.set_align(self.config.align.into()));
551        c.format().write(|w| w.set_format(self.config.format.into()));
552        c.channels().write(|w| w.set_channels(self.config.channels.into()));
553    }
554
555    fn select_pins(&self) {
556        let psel = self.r.psel();
557        psel.mck().write_value(self.mck.psel_bits());
558        psel.sck().write_value(self.sck.psel_bits());
559        psel.lrck().write_value(self.lrck.psel_bits());
560        psel.sdin().write_value(self.sdin.psel_bits());
561        psel.sdout().write_value(self.sdout.psel_bits());
562    }
563
564    fn setup_interrupt(&self) {
565        // Interrupt is already set up in constructor
566
567        let device = Device::new(self.r);
568        device.disable_tx_ptr_interrupt();
569        device.disable_rx_ptr_interrupt();
570        device.disable_stopped_interrupt();
571
572        device.reset_tx_ptr_event();
573        device.reset_rx_ptr_event();
574        device.reset_stopped_event();
575
576        device.enable_tx_ptr_interrupt();
577        device.enable_rx_ptr_interrupt();
578        device.enable_stopped_interrupt();
579    }
580
581    async fn stop(r: pac::i2s::I2s, state: &State) {
582        compiler_fence(Ordering::SeqCst);
583
584        let device = Device::new(r);
585        device.stop();
586
587        state.started.store(false, Ordering::Relaxed);
588
589        poll_fn(|cx| {
590            state.stop_waker.register(cx.waker());
591
592            if device.is_stopped() {
593                trace!("STOP: Ready");
594                device.reset_stopped_event();
595                Poll::Ready(())
596            } else {
597                trace!("STOP: Pending");
598                Poll::Pending
599            }
600        })
601        .await;
602
603        device.disable();
604    }
605
606    async fn send_from_ram<S>(r: pac::i2s::I2s, state: &State, buffer_ptr: *const [S]) -> Result<(), Error>
607    where
608        S: Sample,
609    {
610        trace!("SEND: {}", buffer_ptr as *const S as u32);
611
612        slice_in_ram_or(buffer_ptr, Error::BufferNotInRAM)?;
613
614        compiler_fence(Ordering::SeqCst);
615
616        let device = Device::new(r);
617
618        device.update_tx(buffer_ptr)?;
619
620        Self::wait_tx_ptr_update(r, state).await;
621
622        compiler_fence(Ordering::SeqCst);
623
624        Ok(())
625    }
626
627    async fn wait_tx_ptr_update(r: pac::i2s::I2s, state: &State) {
628        let drop = OnDrop::new(move || {
629            trace!("TX DROP: Stopping");
630
631            let device = Device::new(r);
632            device.disable_tx_ptr_interrupt();
633            device.reset_tx_ptr_event();
634            device.disable_tx();
635
636            // TX is stopped almost instantly, spinning is fine.
637            while !device.is_tx_ptr_updated() {}
638
639            trace!("TX DROP: Stopped");
640        });
641
642        poll_fn(|cx| {
643            state.tx_waker.register(cx.waker());
644
645            let device = Device::new(r);
646            if device.is_tx_ptr_updated() {
647                trace!("TX POLL: Ready");
648                device.reset_tx_ptr_event();
649                device.enable_tx_ptr_interrupt();
650                Poll::Ready(())
651            } else {
652                trace!("TX POLL: Pending");
653                Poll::Pending
654            }
655        })
656        .await;
657
658        drop.defuse();
659    }
660
661    async fn receive_from_ram<S>(r: pac::i2s::I2s, state: &State, buffer_ptr: *mut [S]) -> Result<(), Error>
662    where
663        S: Sample,
664    {
665        trace!("RECEIVE: {}", buffer_ptr as *const S as u32);
666
667        // NOTE: RAM slice check for rx is not necessary, as a mutable
668        // slice can only be built from data located in RAM.
669
670        compiler_fence(Ordering::SeqCst);
671
672        let device = Device::new(r);
673
674        device.update_rx(buffer_ptr)?;
675
676        Self::wait_rx_ptr_update(r, state).await;
677
678        compiler_fence(Ordering::SeqCst);
679
680        Ok(())
681    }
682
683    async fn wait_rx_ptr_update(r: pac::i2s::I2s, state: &State) {
684        let drop = OnDrop::new(move || {
685            trace!("RX DROP: Stopping");
686
687            let device = Device::new(r);
688            device.disable_rx_ptr_interrupt();
689            device.reset_rx_ptr_event();
690            device.disable_rx();
691
692            // TX is stopped almost instantly, spinning is fine.
693            while !device.is_rx_ptr_updated() {}
694
695            trace!("RX DROP: Stopped");
696        });
697
698        poll_fn(|cx| {
699            state.rx_waker.register(cx.waker());
700
701            let device = Device::new(r);
702            if device.is_rx_ptr_updated() {
703                trace!("RX POLL: Ready");
704                device.reset_rx_ptr_event();
705                device.enable_rx_ptr_interrupt();
706                Poll::Ready(())
707            } else {
708                trace!("RX POLL: Pending");
709                Poll::Pending
710            }
711        })
712        .await;
713
714        drop.defuse();
715    }
716}
717
718/// I2S output
719pub struct OutputStream<'d, S: Sample, const NB: usize, const NS: usize> {
720    r: pac::i2s::I2s,
721    state: &'static State,
722    buffers: MultiBuffering<S, NB, NS>,
723    _phantom: PhantomData<&'d ()>,
724}
725
726impl<'d, S: Sample, const NB: usize, const NS: usize> OutputStream<'d, S, NB, NS> {
727    /// Get a mutable reference to the current buffer.
728    pub fn buffer(&mut self) -> &mut [S] {
729        self.buffers.get_mut()
730    }
731
732    /// Prepare the initial buffer and start the I2S transfer.
733    pub async fn start(&mut self) -> Result<(), Error>
734    where
735        S: Sample,
736    {
737        let device = Device::new(self.r);
738
739        if self.state.started.load(Ordering::Relaxed) {
740            self.stop().await;
741        }
742
743        device.enable();
744        device.enable_tx();
745
746        device.update_tx(self.buffers.switch())?;
747
748        self.state.started.store(true, Ordering::Relaxed);
749
750        device.start();
751
752        I2S::wait_tx_ptr_update(self.r, self.state).await;
753
754        Ok(())
755    }
756
757    /// Stops the I2S transfer and waits until it has stopped.
758    #[inline(always)]
759    pub async fn stop(&self) {
760        I2S::stop(self.r, self.state).await
761    }
762
763    /// Sends the current buffer for transmission in the DMA.
764    /// Switches to use the next available buffer.
765    pub async fn send(&mut self) -> Result<(), Error>
766    where
767        S: Sample,
768    {
769        I2S::send_from_ram(self.r, self.state, self.buffers.switch()).await
770    }
771}
772
773/// I2S input
774pub struct InputStream<'d, S: Sample, const NB: usize, const NS: usize> {
775    r: pac::i2s::I2s,
776    state: &'static State,
777    buffers: MultiBuffering<S, NB, NS>,
778    _phantom: PhantomData<&'d ()>,
779}
780
781impl<'d, S: Sample, const NB: usize, const NS: usize> InputStream<'d, S, NB, NS> {
782    /// Get a mutable reference to the current buffer.
783    pub fn buffer(&mut self) -> &mut [S] {
784        self.buffers.get_mut()
785    }
786
787    /// Prepare the initial buffer and start the I2S transfer.
788    pub async fn start(&mut self) -> Result<(), Error>
789    where
790        S: Sample,
791    {
792        let device = Device::new(self.r);
793
794        if self.state.started.load(Ordering::Relaxed) {
795            self.stop().await;
796        }
797
798        device.enable();
799        device.enable_rx();
800
801        device.update_rx(self.buffers.switch())?;
802
803        self.state.started.store(true, Ordering::Relaxed);
804
805        device.start();
806
807        I2S::wait_rx_ptr_update(self.r, self.state).await;
808
809        Ok(())
810    }
811
812    /// Stops the I2S transfer and waits until it has stopped.
813    #[inline(always)]
814    pub async fn stop(&self) {
815        I2S::stop(self.r, self.state).await
816    }
817
818    /// Sets the current buffer for reception from the DMA.
819    /// Switches to use the next available buffer.
820    #[allow(unused_mut)]
821    pub async fn receive(&mut self) -> Result<(), Error>
822    where
823        S: Sample,
824    {
825        I2S::receive_from_ram(self.r, self.state, self.buffers.switch_mut()).await
826    }
827}
828
829/// I2S full duplex stream (input & output)
830pub struct FullDuplexStream<'d, S: Sample, const NB: usize, const NS: usize> {
831    r: pac::i2s::I2s,
832    state: &'static State,
833    buffers_out: MultiBuffering<S, NB, NS>,
834    buffers_in: MultiBuffering<S, NB, NS>,
835    _phantom: PhantomData<&'d ()>,
836}
837
838impl<'d, S: Sample, const NB: usize, const NS: usize> FullDuplexStream<'d, S, NB, NS> {
839    /// Get the current output and input buffers.
840    pub fn buffers(&mut self) -> (&mut [S], &[S]) {
841        (self.buffers_out.get_mut(), self.buffers_in.get())
842    }
843
844    /// Prepare the initial buffers and start the I2S transfer.
845    pub async fn start(&mut self) -> Result<(), Error>
846    where
847        S: Sample,
848    {
849        let device = Device::new(self.r);
850
851        if self.state.started.load(Ordering::Relaxed) {
852            self.stop().await;
853        }
854
855        device.enable();
856        device.enable_tx();
857        device.enable_rx();
858
859        device.update_tx(self.buffers_out.switch())?;
860        device.update_rx(self.buffers_in.switch_mut())?;
861
862        self.state.started.store(true, Ordering::Relaxed);
863
864        device.start();
865
866        I2S::wait_tx_ptr_update(self.r, self.state).await;
867        I2S::wait_rx_ptr_update(self.r, self.state).await;
868
869        Ok(())
870    }
871
872    /// Stops the I2S transfer and waits until it has stopped.
873    #[inline(always)]
874    pub async fn stop(&self) {
875        I2S::stop(self.r, self.state).await
876    }
877
878    /// Sets the current buffers for output and input for transmission/reception from the DMA.
879    /// Switch to use the next available buffers for output/input.
880    pub async fn send_and_receive(&mut self) -> Result<(), Error>
881    where
882        S: Sample,
883    {
884        I2S::send_from_ram(self.r, self.state, self.buffers_out.switch()).await?;
885        I2S::receive_from_ram(self.r, self.state, self.buffers_in.switch_mut()).await?;
886        Ok(())
887    }
888}
889
890/// Helper encapsulating common I2S device operations.
891struct Device(pac::i2s::I2s);
892
893impl Device {
894    fn new(r: pac::i2s::I2s) -> Self {
895        Self(r)
896    }
897
898    #[inline(always)]
899    pub fn enable(&self) {
900        trace!("ENABLED");
901        self.0.enable().write(|w| w.set_enable(true));
902    }
903
904    #[inline(always)]
905    pub fn disable(&self) {
906        trace!("DISABLED");
907        self.0.enable().write(|w| w.set_enable(false));
908    }
909
910    #[inline(always)]
911    fn enable_tx(&self) {
912        trace!("TX ENABLED");
913        self.0.config().txen().write(|w| w.set_txen(true));
914    }
915
916    #[inline(always)]
917    fn disable_tx(&self) {
918        trace!("TX DISABLED");
919        self.0.config().txen().write(|w| w.set_txen(false));
920    }
921
922    #[inline(always)]
923    fn enable_rx(&self) {
924        trace!("RX ENABLED");
925        self.0.config().rxen().write(|w| w.set_rxen(true));
926    }
927
928    #[inline(always)]
929    fn disable_rx(&self) {
930        trace!("RX DISABLED");
931        self.0.config().rxen().write(|w| w.set_rxen(false));
932    }
933
934    #[inline(always)]
935    fn start(&self) {
936        trace!("START");
937        self.0.tasks_start().write_value(1);
938    }
939
940    #[inline(always)]
941    fn stop(&self) {
942        self.0.tasks_stop().write_value(1);
943    }
944
945    #[inline(always)]
946    fn is_stopped(&self) -> bool {
947        self.0.events_stopped().read() != 0
948    }
949
950    #[inline(always)]
951    fn reset_stopped_event(&self) {
952        trace!("STOPPED EVENT: Reset");
953        self.0.events_stopped().write_value(0);
954    }
955
956    #[inline(always)]
957    fn disable_stopped_interrupt(&self) {
958        trace!("STOPPED INTERRUPT: Disabled");
959        self.0.intenclr().write(|w| w.set_stopped(true));
960    }
961
962    #[inline(always)]
963    fn enable_stopped_interrupt(&self) {
964        trace!("STOPPED INTERRUPT: Enabled");
965        self.0.intenset().write(|w| w.set_stopped(true));
966    }
967
968    #[inline(always)]
969    fn reset_tx_ptr_event(&self) {
970        trace!("TX PTR EVENT: Reset");
971        self.0.events_txptrupd().write_value(0);
972    }
973
974    #[inline(always)]
975    fn reset_rx_ptr_event(&self) {
976        trace!("RX PTR EVENT: Reset");
977        self.0.events_rxptrupd().write_value(0);
978    }
979
980    #[inline(always)]
981    fn disable_tx_ptr_interrupt(&self) {
982        trace!("TX PTR INTERRUPT: Disabled");
983        self.0.intenclr().write(|w| w.set_txptrupd(true));
984    }
985
986    #[inline(always)]
987    fn disable_rx_ptr_interrupt(&self) {
988        trace!("RX PTR INTERRUPT: Disabled");
989        self.0.intenclr().write(|w| w.set_rxptrupd(true));
990    }
991
992    #[inline(always)]
993    fn enable_tx_ptr_interrupt(&self) {
994        trace!("TX PTR INTERRUPT: Enabled");
995        self.0.intenset().write(|w| w.set_txptrupd(true));
996    }
997
998    #[inline(always)]
999    fn enable_rx_ptr_interrupt(&self) {
1000        trace!("RX PTR INTERRUPT: Enabled");
1001        self.0.intenset().write(|w| w.set_rxptrupd(true));
1002    }
1003
1004    #[inline(always)]
1005    fn is_tx_ptr_updated(&self) -> bool {
1006        self.0.events_txptrupd().read() != 0
1007    }
1008
1009    #[inline(always)]
1010    fn is_rx_ptr_updated(&self) -> bool {
1011        self.0.events_rxptrupd().read() != 0
1012    }
1013
1014    #[inline]
1015    fn update_tx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> {
1016        let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?;
1017        self.0.rxtxd().maxcnt().write(|w| w.0 = maxcnt);
1018        self.0.txd().ptr().write_value(ptr);
1019        Ok(())
1020    }
1021
1022    #[inline]
1023    fn update_rx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> {
1024        let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?;
1025        self.0.rxtxd().maxcnt().write(|w| w.0 = maxcnt);
1026        self.0.rxd().ptr().write_value(ptr);
1027        Ok(())
1028    }
1029
1030    fn validated_dma_parts<S>(buffer_ptr: *const [S]) -> Result<(u32, u32), Error> {
1031        let ptr = buffer_ptr as *const S as u32;
1032        let bytes_len = buffer_ptr.len() * size_of::<S>();
1033        let maxcnt = (bytes_len / size_of::<u32>()) as u32;
1034
1035        trace!("PTR={}, MAXCNT={}", ptr, maxcnt);
1036
1037        if ptr % 4 != 0 {
1038            Err(Error::BufferMisaligned)
1039        } else if bytes_len % 4 != 0 {
1040            Err(Error::BufferLengthMisaligned)
1041        } else if maxcnt as usize > EASY_DMA_SIZE {
1042            Err(Error::BufferTooLong)
1043        } else {
1044            Ok((ptr, maxcnt))
1045        }
1046    }
1047}
1048
1049/// Sample details
1050pub trait Sample: Sized + Copy + Default {
1051    /// Width of this sample type.
1052    const WIDTH: usize;
1053
1054    /// Scale of this sample.
1055    const SCALE: Self;
1056}
1057
1058impl Sample for i8 {
1059    const WIDTH: usize = 8;
1060    const SCALE: Self = 1 << (Self::WIDTH - 1);
1061}
1062
1063impl Sample for i16 {
1064    const WIDTH: usize = 16;
1065    const SCALE: Self = 1 << (Self::WIDTH - 1);
1066}
1067
1068impl Sample for i32 {
1069    const WIDTH: usize = 24;
1070    const SCALE: Self = 1 << (Self::WIDTH - 1);
1071}
1072
1073/// A 4-bytes aligned buffer. Needed for DMA access.
1074#[derive(Clone, Copy)]
1075#[repr(align(4))]
1076pub struct AlignedBuffer<T: Sample, const N: usize>([T; N]);
1077
1078impl<T: Sample, const N: usize> AlignedBuffer<T, N> {
1079    /// Create a new `AlignedBuffer`.
1080    pub fn new(array: [T; N]) -> Self {
1081        Self(array)
1082    }
1083}
1084
1085impl<T: Sample, const N: usize> Default for AlignedBuffer<T, N> {
1086    fn default() -> Self {
1087        Self([T::default(); N])
1088    }
1089}
1090
1091impl<T: Sample, const N: usize> Deref for AlignedBuffer<T, N> {
1092    type Target = [T];
1093    fn deref(&self) -> &Self::Target {
1094        self.0.as_slice()
1095    }
1096}
1097
1098impl<T: Sample, const N: usize> DerefMut for AlignedBuffer<T, N> {
1099    fn deref_mut(&mut self) -> &mut Self::Target {
1100        self.0.as_mut_slice()
1101    }
1102}
1103
1104/// Set of multiple buffers, for multi-buffering transfers.
1105pub struct MultiBuffering<S: Sample, const NB: usize, const NS: usize> {
1106    buffers: [AlignedBuffer<S, NS>; NB],
1107    index: usize,
1108}
1109
1110impl<S: Sample, const NB: usize, const NS: usize> MultiBuffering<S, NB, NS> {
1111    /// Create a new `MultiBuffering`.
1112    pub fn new() -> Self {
1113        assert!(NB > 1);
1114        Self {
1115            buffers: [AlignedBuffer::<S, NS>::default(); NB],
1116            index: 0,
1117        }
1118    }
1119
1120    fn get(&self) -> &[S] {
1121        &self.buffers[self.index]
1122    }
1123
1124    fn get_mut(&mut self) -> &mut [S] {
1125        &mut self.buffers[self.index]
1126    }
1127
1128    /// Advance to use the next buffer and return a non mutable pointer to the previous one.
1129    fn switch(&mut self) -> *const [S] {
1130        let prev_index = self.index;
1131        self.index = (self.index + 1) % NB;
1132        self.buffers[prev_index].deref() as *const [S]
1133    }
1134
1135    /// Advance to use the next buffer and return a mutable pointer to the previous one.
1136    fn switch_mut(&mut self) -> *mut [S] {
1137        let prev_index = self.index;
1138        self.index = (self.index + 1) % NB;
1139        self.buffers[prev_index].deref_mut() as *mut [S]
1140    }
1141}
1142
1143/// Peripheral static state
1144pub(crate) struct State {
1145    started: AtomicBool,
1146    rx_waker: AtomicWaker,
1147    tx_waker: AtomicWaker,
1148    stop_waker: AtomicWaker,
1149}
1150
1151impl State {
1152    pub(crate) const fn new() -> Self {
1153        Self {
1154            started: AtomicBool::new(false),
1155            rx_waker: AtomicWaker::new(),
1156            tx_waker: AtomicWaker::new(),
1157            stop_waker: AtomicWaker::new(),
1158        }
1159    }
1160}
1161
1162pub(crate) trait SealedInstance {
1163    fn regs() -> pac::i2s::I2s;
1164    fn state() -> &'static State;
1165}
1166
1167/// I2S peripheral instance.
1168#[allow(private_bounds)]
1169pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
1170    /// Interrupt for this peripheral.
1171    type Interrupt: interrupt::typelevel::Interrupt;
1172}
1173
1174macro_rules! impl_i2s {
1175    ($type:ident, $pac_type:ident, $irq:ident) => {
1176        impl crate::i2s::SealedInstance for peripherals::$type {
1177            fn regs() -> pac::i2s::I2s {
1178                pac::$pac_type
1179            }
1180            fn state() -> &'static crate::i2s::State {
1181                static STATE: crate::i2s::State = crate::i2s::State::new();
1182                &STATE
1183            }
1184        }
1185        impl crate::i2s::Instance for peripherals::$type {
1186            type Interrupt = crate::interrupt::typelevel::$irq;
1187        }
1188    };
1189}