mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 22:32:29 +00:00
Merge pull request #3541 from elagil/avoid_sai_start_before_write
Disallow SAI start without an initial write
This commit is contained in:
commit
8d8cd78f63
@ -828,7 +828,6 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
|
|||||||
/// You must call this after creating it for it to work.
|
/// You must call this after creating it for it to work.
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
self.channel.start();
|
self.channel.start();
|
||||||
self.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all data in the ring buffer.
|
/// Clear all data in the ring buffer.
|
||||||
@ -981,7 +980,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
|
|||||||
/// You must call this after creating it for it to work.
|
/// You must call this after creating it for it to work.
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
self.channel.start();
|
self.channel.start();
|
||||||
self.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all data in the ring buffer.
|
/// Clear all data in the ring buffer.
|
||||||
@ -991,7 +989,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
|
|||||||
|
|
||||||
/// Write elements directly to the raw buffer.
|
/// Write elements directly to the raw buffer.
|
||||||
/// This can be used to fill the buffer before starting the DMA transfer.
|
/// This can be used to fill the buffer before starting the DMA transfer.
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), Error> {
|
pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), Error> {
|
||||||
self.ringbuf.write_immediate(buf)
|
self.ringbuf.write_immediate(buf)
|
||||||
}
|
}
|
||||||
|
@ -958,13 +958,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Start the SAI driver.
|
/// Start the SAI driver.
|
||||||
pub fn start(&mut self) {
|
///
|
||||||
|
/// Only receivers can be started. Transmitters are started on the first writing operation.
|
||||||
|
pub fn start(&mut self) -> Result<(), Error> {
|
||||||
match self.ring_buffer {
|
match self.ring_buffer {
|
||||||
RingBuffer::Writable(ref mut rb) => {
|
RingBuffer::Writable(_) => Err(Error::NotAReceiver),
|
||||||
rb.start();
|
|
||||||
}
|
|
||||||
RingBuffer::Readable(ref mut rb) => {
|
RingBuffer::Readable(ref mut rb) => {
|
||||||
rb.start();
|
rb.start();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -981,14 +982,6 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
|
|||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush.
|
|
||||||
pub fn flush(&mut self) {
|
|
||||||
let ch = T::REGS.ch(self.sub_block as usize);
|
|
||||||
ch.cr1().modify(|w| w.set_saien(false));
|
|
||||||
ch.cr2().modify(|w| w.set_fflush(true));
|
|
||||||
ch.cr1().modify(|w| w.set_saien(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable or disable mute.
|
/// Enable or disable mute.
|
||||||
pub fn set_mute(&mut self, value: bool) {
|
pub fn set_mute(&mut self, value: bool) {
|
||||||
let ch = T::REGS.ch(self.sub_block as usize);
|
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> {
|
|||||||
|
|
||||||
/// Write data to the SAI ringbuffer.
|
/// Write data to the SAI ringbuffer.
|
||||||
///
|
///
|
||||||
|
/// The first write starts the DMA after filling the ring buffer with the provided data.
|
||||||
|
/// This ensures that the DMA does not run before data is available in the ring buffer.
|
||||||
|
///
|
||||||
/// This appends the data to the buffer and returns immediately. The
|
/// This appends the data to the buffer and returns immediately. The
|
||||||
/// data will be transmitted in the background.
|
/// data will be transmitted in the background.
|
||||||
///
|
///
|
||||||
@ -1019,7 +1015,12 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
|
|||||||
pub async fn write(&mut self, data: &[W]) -> Result<(), Error> {
|
pub async fn write(&mut self, data: &[W]) -> Result<(), Error> {
|
||||||
match &mut self.ring_buffer {
|
match &mut self.ring_buffer {
|
||||||
RingBuffer::Writable(buffer) => {
|
RingBuffer::Writable(buffer) => {
|
||||||
buffer.write_exact(data).await?;
|
if buffer.is_running() {
|
||||||
|
buffer.write_exact(data).await?;
|
||||||
|
} else {
|
||||||
|
buffer.write_immediate(data)?;
|
||||||
|
buffer.start();
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => return Err(Error::NotATransmitter),
|
_ => return Err(Error::NotATransmitter),
|
||||||
|
@ -107,8 +107,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config);
|
let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config);
|
||||||
|
|
||||||
sai_receiver.start();
|
sai_receiver.start().unwrap();
|
||||||
sai_transmitter.start();
|
|
||||||
|
|
||||||
let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH];
|
let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user