aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/sai
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/sai
parent6c4b3d82b637fce5ab6efdc312d7852381d8ddeb (diff)
fix(SAI): disallow start without initial write
Diffstat (limited to 'embassy-stm32/src/sai')
-rw-r--r--embassy-stm32/src/sai/mod.rs27
1 files changed, 14 insertions, 13 deletions
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),