diff options
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | embassy-stm32f4/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32f4/src/serial.rs (renamed from embassy-stm32f4/src/uarte.rs) | 0 | ||||
| -rw-r--r-- | examples-stm32f4/Cargo.toml | 38 | ||||
| -rw-r--r-- | examples-stm32f4/src/dma_adc.rs | 125 |
5 files changed, 165 insertions, 1 deletions
diff --git a/Cargo.toml b/Cargo.toml index e1a1c34b5..be98b26f6 100644 --- a/Cargo.toml +++ b/Cargo.toml | |||
| @@ -6,6 +6,7 @@ members = [ | |||
| 6 | "embassy-stm32f4", | 6 | "embassy-stm32f4", |
| 7 | "embassy-macros", | 7 | "embassy-macros", |
| 8 | "examples", | 8 | "examples", |
| 9 | "examples-stm32f4", | ||
| 9 | ] | 10 | ] |
| 10 | 11 | ||
| 11 | exclude = [ | 12 | exclude = [ |
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs index e6d523d21..cfcb49bcb 100644 --- a/embassy-stm32f4/src/lib.rs +++ b/embassy-stm32f4/src/lib.rs | |||
| @@ -361,6 +361,6 @@ macro_rules! waker_interrupt { | |||
| 361 | // This mod MUST go first, so that the others see its macros. | 361 | // This mod MUST go first, so that the others see its macros. |
| 362 | pub(crate) mod fmt; | 362 | pub(crate) mod fmt; |
| 363 | 363 | ||
| 364 | pub mod uarte; | 364 | pub mod serial; |
| 365 | 365 | ||
| 366 | pub use cortex_m_rt::interrupt; | 366 | pub use cortex_m_rt::interrupt; |
diff --git a/embassy-stm32f4/src/uarte.rs b/embassy-stm32f4/src/serial.rs index 273c384cb..273c384cb 100644 --- a/embassy-stm32f4/src/uarte.rs +++ b/embassy-stm32f4/src/serial.rs | |||
diff --git a/examples-stm32f4/Cargo.toml b/examples-stm32f4/Cargo.toml new file mode 100644 index 000000000..0fdb21b4e --- /dev/null +++ b/examples-stm32f4/Cargo.toml | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | [package] | ||
| 2 | authors = ["Dario Nieuwenhuis <[email protected]>"] | ||
| 3 | edition = "2018" | ||
| 4 | name = "embassy-examples-stm32f4" | ||
| 5 | version = "0.1.0" | ||
| 6 | |||
| 7 | [features] | ||
| 8 | default = [ | ||
| 9 | "defmt-default", | ||
| 10 | ] | ||
| 11 | defmt-default = [] | ||
| 12 | defmt-trace = [] | ||
| 13 | defmt-debug = [] | ||
| 14 | defmt-info = [] | ||
| 15 | defmt-warn = [] | ||
| 16 | defmt-error = [] | ||
| 17 | |||
| 18 | |||
| 19 | [dependencies] | ||
| 20 | embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } | ||
| 21 | # embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f405"] } | ||
| 22 | |||
| 23 | defmt = "0.1.3" | ||
| 24 | defmt-rtt = "0.1.0" | ||
| 25 | |||
| 26 | cortex-m = { version = "0.6.3" } | ||
| 27 | cortex-m-rt = "0.6.13" | ||
| 28 | embedded-hal = { version = "0.2.4" } | ||
| 29 | panic-probe = "0.1.0" | ||
| 30 | stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f405"], git = "https://github.com/xoviat/stm32f4xx-hal.git", branch = "dma-is-done"} | ||
| 31 | futures = { version = "0.3.8", default-features = false, features = ["async-await"] } | ||
| 32 | cortex-m-rtic = "0.5" # { git = "https://github.com/rtic-rs/cortex-m-rtic", branch = "master"} | ||
| 33 | rtt-target = { version = "0.3", features = ["cortex-m"] } | ||
| 34 | |||
| 35 | |||
| 36 | [[bin]] | ||
| 37 | name = "dma_adc" | ||
| 38 | 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 000000000..110bda306 --- /dev/null +++ b/examples-stm32f4/src/dma_adc.rs | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(lang_items)] | ||
| 4 | |||
| 5 | use core::{ | ||
| 6 | panic::PanicInfo, | ||
| 7 | sync::atomic::{compiler_fence, Ordering}, | ||
| 8 | }; | ||
| 9 | |||
| 10 | use cortex_m::singleton; | ||
| 11 | use rtic::app; | ||
| 12 | // use rtt_target::{rprintln, rtt_init_print}; | ||
| 13 | use stm32f4xx_hal::{ | ||
| 14 | dma::{config::DmaConfig, Channel0, PeripheralToMemory, Stream0, StreamsTuple, Transfer}, | ||
| 15 | pac::{ADC1, DMA2, RCC}, | ||
| 16 | prelude::*, | ||
| 17 | }; | ||
| 18 | |||
| 19 | #[lang = "eh_personality"] | ||
| 20 | extern "C" fn eh_personality() {} | ||
| 21 | |||
| 22 | type DmaTransfer = | ||
| 23 | Transfer<Stream0<DMA2>, Channel0, ADC1, PeripheralToMemory, &'static mut [u16; 128]>; | ||
| 24 | |||
| 25 | #[app(device = stm32f4xx_hal::pac, peripherals = true)] | ||
| 26 | const APP: () = { | ||
| 27 | struct Resources { | ||
| 28 | transfer: DmaTransfer, | ||
| 29 | triple_buffer: Option<&'static mut [u16; 128]>, | ||
| 30 | } | ||
| 31 | |||
| 32 | #[init] | ||
| 33 | fn init(cx: init::Context) -> init::LateResources { | ||
| 34 | let rcc = cx.device.RCC.constrain(); | ||
| 35 | |||
| 36 | // rtt_init_print!(); | ||
| 37 | // rprintln!("Init"); | ||
| 38 | |||
| 39 | let _clocks = rcc | ||
| 40 | .cfgr | ||
| 41 | .sysclk(84.mhz()) | ||
| 42 | .pclk2(28.mhz()) | ||
| 43 | .pclk1(28.mhz()) | ||
| 44 | .freeze(); | ||
| 45 | |||
| 46 | let gpioa = cx.device.GPIOA.split(); | ||
| 47 | let _pa0 = gpioa.pa0.into_analog(); | ||
| 48 | |||
| 49 | let stream_0 = StreamsTuple::new(cx.device.DMA2).0; | ||
| 50 | let config = DmaConfig::default() | ||
| 51 | .transfer_complete_interrupt(true) | ||
| 52 | .memory_increment(true) | ||
| 53 | .double_buffer(true); | ||
| 54 | |||
| 55 | let rcc = unsafe { &*RCC::ptr() }; | ||
| 56 | rcc.apb2enr.modify(|_, w| w.adc1en().enabled()); | ||
| 57 | rcc.apb2rstr.modify(|_, w| w.adcrst().set_bit()); | ||
| 58 | rcc.apb2rstr.modify(|_, w| w.adcrst().clear_bit()); | ||
| 59 | let adc = cx.device.ADC1; | ||
| 60 | adc.cr2.modify(|_, w| { | ||
| 61 | w.dma() | ||
| 62 | .enabled() | ||
| 63 | .cont() | ||
| 64 | .continuous() | ||
| 65 | .dds() | ||
| 66 | .continuous() | ||
| 67 | .adon() | ||
| 68 | .enabled() | ||
| 69 | }); | ||
| 70 | |||
| 71 | let first_buffer = singleton!(: [u16; 128] = [0; 128]).unwrap(); | ||
| 72 | let second_buffer = singleton!(: [u16; 128] = [0; 128]).unwrap(); | ||
| 73 | let triple_buffer = Some(singleton!(: [u16; 128] = [0; 128]).unwrap()); | ||
| 74 | |||
| 75 | let transfer = Transfer::init(stream_0, adc, first_buffer, Some(second_buffer), config); | ||
| 76 | |||
| 77 | // rprintln!("Finished init"); | ||
| 78 | init::LateResources { | ||
| 79 | transfer, | ||
| 80 | triple_buffer, | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | #[idle(resources = [transfer])] | ||
| 85 | fn idle(mut cx: idle::Context) -> ! { | ||
| 86 | cx.resources.transfer.lock(|shared| { | ||
| 87 | shared.start(|adc| { | ||
| 88 | adc.cr2.modify(|_, w| w.swstart().start()); | ||
| 89 | }); | ||
| 90 | }); | ||
| 91 | // rprintln!("DMA started"); | ||
| 92 | loop { | ||
| 93 | compiler_fence(Ordering::SeqCst); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | #[task(binds = DMA2_STREAM0, priority = 2, resources = [transfer, triple_buffer])] | ||
| 98 | fn dma(cx: dma::Context) { | ||
| 99 | static mut COUNT: usize = 0; | ||
| 100 | |||
| 101 | let triple = cx.resources.triple_buffer.take().unwrap(); | ||
| 102 | let buf = cx | ||
| 103 | .resources | ||
| 104 | .transfer | ||
| 105 | .next_transfer(triple) | ||
| 106 | .map_err(|_| {}) | ||
| 107 | .unwrap() | ||
| 108 | .0; | ||
| 109 | if *COUNT % (1 << 14) == 0 { | ||
| 110 | // rprintln!("Buf: {:?}", &buf[0..10]); | ||
| 111 | } | ||
| 112 | *COUNT += 1; | ||
| 113 | *cx.resources.triple_buffer = Some(buf); | ||
| 114 | } | ||
| 115 | }; | ||
| 116 | |||
| 117 | #[inline(never)] | ||
| 118 | #[panic_handler] | ||
| 119 | fn panic(info: &PanicInfo) -> ! { | ||
| 120 | cortex_m::interrupt::disable(); | ||
| 121 | // rprintln!("{}", info); | ||
| 122 | loop { | ||
| 123 | compiler_fence(Ordering::SeqCst); | ||
| 124 | } | ||
| 125 | } | ||
