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::*,
|
||||
};
|
||||
|
||||
// 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];
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user