diff --git a/Cargo.toml b/Cargo.toml index e1a1c34b..be98b26f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "embassy-stm32f4", "embassy-macros", "examples", + "examples-stm32f4", ] exclude = [ diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs index e6d523d2..cfcb49bc 100644 --- a/embassy-stm32f4/src/lib.rs +++ b/embassy-stm32f4/src/lib.rs @@ -361,6 +361,6 @@ macro_rules! waker_interrupt { // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; -pub mod uarte; +pub mod serial; pub use cortex_m_rt::interrupt; diff --git a/embassy-stm32f4/src/uarte.rs b/embassy-stm32f4/src/serial.rs similarity index 100% rename from embassy-stm32f4/src/uarte.rs rename to embassy-stm32f4/src/serial.rs diff --git a/examples-stm32f4/Cargo.toml b/examples-stm32f4/Cargo.toml new file mode 100644 index 00000000..0fdb21b4 --- /dev/null +++ b/examples-stm32f4/Cargo.toml @@ -0,0 +1,38 @@ +[package] +authors = ["Dario Nieuwenhuis "] +edition = "2018" +name = "embassy-examples-stm32f4" +version = "0.1.0" + +[features] +default = [ + "defmt-default", +] +defmt-default = [] +defmt-trace = [] +defmt-debug = [] +defmt-info = [] +defmt-warn = [] +defmt-error = [] + + +[dependencies] +embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } +# embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f405"] } + +defmt = "0.1.3" +defmt-rtt = "0.1.0" + +cortex-m = { version = "0.6.3" } +cortex-m-rt = "0.6.13" +embedded-hal = { version = "0.2.4" } +panic-probe = "0.1.0" +stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f405"], git = "https://github.com/xoviat/stm32f4xx-hal.git", branch = "dma-is-done"} +futures = { version = "0.3.8", default-features = false, features = ["async-await"] } +cortex-m-rtic = "0.5" # { git = "https://github.com/rtic-rs/cortex-m-rtic", branch = "master"} +rtt-target = { version = "0.3", features = ["cortex-m"] } + + +[[bin]] +name = "dma_adc" +path = "src/dma_adc.rs" \ No newline at end of file diff --git a/examples-stm32f4/src/dma_adc.rs b/examples-stm32f4/src/dma_adc.rs new file mode 100644 index 00000000..110bda30 --- /dev/null +++ b/examples-stm32f4/src/dma_adc.rs @@ -0,0 +1,125 @@ +#![no_std] +#![no_main] +#![feature(lang_items)] + +use core::{ + panic::PanicInfo, + sync::atomic::{compiler_fence, Ordering}, +}; + +use cortex_m::singleton; +use rtic::app; +// use rtt_target::{rprintln, rtt_init_print}; +use stm32f4xx_hal::{ + dma::{config::DmaConfig, Channel0, PeripheralToMemory, Stream0, StreamsTuple, Transfer}, + pac::{ADC1, DMA2, RCC}, + prelude::*, +}; + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} + +type DmaTransfer = + Transfer, Channel0, ADC1, PeripheralToMemory, &'static mut [u16; 128]>; + +#[app(device = stm32f4xx_hal::pac, peripherals = true)] +const APP: () = { + struct Resources { + transfer: DmaTransfer, + triple_buffer: Option<&'static mut [u16; 128]>, + } + + #[init] + fn init(cx: init::Context) -> init::LateResources { + let rcc = cx.device.RCC.constrain(); + + // rtt_init_print!(); + // rprintln!("Init"); + + let _clocks = rcc + .cfgr + .sysclk(84.mhz()) + .pclk2(28.mhz()) + .pclk1(28.mhz()) + .freeze(); + + let gpioa = cx.device.GPIOA.split(); + let _pa0 = gpioa.pa0.into_analog(); + + let stream_0 = StreamsTuple::new(cx.device.DMA2).0; + let config = DmaConfig::default() + .transfer_complete_interrupt(true) + .memory_increment(true) + .double_buffer(true); + + let rcc = unsafe { &*RCC::ptr() }; + rcc.apb2enr.modify(|_, w| w.adc1en().enabled()); + rcc.apb2rstr.modify(|_, w| w.adcrst().set_bit()); + rcc.apb2rstr.modify(|_, w| w.adcrst().clear_bit()); + let adc = cx.device.ADC1; + adc.cr2.modify(|_, w| { + w.dma() + .enabled() + .cont() + .continuous() + .dds() + .continuous() + .adon() + .enabled() + }); + + let first_buffer = singleton!(: [u16; 128] = [0; 128]).unwrap(); + let second_buffer = singleton!(: [u16; 128] = [0; 128]).unwrap(); + let triple_buffer = Some(singleton!(: [u16; 128] = [0; 128]).unwrap()); + + let transfer = Transfer::init(stream_0, adc, first_buffer, Some(second_buffer), config); + + // rprintln!("Finished init"); + init::LateResources { + transfer, + triple_buffer, + } + } + + #[idle(resources = [transfer])] + fn idle(mut cx: idle::Context) -> ! { + cx.resources.transfer.lock(|shared| { + shared.start(|adc| { + adc.cr2.modify(|_, w| w.swstart().start()); + }); + }); + // rprintln!("DMA started"); + loop { + compiler_fence(Ordering::SeqCst); + } + } + + #[task(binds = DMA2_STREAM0, priority = 2, resources = [transfer, triple_buffer])] + fn dma(cx: dma::Context) { + static mut COUNT: usize = 0; + + let triple = cx.resources.triple_buffer.take().unwrap(); + let buf = cx + .resources + .transfer + .next_transfer(triple) + .map_err(|_| {}) + .unwrap() + .0; + if *COUNT % (1 << 14) == 0 { + // rprintln!("Buf: {:?}", &buf[0..10]); + } + *COUNT += 1; + *cx.resources.triple_buffer = Some(buf); + } +}; + +#[inline(never)] +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + cortex_m::interrupt::disable(); + // rprintln!("{}", info); + loop { + compiler_fence(Ordering::SeqCst); + } +}