aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Perez Llamas <[email protected]>2022-11-29 01:09:47 +0100
committerChristian Perez Llamas <[email protected]>2022-11-29 01:09:47 +0100
commit199504be564b231154e07c58bcc52b11afdc9fe7 (patch)
tree88d66d98acf9edbdb23d869d81f453fd3b2eb0f1
parent6b8ab32536bf2e831ec424b5aaf489bb1f53d017 (diff)
Optimization to be able to work with only 2 buffers
-rw-r--r--embassy-nrf/src/i2s.rs48
-rw-r--r--examples/nrf/src/bin/i2s_waveform.rs20
2 files changed, 43 insertions, 25 deletions
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs
index bc90dbc98..08d4093f2 100644
--- a/embassy-nrf/src/i2s.rs
+++ b/embassy-nrf/src/i2s.rs
@@ -398,6 +398,7 @@ impl<'d, T: Instance> I2S<'d, T> {
398 ) -> FullDuplexStream<'d, T> { 398 ) -> FullDuplexStream<'d, T> {
399 self.sdout = Some(sdout.into_ref().map_into()); 399 self.sdout = Some(sdout.into_ref().map_into());
400 self.sdin = Some(sdin.into_ref().map_into()); 400 self.sdin = Some(sdin.into_ref().map_into());
401
401 FullDuplexStream { _p: self.build() } 402 FullDuplexStream { _p: self.build() }
402 } 403 }
403 404
@@ -549,6 +550,16 @@ impl<'d, T: Instance> I2S<'d, T> {
549 550
550 let device = Device::<T>::new(); 551 let device = Device::<T>::new();
551 552
553 device.update_tx(buffer_ptr)?;
554
555 Self::wait_tx_ptr_update().await;
556
557 compiler_fence(Ordering::SeqCst);
558
559 Ok(())
560 }
561
562 async fn wait_tx_ptr_update() {
552 let drop = OnDrop::new(move || { 563 let drop = OnDrop::new(move || {
553 trace!("TX DROP: Stopping"); 564 trace!("TX DROP: Stopping");
554 565
@@ -566,6 +577,7 @@ impl<'d, T: Instance> I2S<'d, T> {
566 poll_fn(|cx| { 577 poll_fn(|cx| {
567 T::state().tx_waker.register(cx.waker()); 578 T::state().tx_waker.register(cx.waker());
568 579
580 let device = Device::<T>::new();
569 if device.is_tx_ptr_updated() { 581 if device.is_tx_ptr_updated() {
570 trace!("TX POLL: Ready"); 582 trace!("TX POLL: Ready");
571 device.reset_tx_ptr_event(); 583 device.reset_tx_ptr_event();
@@ -578,12 +590,7 @@ impl<'d, T: Instance> I2S<'d, T> {
578 }) 590 })
579 .await; 591 .await;
580 592
581 device.update_tx(buffer_ptr)?;
582
583 compiler_fence(Ordering::SeqCst);
584 drop.defuse(); 593 drop.defuse();
585
586 Ok(())
587 } 594 }
588 595
589 async fn receive_from_ram<S>(buffer_ptr: *mut [S]) -> Result<(), Error> 596 async fn receive_from_ram<S>(buffer_ptr: *mut [S]) -> Result<(), Error>
@@ -599,6 +606,16 @@ impl<'d, T: Instance> I2S<'d, T> {
599 606
600 let device = Device::<T>::new(); 607 let device = Device::<T>::new();
601 608
609 device.update_rx(buffer_ptr)?;
610
611 Self::wait_rx_ptr_update().await;
612
613 compiler_fence(Ordering::SeqCst);
614
615 Ok(())
616 }
617
618 async fn wait_rx_ptr_update() {
602 let drop = OnDrop::new(move || { 619 let drop = OnDrop::new(move || {
603 trace!("RX DROP: Stopping"); 620 trace!("RX DROP: Stopping");
604 621
@@ -616,6 +633,7 @@ impl<'d, T: Instance> I2S<'d, T> {
616 poll_fn(|cx| { 633 poll_fn(|cx| {
617 T::state().rx_waker.register(cx.waker()); 634 T::state().rx_waker.register(cx.waker());
618 635
636 let device = Device::<T>::new();
619 if device.is_rx_ptr_updated() { 637 if device.is_rx_ptr_updated() {
620 trace!("RX POLL: Ready"); 638 trace!("RX POLL: Ready");
621 device.reset_rx_ptr_event(); 639 device.reset_rx_ptr_event();
@@ -628,13 +646,7 @@ impl<'d, T: Instance> I2S<'d, T> {
628 }) 646 })
629 .await; 647 .await;
630 648
631 device.update_rx(buffer_ptr)?;
632
633 compiler_fence(Ordering::SeqCst);
634
635 drop.defuse(); 649 drop.defuse();
636
637 Ok(())
638 } 650 }
639} 651}
640 652
@@ -666,6 +678,8 @@ impl<'d, T: Instance> OutputStream<'d, T> {
666 678
667 device.start(); 679 device.start();
668 680
681 I2S::<T>::wait_tx_ptr_update().await;
682
669 Ok(()) 683 Ok(())
670 } 684 }
671 685
@@ -716,6 +730,8 @@ impl<'d, T: Instance> InputStream<'d, T> {
716 730
717 device.start(); 731 device.start();
718 732
733 I2S::<T>::wait_rx_ptr_update().await;
734
719 Ok(()) 735 Ok(())
720 } 736 }
721 737
@@ -746,7 +762,7 @@ pub struct FullDuplexStream<'d, T: Instance> {
746impl<'d, T: Instance> FullDuplexStream<'d, T> { 762impl<'d, T: Instance> FullDuplexStream<'d, T> {
747 /// Prepare the initial buffers and start the I2S transfer. 763 /// Prepare the initial buffers and start the I2S transfer.
748 #[allow(unused_mut)] 764 #[allow(unused_mut)]
749 pub async fn start<S>(&mut self, buffer_out: &[S], buffer_in: &mut [S]) -> Result<(), Error> 765 pub async fn start<S>(&mut self, buffer_in: &mut [S], buffer_out: &[S]) -> Result<(), Error>
750 where 766 where
751 S: Sample, 767 S: Sample,
752 { 768 {
@@ -768,6 +784,9 @@ impl<'d, T: Instance> FullDuplexStream<'d, T> {
768 784
769 device.start(); 785 device.start();
770 786
787 I2S::<T>::wait_tx_ptr_update().await;
788 I2S::<T>::wait_rx_ptr_update().await;
789
771 Ok(()) 790 Ok(())
772 } 791 }
773 792
@@ -782,7 +801,7 @@ impl<'d, T: Instance> FullDuplexStream<'d, T> {
782 /// The buffers must not be written/read while being used by the DMA, 801 /// The buffers must not be written/read while being used by the DMA,
783 /// which takes two other `send_and_receive` operations being awaited. 802 /// which takes two other `send_and_receive` operations being awaited.
784 #[allow(unused_mut)] 803 #[allow(unused_mut)]
785 pub async fn send_and_receive_from_ram<S>(&mut self, buffer_out: &[S], buffer_in: &mut [S]) -> Result<(), Error> 804 pub async fn send_and_receive_from_ram<S>(&mut self, buffer_in: &mut [S], buffer_out: &[S]) -> Result<(), Error>
786 where 805 where
787 S: Sample, 806 S: Sample,
788 { 807 {
@@ -903,7 +922,7 @@ impl<T: Instance> Device<T> {
903 #[inline(always)] 922 #[inline(always)]
904 fn enable_rx_ptr_interrupt(&self) { 923 fn enable_rx_ptr_interrupt(&self) {
905 trace!("RX PTR INTERRUPT: Enabled"); 924 trace!("RX PTR INTERRUPT: Enabled");
906 self.0.intenclr.write(|w| w.rxptrupd().clear()); 925 self.0.intenset.write(|w| w.rxptrupd().set());
907 } 926 }
908 927
909 #[inline(always)] 928 #[inline(always)]
@@ -974,6 +993,7 @@ impl Sample for i32 {
974} 993}
975 994
976/// A 4-bytes aligned [Buffer]. 995/// A 4-bytes aligned [Buffer].
996#[derive(Clone, Copy)]
977#[repr(align(4))] 997#[repr(align(4))]
978pub struct AlignedBuffer<T: Sample, const N: usize>([T; N]); 998pub struct AlignedBuffer<T: Sample, const N: usize>([T; N]);
979 999
diff --git a/examples/nrf/src/bin/i2s_waveform.rs b/examples/nrf/src/bin/i2s_waveform.rs
index 81858ff59..13b1300ea 100644
--- a/examples/nrf/src/bin/i2s_waveform.rs
+++ b/examples/nrf/src/bin/i2s_waveform.rs
@@ -12,7 +12,8 @@ use {defmt_rtt as _, panic_probe as _};
12 12
13type Sample = i16; 13type Sample = i16;
14 14
15const NUM_SAMPLES: usize = 6000; 15const NUM_BUFFERS: usize = 2;
16const NUM_SAMPLES: usize = 50;
16 17
17#[embassy_executor::main] 18#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
@@ -30,31 +31,27 @@ async fn main(_spawner: Spawner) {
30 let irq = interrupt::take!(I2S); 31 let irq = interrupt::take!(I2S);
31 let mut output_stream = I2S::master(p.I2S, irq, p.P0_25, p.P0_26, p.P0_27, master_clock, config).output(p.P0_28); 32 let mut output_stream = I2S::master(p.I2S, irq, p.P0_25, p.P0_26, p.P0_27, master_clock, config).output(p.P0_28);
32 33
33 let mut buffers: [i2s::AlignedBuffer<Sample, NUM_SAMPLES>; 3] = [ 34 let mut buffers: [i2s::AlignedBuffer<Sample, NUM_SAMPLES>; NUM_BUFFERS] =
34 i2s::AlignedBuffer::default(), 35 [i2s::AlignedBuffer::default(); NUM_BUFFERS];
35 i2s::AlignedBuffer::default(),
36 i2s::AlignedBuffer::default(),
37 ];
38 36
39 let mut waveform = Waveform::new(1.0 / sample_rate as f32); 37 let mut waveform = Waveform::new(1.0 / sample_rate as f32);
40 38
41 waveform.process(&mut buffers[0]); 39 waveform.process(&mut buffers[0]);
42 waveform.process(&mut buffers[1]);
43 40
44 output_stream.start(&buffers[0]).await.expect("I2S Start"); 41 output_stream.start(&buffers[0]).await.expect("I2S Start");
45 42
46 let mut index = 1; 43 let mut index = 1;
47 loop { 44 loop {
45 waveform.process(&mut buffers[index]);
46
48 if let Err(err) = output_stream.send_from_ram(&buffers[index]).await { 47 if let Err(err) = output_stream.send_from_ram(&buffers[index]).await {
49 error!("{}", err); 48 error!("{}", err);
50 } 49 }
51 50
52 index += 1; 51 index += 1;
53 if index >= 3 { 52 if index >= NUM_BUFFERS {
54 index = 0; 53 index = 0;
55 } 54 }
56
57 waveform.process(&mut buffers[index]);
58 } 55 }
59} 56}
60 57
@@ -67,7 +64,8 @@ struct Waveform {
67 64
68impl Waveform { 65impl Waveform {
69 fn new(inv_sample_rate: f32) -> Self { 66 fn new(inv_sample_rate: f32) -> Self {
70 let carrier = SineOsc::new(); 67 let mut carrier = SineOsc::new();
68 carrier.set_frequency(110.0, inv_sample_rate);
71 69
72 let mut freq_mod = SineOsc::new(); 70 let mut freq_mod = SineOsc::new();
73 freq_mod.set_frequency(8.0, inv_sample_rate); 71 freq_mod.set_frequency(8.0, inv_sample_rate);