static DMA ctrl block placement
All checks were successful
Rust/va416xx-rs/pipeline/head This commit looks good
All checks were successful
Rust/va416xx-rs/pipeline/head This commit looks good
This commit is contained in:
parent
01341edc91
commit
16d2856fb2
@ -17,11 +17,14 @@ use va416xx_hal::{
|
|||||||
prelude::*,
|
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_DONE_FLAG: Mutex<Cell<bool>> = Mutex::new(Cell::new(false));
|
||||||
static DMA_ACTIVE_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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
rtt_init_print!();
|
rtt_init_print!();
|
||||||
@ -35,9 +38,11 @@ fn main() -> ! {
|
|||||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||||
.freeze(&mut dp.sysconfig)
|
.freeze(&mut dp.sysconfig)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let dma_ctrl_block =
|
// Safety: The DMA control block has an alignment rule of 128 and we constructed it directly
|
||||||
DmaCtrlBlock::new_at_addr(DMA_CTRL_BLOCK_ADDR).expect("error creating DMA control block");
|
// statically.
|
||||||
let dma = Dma::new(&mut dp.sysconfig, dp.dma, DmaCfg::default(), dma_ctrl_block)
|
let dma = Dma::new(&mut dp.sysconfig, dp.dma, DmaCfg::default(), unsafe {
|
||||||
|
core::ptr::addr_of_mut!(DMA_CTRL_BLOCK)
|
||||||
|
})
|
||||||
.expect("error creating DMA");
|
.expect("error creating DMA");
|
||||||
let (mut dma0, _, _, _) = dma.split();
|
let (mut dma0, _, _, _) = dma.split();
|
||||||
let mut delay_ms = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
|
let mut delay_ms = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
|
||||||
|
@ -118,22 +118,42 @@ pub struct DmaChannelControl {
|
|||||||
padding: u32,
|
padding: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DmaChannelControl {
|
impl DmaChannelControl {
|
||||||
fn default() -> Self {
|
const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
src_end_ptr: Default::default(),
|
src_end_ptr: 0,
|
||||||
dest_end_ptr: Default::default(),
|
dest_end_ptr: 0,
|
||||||
cfg: ChannelConfig(0),
|
cfg: ChannelConfig(0),
|
||||||
padding: Default::default(),
|
padding: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Default for DmaChannelControl {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[repr(align(128))]
|
||||||
pub struct DmaCtrlBlock {
|
pub struct DmaCtrlBlock {
|
||||||
pub pri: [DmaChannelControl; 4],
|
pub pri: [DmaChannelControl; 4],
|
||||||
pub alt: [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 {
|
impl DmaCtrlBlock {
|
||||||
/// This function creates a DMA control block at the specified memory address.
|
/// This function creates a DMA control block at the specified memory address.
|
||||||
///
|
///
|
||||||
@ -145,15 +165,7 @@ impl DmaCtrlBlock {
|
|||||||
return Err(InvalidCtrlBlockAddr);
|
return Err(InvalidCtrlBlockAddr);
|
||||||
}
|
}
|
||||||
let ctrl_block_ptr = addr as *mut DmaCtrlBlock;
|
let ctrl_block_ptr = addr as *mut DmaCtrlBlock;
|
||||||
unsafe {
|
unsafe { core::ptr::write(ctrl_block_ptr, DmaCtrlBlock::default()) }
|
||||||
core::ptr::write(
|
|
||||||
ctrl_block_ptr,
|
|
||||||
DmaCtrlBlock {
|
|
||||||
pri: [DmaChannelControl::default(); 4],
|
|
||||||
alt: [DmaChannelControl::default(); 4],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Ok(ctrl_block_ptr)
|
Ok(ctrl_block_ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,7 +400,13 @@ impl DmaChannel {
|
|||||||
impl Dma {
|
impl Dma {
|
||||||
/// Create a new DMA instance.
|
/// 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(
|
pub fn new(
|
||||||
syscfg: &mut pac::Sysconfig,
|
syscfg: &mut pac::Sysconfig,
|
||||||
dma: pac::Dma,
|
dma: pac::Dma,
|
||||||
|
Loading…
Reference in New Issue
Block a user