Add async stop() function to stm32 bdma_dma
This commit is contained in:
		
							parent
							
								
									6634cc90bc
								
							
						
					
					
						commit
						cb01d03835
					
				@ -1,4 +1,4 @@
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::pin::Pin;
 | 
			
		||||
use core::sync::atomic::{fence, AtomicUsize, Ordering};
 | 
			
		||||
use core::task::{Context, Poll, Waker};
 | 
			
		||||
@ -510,6 +510,31 @@ impl AnyChannel {
 | 
			
		||||
            DmaInfo::Bdma(r) => r.ch(info.num).ndtr().read().ndt(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn disable_circular_mode(&self) {
 | 
			
		||||
        let info = self.info();
 | 
			
		||||
        match self.info().dma {
 | 
			
		||||
            #[cfg(dma)]
 | 
			
		||||
            DmaInfo::Dma(regs) => regs.st(info.num).cr().modify(|w| {
 | 
			
		||||
                w.set_circ(false);
 | 
			
		||||
            }),
 | 
			
		||||
            #[cfg(bdma)]
 | 
			
		||||
            DmaInfo::Bdma(regs) => regs.ch(info.num).cr().modify(|w| {
 | 
			
		||||
                w.set_circ(false);
 | 
			
		||||
            }),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn poll_stop(&self) -> Poll<()> {
 | 
			
		||||
        use core::sync::atomic::compiler_fence;
 | 
			
		||||
        compiler_fence(Ordering::SeqCst);
 | 
			
		||||
 | 
			
		||||
        if !self.is_running() {
 | 
			
		||||
            Poll::Ready(())
 | 
			
		||||
        } else {
 | 
			
		||||
            Poll::Pending
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// DMA transfer.
 | 
			
		||||
@ -829,6 +854,25 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
 | 
			
		||||
    pub fn is_running(&mut self) -> bool {
 | 
			
		||||
        self.channel.is_running()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Stop the DMA transfer and await until the buffer is full.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This disables the DMA transfer's circular mode so that the transfer
 | 
			
		||||
    /// stops when the buffer is full.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This is designed to be used with streaming input data such as the
 | 
			
		||||
    /// I2S/SAI or ADC.
 | 
			
		||||
    ///
 | 
			
		||||
    /// When using the UART, you probably want `request_stop()`.
 | 
			
		||||
    pub async fn stop(&mut self) {
 | 
			
		||||
        self.channel.disable_circular_mode();
 | 
			
		||||
        //wait until cr.susp reads as true
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            self.set_waker(cx.waker());
 | 
			
		||||
            self.channel.poll_stop()
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> {
 | 
			
		||||
@ -940,6 +984,23 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
 | 
			
		||||
    pub fn is_running(&mut self) -> bool {
 | 
			
		||||
        self.channel.is_running()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Stop the DMA transfer and await until the buffer is empty.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This disables the DMA transfer's circular mode so that the transfer
 | 
			
		||||
    /// stops when all available data has been written.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This is designed to be used with streaming output data such as the
 | 
			
		||||
    /// I2S/SAI or DAC.
 | 
			
		||||
    pub async fn stop(&mut self) {
 | 
			
		||||
        self.channel.disable_circular_mode();
 | 
			
		||||
        //wait until cr.susp reads as true
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            self.set_waker(cx.waker());
 | 
			
		||||
            self.channel.poll_stop()
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a, W: Word> Drop for WritableRingBuffer<'a, W> {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user