issue 2059 fix build errors in ci
This commit is contained in:
parent
6c2ad332e8
commit
3c58465e30
@ -1,6 +1,6 @@
|
||||
//! Basic Direct Memory Acccess (BDMA)
|
||||
|
||||
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};
|
||||
@ -431,6 +431,45 @@ impl<'a, C: Channel> DmaCtrl for DmaCtrlImpl<'a, C> {
|
||||
}
|
||||
}
|
||||
|
||||
struct RingBuffer {}
|
||||
|
||||
impl RingBuffer {
|
||||
fn is_running(ch: &pac::bdma::Ch) -> bool {
|
||||
ch.cr().read().en()
|
||||
}
|
||||
|
||||
fn request_stop(ch: &pac::bdma::Ch) {
|
||||
// Disable the channel. Keep the IEs enabled so the irqs still fire.
|
||||
// If the channel is enabled and transfer is not completed, we need to perform
|
||||
// two separate write access to the CR register to disable the channel.
|
||||
ch.cr().write(|w| {
|
||||
w.set_teie(true);
|
||||
w.set_htie(true);
|
||||
w.set_tcie(true);
|
||||
});
|
||||
}
|
||||
|
||||
async fn stop(ch: &pac::bdma::Ch, set_waker: &mut dyn FnMut(&Waker)) {
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
Self::request_stop(ch);
|
||||
|
||||
//wait until cr.susp reads as true
|
||||
poll_fn(|cx| {
|
||||
set_waker(cx.waker());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
if !Self::is_running(ch) {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
/// Ringbuffer for reading data using DMA circular mode.
|
||||
pub struct ReadableRingBuffer<'a, C: Channel, W: Word> {
|
||||
cr: regs::Cr,
|
||||
@ -508,6 +547,13 @@ impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
self.ringbuf.clear(&mut DmaCtrlImpl(self.channel.reborrow()));
|
||||
}
|
||||
|
||||
pub async fn stop(&mut self) {
|
||||
RingBuffer::stop(&self.channel.regs().ch(self.channel.num()), &mut |waker| {
|
||||
self.set_waker(waker)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Read elements from the ring buffer
|
||||
/// Return a tuple of the length read and the length remaining in the buffer
|
||||
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||
@ -557,16 +603,7 @@ impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
///
|
||||
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
|
||||
pub fn request_stop(&mut self) {
|
||||
let ch = self.channel.regs().ch(self.channel.num());
|
||||
|
||||
// Disable the channel. Keep the IEs enabled so the irqs still fire.
|
||||
// If the channel is enabled and transfer is not completed, we need to perform
|
||||
// two separate write access to the CR register to disable the channel.
|
||||
ch.cr().write(|w| {
|
||||
w.set_teie(true);
|
||||
w.set_htie(true);
|
||||
w.set_tcie(true);
|
||||
});
|
||||
RingBuffer::request_stop(&self.channel.regs().ch(self.channel.num()));
|
||||
}
|
||||
|
||||
/// Return whether DMA is still running.
|
||||
@ -574,8 +611,7 @@ impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
/// If this returns `false`, it can be because either the transfer finished, or
|
||||
/// it was requested to stop early with [`request_stop`](Self::request_stop).
|
||||
pub fn is_running(&mut self) -> bool {
|
||||
let ch = self.channel.regs().ch(self.channel.num());
|
||||
ch.cr().read().en()
|
||||
RingBuffer::is_running(&self.channel.regs().ch(self.channel.num()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -666,6 +702,20 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
self.ringbuf.clear(&mut DmaCtrlImpl(self.channel.reborrow()));
|
||||
}
|
||||
|
||||
/// Write elements directly to the raw buffer.
|
||||
/// 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), OverrunError> {
|
||||
self.ringbuf.write_immediate(buf)
|
||||
}
|
||||
|
||||
pub async fn stop(&mut self) {
|
||||
RingBuffer::stop(&self.channel.regs().ch(self.channel.num()), &mut |waker| {
|
||||
self.set_waker(waker)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Write elements to the ring buffer
|
||||
/// Return a tuple of the length written and the length remaining in the buffer
|
||||
pub fn write(&mut self, buf: &[W]) -> Result<(usize, usize), OverrunError> {
|
||||
@ -702,16 +752,7 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
///
|
||||
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
|
||||
pub fn request_stop(&mut self) {
|
||||
let ch = self.channel.regs().ch(self.channel.num());
|
||||
|
||||
// Disable the channel. Keep the IEs enabled so the irqs still fire.
|
||||
// If the channel is enabled and transfer is not completed, we need to perform
|
||||
// two separate write access to the CR register to disable the channel.
|
||||
ch.cr().write(|w| {
|
||||
w.set_teie(true);
|
||||
w.set_htie(true);
|
||||
w.set_tcie(true);
|
||||
});
|
||||
RingBuffer::request_stop(&self.channel.regs().ch(self.channel.num()));
|
||||
}
|
||||
|
||||
/// Return whether DMA is still running.
|
||||
@ -719,8 +760,7 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
/// If this returns `false`, it can be because either the transfer finished, or
|
||||
/// it was requested to stop early with [`request_stop`](Self::request_stop).
|
||||
pub fn is_running(&mut self) -> bool {
|
||||
let ch = self.channel.regs().ch(self.channel.num());
|
||||
ch.cr().read().en()
|
||||
RingBuffer::is_running(&self.channel.regs().ch(self.channel.num()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::future::Future;
|
||||
use core::future::{poll_fn, Future};
|
||||
use core::marker::PhantomData;
|
||||
use core::pin::Pin;
|
||||
use core::sync::atomic::{fence, AtomicUsize, Ordering};
|
||||
@ -668,6 +668,42 @@ impl<'a, C: Channel> DmaCtrl for DmaCtrlImpl<'a, C> {
|
||||
}
|
||||
}
|
||||
|
||||
struct RingBuffer {}
|
||||
|
||||
impl RingBuffer {
|
||||
fn is_running(ch: &pac::dma::St) -> bool {
|
||||
ch.cr().read().en()
|
||||
}
|
||||
|
||||
fn request_stop(ch: &pac::dma::St) {
|
||||
ch.cr().write(|w| {
|
||||
w.set_teie(true);
|
||||
w.set_htie(true);
|
||||
w.set_tcie(true);
|
||||
});
|
||||
}
|
||||
|
||||
async fn stop(ch: &pac::dma::St, set_waker: &mut dyn FnMut(&Waker)) {
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
Self::request_stop(ch);
|
||||
|
||||
//wait until cr.susp reads as true
|
||||
poll_fn(|cx| {
|
||||
set_waker(cx.waker());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
if !Self::is_running(ch) {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
/// Ringbuffer for receiving data using DMA circular mode.
|
||||
pub struct ReadableRingBuffer<'a, C: Channel, W: Word> {
|
||||
cr: regs::Cr,
|
||||
@ -755,6 +791,17 @@ impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
ch.cr().write_value(self.cr);
|
||||
}
|
||||
|
||||
pub async fn stop(&mut self) {
|
||||
RingBuffer::stop(&self.channel.regs().st(self.channel.num()), &mut |waker| {
|
||||
self.set_waker(waker)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn resume(&mut self) {
|
||||
self.start();
|
||||
}
|
||||
|
||||
/// Clear all data in the ring buffer.
|
||||
pub fn clear(&mut self) {
|
||||
self.ringbuf.clear(&mut DmaCtrlImpl(self.channel.reborrow()));
|
||||
@ -930,6 +977,13 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
ch.cr().write_value(self.cr);
|
||||
}
|
||||
|
||||
pub async fn stop(&mut self) {
|
||||
RingBuffer::stop(&self.channel.regs().st(self.channel.num()), &mut |waker| {
|
||||
self.set_waker(waker)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Clear all data in the ring buffer.
|
||||
pub fn clear(&mut self) {
|
||||
self.ringbuf.clear(&mut DmaCtrlImpl(self.channel.reborrow()));
|
||||
@ -937,14 +991,9 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
|
||||
/// Write elements directly to the raw buffer.
|
||||
/// 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), OverrunError> {
|
||||
self.ringbuf.write_immediate(
|
||||
&mut DmaCtrlImpl {
|
||||
channel: self.channel.reborrow(),
|
||||
word_size: W::size(),
|
||||
},
|
||||
buf,
|
||||
)
|
||||
self.ringbuf.write_immediate(buf)
|
||||
}
|
||||
|
||||
/// Write elements from the ring buffer
|
||||
|
@ -491,7 +491,7 @@ impl RingBuffer {
|
||||
});
|
||||
}
|
||||
|
||||
async fn suspend(ch: &pac::gpdma::Channel, set_waker: &mut dyn FnMut(&Waker)) {
|
||||
async fn stop(ch: &pac::gpdma::Channel, set_waker: &mut dyn FnMut(&Waker)) {
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
Self::request_suspend(ch);
|
||||
@ -504,17 +504,15 @@ impl RingBuffer {
|
||||
|
||||
let cr = ch.cr().read();
|
||||
if cr.susp() {
|
||||
defmt::info!("Ready {}", cr.susp());
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
defmt::info!("still pending {}", cr.susp());
|
||||
Poll::Pending
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
fn resume(ch: &pac::gpdma::Channel) {
|
||||
fn start(ch: &pac::gpdma::Channel) {
|
||||
Self::clear_irqs(ch);
|
||||
ch.cr().modify(|w| {
|
||||
w.set_susp(false);
|
||||
@ -534,7 +532,7 @@ pub struct ReadableRingBuffer<'a, C: Channel, W: Word> {
|
||||
}
|
||||
|
||||
impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
pub unsafe fn new_read(
|
||||
pub unsafe fn new(
|
||||
channel: impl Peripheral<P = C> + 'a,
|
||||
request: Request,
|
||||
peri_addr: *mut W,
|
||||
@ -564,25 +562,21 @@ impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
|
||||
pub fn start(&mut self) {
|
||||
let ch = &self.channel.regs().ch(self.channel.num());
|
||||
RingBuffer::clear_irqs(ch);
|
||||
ch.cr().modify(|w| w.set_en(true));
|
||||
RingBuffer::start(ch);
|
||||
//ch.cr().modify(|w| w.set_en(true));
|
||||
}
|
||||
|
||||
pub fn request_stop(&mut self, ch: &pac::gpdma::Channel) {
|
||||
ch.cr().modify(|w| w.set_en(false));
|
||||
pub fn request_stop(&mut self) {
|
||||
RingBuffer::request_suspend(&self.channel.regs().ch(self.channel.num()));
|
||||
}
|
||||
|
||||
pub async fn suspend(&mut self) {
|
||||
RingBuffer::suspend(&self.channel.regs().ch(self.channel.num()), &mut |waker| {
|
||||
pub async fn stop(&mut self) {
|
||||
RingBuffer::stop(&self.channel.regs().ch(self.channel.num()), &mut |waker| {
|
||||
self.set_waker(waker)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn resume(&mut self) {
|
||||
RingBuffer::resume(&self.channel.regs().ch(self.channel.num()));
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.ringbuf.clear(&mut DmaCtrlImpl {
|
||||
channel: self.channel.reborrow(),
|
||||
@ -648,7 +642,7 @@ impl<'a, C: Channel, W: Word> ReadableRingBuffer<'a, C, W> {
|
||||
|
||||
impl<'a, C: Channel, W: Word> Drop for ReadableRingBuffer<'a, C, W> {
|
||||
fn drop(&mut self) {
|
||||
RingBuffer::request_suspend(&self.channel.regs().ch(self.channel.num()));
|
||||
self.request_stop();
|
||||
while self.is_running() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
@ -663,7 +657,7 @@ pub struct WritableRingBuffer<'a, C: Channel, W: Word> {
|
||||
}
|
||||
|
||||
impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
pub unsafe fn new_write(
|
||||
pub unsafe fn new(
|
||||
channel: impl Peripheral<P = C> + 'a,
|
||||
request: Request,
|
||||
peri_addr: *mut W,
|
||||
@ -692,26 +686,28 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
self.resume();
|
||||
RingBuffer::start(&self.channel.regs().ch(self.channel.num()));
|
||||
}
|
||||
|
||||
pub async fn suspend(&mut self) {
|
||||
RingBuffer::suspend(&self.channel.regs().ch(self.channel.num()), &mut |waker| {
|
||||
pub async fn stop(&mut self) {
|
||||
RingBuffer::stop(&self.channel.regs().ch(self.channel.num()), &mut |waker| {
|
||||
self.set_waker(waker)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn resume(&mut self) {
|
||||
RingBuffer::resume(&self.channel.regs().ch(self.channel.num()));
|
||||
}
|
||||
|
||||
pub fn request_stop(&mut self) {
|
||||
// reads can be stopped by disabling the enable flag
|
||||
let ch = &self.channel.regs().ch(self.channel.num());
|
||||
ch.cr().modify(|w| w.set_en(false));
|
||||
}
|
||||
|
||||
/// Write elements directly to the raw buffer.
|
||||
/// This can be used to fill the buffer before starting the DMA transfer.
|
||||
pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), OverrunError> {
|
||||
self.ringbuf.write_immediate(buf)
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.ringbuf.clear(&mut DmaCtrlImpl {
|
||||
channel: self.channel.reborrow(),
|
||||
@ -731,18 +727,6 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Write elements directly to the raw buffer.
|
||||
/// This can be used to fill the buffer before starting the DMA transfer.
|
||||
pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), OverrunError> {
|
||||
self.ringbuf.write_immediate(
|
||||
&mut DmaCtrlImpl {
|
||||
channel: self.channel.reborrow(),
|
||||
word_size: W::size(),
|
||||
},
|
||||
buf,
|
||||
)
|
||||
}
|
||||
|
||||
/// Write an exact number of elements to the ringbuffer.
|
||||
pub async fn write_exact(&mut self, buffer: &[W]) -> Result<usize, OverrunError> {
|
||||
self.ringbuf
|
||||
@ -776,7 +760,7 @@ impl<'a, C: Channel, W: Word> WritableRingBuffer<'a, C, W> {
|
||||
|
||||
impl<'a, C: Channel, W: Word> Drop for WritableRingBuffer<'a, C, W> {
|
||||
fn drop(&mut self) {
|
||||
RingBuffer::request_suspend(&self.channel.regs().ch(self.channel.num()));
|
||||
self.request_stop();
|
||||
while self.is_running() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
|
@ -264,7 +264,7 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
|
||||
}
|
||||
|
||||
/// Write elements directl to the buffer. This should be done before the DMA is started.
|
||||
pub fn write_immediate(&mut self, dma: &mut impl DmaCtrl, buffer: &[W]) -> Result<(usize, usize), OverrunError> {
|
||||
pub fn write_immediate(&mut self, buffer: &[W]) -> Result<(usize, usize), OverrunError> {
|
||||
if self.end != 0 {
|
||||
return Err(OverrunError);
|
||||
}
|
||||
|
@ -1008,17 +1008,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn suspend(&mut self) {
|
||||
pub async fn stop(&mut self) {
|
||||
match &mut self.ring_buffer {
|
||||
RingBuffer::Writable(buffer) => buffer.suspend().await,
|
||||
RingBuffer::Readable(buffer) => buffer.suspend().await,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resume(&mut self) {
|
||||
match &mut self.ring_buffer {
|
||||
RingBuffer::Writable(buffer) => buffer.resume(),
|
||||
RingBuffer::Readable(buffer) => buffer.resume(),
|
||||
RingBuffer::Writable(buffer) => buffer.stop().await,
|
||||
RingBuffer::Readable(buffer) => buffer.stop().await,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ async fn main(_spawner: Spawner) {
|
||||
m: Pllm::DIV2,
|
||||
n: Plln::MUL10,
|
||||
r: Plldiv::DIV1,
|
||||
p: Plldiv::DIV1,
|
||||
q: Plldiv::DIV1,
|
||||
});
|
||||
config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user