Skip to content

Instantly share code, notes, and snippets.

@chmanie
Last active July 18, 2022 20:34
Show Gist options
  • Save chmanie/f94559cbe8c72c16c69ff1f3aa6dff84 to your computer and use it in GitHub Desktop.
Save chmanie/f94559cbe8c72c16c69ff1f3aa6dff84 to your computer and use it in GitHub Desktop.
RP2040 Simple DMA Example
#![no_std]
#![no_main]
/**
* Basic RP2040 DMA example, just copying one value in memory to another place in memory using DMA
*/
use bsp::entry;
use cortex_m::singleton;
use defmt::*;
use defmt_rtt as _;
use panic_probe as _;
use rp_pico as bsp;
use bsp::hal::{clocks::init_clocks_and_plls, pac, watchdog::Watchdog};
#[entry]
fn main() -> ! {
info!("Program start");
let src: &'static mut u8 = singleton!(: u8 = 42).unwrap();
let dest: &'static mut u8 = singleton!(: u8 = 0).unwrap();
let mut pac = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
// External high-speed crystal on the pico board is 12Mhz
let external_xtal_freq_hz = 12_000_000u32;
let _clocks = init_clocks_and_plls(
external_xtal_freq_hz,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
// Enable DMA peripheral
pac.RESETS.reset.modify(|_, w| w.dma().clear_bit());
while pac.RESETS.reset_done.read().dma().bit_is_clear() {}
info!("RESETTING DMA");
pac.DMA.chan_abort.write(|w| unsafe { w.bits(1) });
while pac.DMA.chan_abort.read().bits() != 0 {}
info!("DMA RESET");
// Set DMA source address
pac.DMA.ch[0]
.ch_read_addr
.modify(|_, w| unsafe { w.bits(src as *const u8 as u32) });
// Set DMA destination address
pac.DMA.ch[0]
.ch_write_addr
.modify(|_, w| unsafe { w.bits(dest as *const u8 as u32) });
// Set DMA transfer count (just 1)
pac.DMA.ch[0]
.ch_trans_count
.modify(|_, w| unsafe { w.bits(1) });
// Configure and start DMA channel 0
pac.DMA.ch[0].ch_ctrl_trig.modify(|_, w| unsafe {
w
// Set unpaced timer
.treq_sel()
.bits(0x3f)
// Set data size to 0x0 (8 bit)
.data_size()
.bits(0x0)
// Chain to itself (do not chain)
.chain_to()
.bits(0)
// Enable channel 0
.en()
.bit(true)
});
// Wait for DMA transfer to be done
while pac.DMA.ch[0].ch_ctrl_trig.read().busy().bit_is_set() {}
// This should now be the value of src
info!("DEST VALUE: {}", dest);
loop {
cortex_m::asm::nop();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment