aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorelagil <[email protected]>2024-11-16 15:02:32 +0100
committerelagil <[email protected]>2024-11-16 15:02:32 +0100
commitd592875ca6d4df2b126e67603d32ed7f3e71910b (patch)
tree04a86d83160817fa4f06f63a5cdb85886f320636 /embassy-stm32/src
parent6c4b3d82b637fce5ab6efdc312d7852381d8ddeb (diff)
fix(SAI): disallow start without initial write
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/dma/dma_bdma.rs3
-rw-r--r--embassy-stm32/src/sai/mod.rs27
2 files changed, 14 insertions, 16 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),