rp: add initial version
This commit is contained in:
87
embassy-rp/src/dma.rs
Normal file
87
embassy-rp/src/dma.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
use defmt::{assert, *};
|
||||
|
||||
use crate::{pac, peripherals};
|
||||
use pac::dma::vals;
|
||||
|
||||
pub struct Dma<T: Channel> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T: Channel> Dma<T> {
|
||||
pub fn copy(inner: T, from: &[u32], to: &mut [u32]) {
|
||||
assert!(from.len() == to.len());
|
||||
|
||||
unsafe {
|
||||
let p = inner.regs();
|
||||
|
||||
p.read_addr().write_value(from.as_ptr() as u32);
|
||||
p.write_addr().write_value(to.as_mut_ptr() as u32);
|
||||
p.trans_count().write_value(from.len() as u32);
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
p.ctrl_trig().write(|w| {
|
||||
w.set_data_size(vals::DataSize::SIZE_WORD);
|
||||
w.set_incr_read(true);
|
||||
w.set_incr_write(true);
|
||||
w.set_chain_to(inner.number());
|
||||
w.set_en(true);
|
||||
});
|
||||
|
||||
while p.ctrl_trig().read().busy() {}
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod sealed {
|
||||
use super::*;
|
||||
|
||||
pub trait Channel {
|
||||
fn number(&self) -> u8;
|
||||
|
||||
fn regs(&self) -> pac::dma::Channel {
|
||||
pac::DMA.ch(self.number() as _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Channel: sealed::Channel {}
|
||||
|
||||
pub struct AnyChannel {
|
||||
number: u8,
|
||||
}
|
||||
|
||||
impl Channel for AnyChannel {}
|
||||
impl sealed::Channel for AnyChannel {
|
||||
fn number(&self) -> u8 {
|
||||
self.number
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! channel {
|
||||
($type:ident, $num:expr) => {
|
||||
impl Channel for peripherals::$type {}
|
||||
impl sealed::Channel for peripherals::$type {
|
||||
fn number(&self) -> u8 {
|
||||
$num
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
channel!(DMA_CH0, 0);
|
||||
channel!(DMA_CH1, 1);
|
||||
channel!(DMA_CH2, 2);
|
||||
channel!(DMA_CH3, 3);
|
||||
channel!(DMA_CH4, 4);
|
||||
channel!(DMA_CH5, 5);
|
||||
channel!(DMA_CH6, 6);
|
||||
channel!(DMA_CH7, 7);
|
||||
channel!(DMA_CH8, 8);
|
||||
channel!(DMA_CH9, 9);
|
||||
channel!(DMA_CH10, 10);
|
||||
channel!(DMA_CH11, 11);
|
Reference in New Issue
Block a user