aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-11-16 22:36:41 +0000
committerGitHub <[email protected]>2024-11-16 22:36:41 +0000
commit8d8cd78f634b2f435e3a997f7f8f3ac0b8ca300c (patch)
tree4d698c0039af983b6a71c947c26c08e53360f086
parent6c4b3d82b637fce5ab6efdc312d7852381d8ddeb (diff)
parentf2a46e2ac3d8764a205cdde20a1e2af3cbd7ec1e (diff)
Merge pull request #3541 from elagil/avoid_sai_start_before_write
Disallow SAI start without an initial write
-rw-r--r--embassy-stm32/src/dma/dma_bdma.rs3
-rw-r--r--embassy-stm32/src/sai/mod.rs27
-rw-r--r--examples/stm32h7/src/bin/sai.rs3
3 files changed, 15 insertions, 18 deletions
diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs
index cdc603e2c..08c7a5508 100644
--- a/embassy-stm32/src/dma/dma_bdma.rs
+++ b/embassy-stm32/src/dma/dma_bdma.rs
@@ -828,7 +828,6 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
828 /// You must call this after creating it for it to work. 828 /// You must call this after creating it for it to work.
829 pub fn start(&mut self) { 829 pub fn start(&mut self) {
830 self.channel.start(); 830 self.channel.start();
831 self.clear();
832 } 831 }
833 832
834 /// Clear all data in the ring buffer. 833 /// Clear all data in the ring buffer.
@@ -981,7 +980,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
981 /// You must call this after creating it for it to work. 980 /// You must call this after creating it for it to work.
982 pub fn start(&mut self) { 981 pub fn start(&mut self) {
983 self.channel.start(); 982 self.channel.start();
984 self.clear();
985 } 983 }
986 984
987 /// Clear all data in the ring buffer. 985 /// Clear all data in the ring buffer.
@@ -991,7 +989,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
991 989
992 /// Write elements directly to the raw buffer. 990 /// Write elements directly to the raw buffer.
993 /// This can be used to fill the buffer before starting the DMA transfer. 991 /// This can be used to fill the buffer before starting the DMA transfer.
994 #[allow(dead_code)]
995 pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), Error> { 992 pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), Error> {
996 self.ringbuf.write_immediate(buf) 993 self.ringbuf.write_immediate(buf)
997 } 994 }
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 62b44b77f..057b21980 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -958,13 +958,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
958 } 958 }
959 959
960 /// Start the SAI driver. 960 /// Start the SAI driver.
961 pub fn start(&mut self) { 961 ///
962 /// Only receivers can be started. Transmitters are started on the first writing operation.
963 pub fn start(&mut self) -> Result<(), Error> {
962 match self.ring_buffer { 964 match self.ring_buffer {
963 RingBuffer::Writable(ref mut rb) => { 965 RingBuffer::Writable(_) => Err(Error::NotAReceiver),
964 rb.start();
965 }
966 RingBuffer::Readable(ref mut rb) => { 966 RingBuffer::Readable(ref mut rb) => {
967 rb.start(); 967 rb.start();
968 Ok(())
968 } 969 }
969 } 970 }
970 } 971 }
@@ -981,14 +982,6 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
981 rcc::enable_and_reset::<T>(); 982 rcc::enable_and_reset::<T>();
982 } 983 }
983 984
984 /// Flush.
985 pub fn flush(&mut self) {
986 let ch = T::REGS.ch(self.sub_block as usize);
987 ch.cr1().modify(|w| w.set_saien(false));
988 ch.cr2().modify(|w| w.set_fflush(true));
989 ch.cr1().modify(|w| w.set_saien(true));
990 }
991
992 /// Enable or disable mute. 985 /// Enable or disable mute.
993 pub fn set_mute(&mut self, value: bool) { 986 pub fn set_mute(&mut self, value: bool) {
994 let ch = T::REGS.ch(self.sub_block as usize); 987 let ch = T::REGS.ch(self.sub_block as usize);
@@ -1012,6 +1005,9 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
1012 1005
1013 /// Write data to the SAI ringbuffer. 1006 /// Write data to the SAI ringbuffer.
1014 /// 1007 ///
1008 /// The first write starts the DMA after filling the ring buffer with the provided data.
1009 /// This ensures that the DMA does not run before data is available in the ring buffer.
1010 ///
1015 /// This appends the data to the buffer and returns immediately. The 1011 /// This appends the data to the buffer and returns immediately. The
1016 /// data will be transmitted in the background. 1012 /// data will be transmitted in the background.
1017 /// 1013 ///
@@ -1019,7 +1015,12 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
1019 pub async fn write(&mut self, data: &[W]) -> Result<(), Error> { 1015 pub async fn write(&mut self, data: &[W]) -> Result<(), Error> {
1020 match &mut self.ring_buffer { 1016 match &mut self.ring_buffer {
1021 RingBuffer::Writable(buffer) => { 1017 RingBuffer::Writable(buffer) => {
1022 buffer.write_exact(data).await?; 1018 if buffer.is_running() {
1019 buffer.write_exact(data).await?;
1020 } else {
1021 buffer.write_immediate(data)?;
1022 buffer.start();
1023 }
1023 Ok(()) 1024 Ok(())
1024 } 1025 }
1025 _ => return Err(Error::NotATransmitter), 1026 _ => return Err(Error::NotATransmitter),
diff --git a/examples/stm32h7/src/bin/sai.rs b/examples/stm32h7/src/bin/sai.rs
index 04d14bd6b..95ffe257a 100644
--- a/examples/stm32h7/src/bin/sai.rs
+++ b/examples/stm32h7/src/bin/sai.rs
@@ -107,8 +107,7 @@ async fn main(_spawner: Spawner) {
107 107
108 let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config); 108 let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config);
109 109
110 sai_receiver.start(); 110 sai_receiver.start().unwrap();
111 sai_transmitter.start();
112 111
113 let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH]; 112 let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH];
114 113