static DMA ctrl block placement
All checks were successful
Rust/va416xx-rs/pipeline/head This commit looks good

This commit is contained in:
Robin Müller 2024-07-03 00:01:33 +02:00
parent 01341edc91
commit 16d2856fb2
Signed by: muellerr
GPG Key ID: A649FB78196E3849
2 changed files with 44 additions and 21 deletions

View File

@ -17,11 +17,14 @@ use va416xx_hal::{
prelude::*,
};
// Place the DMA control block in SRAM1
const DMA_CTRL_BLOCK_ADDR: u32 = 0x2000_0000;
static DMA_DONE_FLAG: Mutex<Cell<bool>> = Mutex::new(Cell::new(false));
static DMA_ACTIVE_FLAG: Mutex<Cell<bool>> = Mutex::new(Cell::new(false));
// Place the DMA control block into SRAM1 statically. This section needs to be defined in
// memory.x
#[link_section = ".sram1"]
static mut DMA_CTRL_BLOCK: DmaCtrlBlock = DmaCtrlBlock::new();
#[entry]
fn main() -> ! {
rtt_init_print!();
@ -35,10 +38,12 @@ fn main() -> ! {
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
.freeze(&mut dp.sysconfig)
.unwrap();
let dma_ctrl_block =
DmaCtrlBlock::new_at_addr(DMA_CTRL_BLOCK_ADDR).expect("error creating DMA control block");
let dma = Dma::new(&mut dp.sysconfig, dp.dma, DmaCfg::default(), dma_ctrl_block)
.expect("error creating DMA");
// Safety: The DMA control block has an alignment rule of 128 and we constructed it directly
// statically.
let dma = Dma::new(&mut dp.sysconfig, dp.dma, DmaCfg::default(), unsafe {
core::ptr::addr_of_mut!(DMA_CTRL_BLOCK)
})
.expect("error creating DMA");
let (mut dma0, _, _, _) = dma.split();
let mut delay_ms = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
let mut src_buf_8_bit: [u8; 65] = [0; 65];

View File

@ -118,22 +118,42 @@ pub struct DmaChannelControl {
padding: u32,
}
impl Default for DmaChannelControl {
fn default() -> Self {
impl DmaChannelControl {
const fn new() -> Self {
Self {
src_end_ptr: Default::default(),
dest_end_ptr: Default::default(),
src_end_ptr: 0,
dest_end_ptr: 0,
cfg: ChannelConfig(0),
padding: Default::default(),
padding: 0,
}
}
}
impl Default for DmaChannelControl {
fn default() -> Self {
Self::new()
}
}
#[repr(C)]
#[repr(align(128))]
pub struct DmaCtrlBlock {
pub pri: [DmaChannelControl; 4],
pub alt: [DmaChannelControl; 4],
}
impl DmaCtrlBlock {
pub const fn new() -> Self {
Self {
pri: [DmaChannelControl::new(); 4],
alt: [DmaChannelControl::new(); 4],
}
}
}
impl Default for DmaCtrlBlock {
fn default() -> Self {
Self::new()
}
}
impl DmaCtrlBlock {
/// This function creates a DMA control block at the specified memory address.
///
@ -145,15 +165,7 @@ impl DmaCtrlBlock {
return Err(InvalidCtrlBlockAddr);
}
let ctrl_block_ptr = addr as *mut DmaCtrlBlock;
unsafe {
core::ptr::write(
ctrl_block_ptr,
DmaCtrlBlock {
pri: [DmaChannelControl::default(); 4],
alt: [DmaChannelControl::default(); 4],
},
)
}
unsafe { core::ptr::write(ctrl_block_ptr, DmaCtrlBlock::default()) }
Ok(ctrl_block_ptr)
}
}
@ -388,7 +400,13 @@ impl DmaChannel {
impl Dma {
/// Create a new DMA instance.
///
/// You can use [DmaCtrlBlock::new_at_addr] to create the DMA control block at a specific address.
/// You can also place the [DmaCtrlBlock] statically using a global static mutable
/// instance and the [DmaCtrlBlock::new] const constructor This also allows to place the control
/// block in a memory section using the [link_section](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
/// attribute and then creating a mutable pointer to it using [core::ptr::addr_of_mut].
///
/// Alternatively, the [DmaCtrlBlock::new_at_addr] function can be used to create the DMA
/// control block at a specific address.
pub fn new(
syscfg: &mut pac::Sysconfig,
dma: pac::Dma,