aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/bdma.rs45
-rw-r--r--embassy-stm32/src/dma/dma.rs13
-rw-r--r--examples/stm32h7/src/bin/usart_dma.rs100
m---------stm32-data0
4 files changed, 114 insertions, 44 deletions
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index c6e77488d..26adda089 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -139,7 +139,7 @@ unsafe fn on_irq() {
139/// safety: must be called only once 139/// safety: must be called only once
140pub(crate) unsafe fn init() { 140pub(crate) unsafe fn init() {
141 pac::interrupts! { 141 pac::interrupts! {
142 (DMA, $irq:ident) => { 142 (BDMA, $irq:ident) => {
143 crate::interrupt::$irq::steal().enable(); 143 crate::interrupt::$irq::steal().enable();
144 }; 144 };
145 } 145 }
@@ -209,52 +209,11 @@ pac::bdma_channels! {
209 }; 209 };
210} 210}
211 211
212// HACK: on stm32h7 "DMA" interrupts are for DMA, not BDMA, so this
213// would cause duplicate interrupt definitions. Do it manually insted
214#[cfg(not(rcc_h7))]
215pac::interrupts! { 212pac::interrupts! {
216 (DMA, $irq:ident) => { 213 (BDMA, $irq:ident) => {
217 #[crate::interrupt] 214 #[crate::interrupt]
218 unsafe fn $irq () { 215 unsafe fn $irq () {
219 on_irq() 216 on_irq()
220 } 217 }
221 }; 218 };
222} 219}
223
224#[cfg(rcc_h7)]
225mod _if_h7 {
226 use super::*;
227
228 #[crate::interrupt]
229 unsafe fn BDMA_CHANNEL0() {
230 on_irq()
231 }
232 #[crate::interrupt]
233 unsafe fn BDMA_CHANNEL1() {
234 on_irq()
235 }
236 #[crate::interrupt]
237 unsafe fn BDMA_CHANNEL2() {
238 on_irq()
239 }
240 #[crate::interrupt]
241 unsafe fn BDMA_CHANNEL3() {
242 on_irq()
243 }
244 #[crate::interrupt]
245 unsafe fn BDMA_CHANNEL4() {
246 on_irq()
247 }
248 #[crate::interrupt]
249 unsafe fn BDMA_CHANNEL5() {
250 on_irq()
251 }
252 #[crate::interrupt]
253 unsafe fn BDMA_CHANNEL6() {
254 on_irq()
255 }
256 #[crate::interrupt]
257 unsafe fn BDMA_CHANNEL7() {
258 on_irq()
259 }
260}
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index b0df6ddc5..1d6f7aee8 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -3,7 +3,7 @@ use core::task::Poll;
3use atomic_polyfill::{AtomicU8, Ordering}; 3use atomic_polyfill::{AtomicU8, Ordering};
4use core::future::Future; 4use core::future::Future;
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::util::AtomicWaker; 6use embassy::util::{AtomicWaker, OnDrop};
7use futures::future::poll_fn; 7use futures::future::poll_fn;
8 8
9use crate::interrupt; 9use crate::interrupt;
@@ -38,6 +38,7 @@ static STATE: State = State::new();
38 38
39//async unsafe fn do_transfer(ch: &mut impl Channel, ch_func: u8, src: *const u8, dst: &mut [u8]) { 39//async unsafe fn do_transfer(ch: &mut impl Channel, ch_func: u8, src: *const u8, dst: &mut [u8]) {
40 40
41#[allow(unused)]
41pub(crate) async unsafe fn do_transfer( 42pub(crate) async unsafe fn do_transfer(
42 dma: pac::dma::Dma, 43 dma: pac::dma::Dma,
43 channel_number: u8, 44 channel_number: u8,
@@ -59,6 +60,15 @@ pub(crate) async unsafe fn do_transfer(
59 60
60 let ch = dma.st(channel_number as _); 61 let ch = dma.st(channel_number as _);
61 62
63 let on_drop = OnDrop::new(|| unsafe {
64 ch.cr().modify(|w| {
65 w.set_tcie(false);
66 w.set_teie(false);
67 w.set_en(false);
68 });
69 while ch.cr().read().en() {}
70 });
71
62 #[cfg(dmamux)] 72 #[cfg(dmamux)]
63 super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request); 73 super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request);
64 74
@@ -74,6 +84,7 @@ pub(crate) async unsafe fn do_transfer(
74 w.set_pinc(vals::Inc::FIXED); 84 w.set_pinc(vals::Inc::FIXED);
75 w.set_teie(true); 85 w.set_teie(true);
76 w.set_tcie(true); 86 w.set_tcie(true);
87 w.set_trbuff(true);
77 w.set_en(true); 88 w.set_en(true);
78 89
79 #[cfg(dma_v2)] 90 #[cfg(dma_v2)]
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
new file mode 100644
index 000000000..fd5da8b35
--- /dev/null
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -0,0 +1,100 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7#![allow(incomplete_features)]
8
9#[path = "../example_common.rs"]
10mod example_common;
11use core::fmt::Write;
12use embassy::executor::Executor;
13use embassy::time::Clock;
14use embassy::util::Forever;
15use embassy_stm32::dma::NoDma;
16use embassy_stm32::usart::{Config, Uart};
17use example_common::*;
18use embassy_traits::uart::Write as _Write;
19
20use hal::prelude::*;
21use stm32h7xx_hal as hal;
22
23use cortex_m_rt::entry;
24use stm32h7::stm32h743 as pac;
25use heapless::String;
26
27#[embassy::task]
28async fn main_task() {
29 let p = embassy_stm32::init(Default::default());
30
31 let config = Config::default();
32 let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, p.DMA1_0, NoDma, config);
33
34 for n in 0u32.. {
35 let mut s: String<128> = String::new();
36 core::write!(&mut s, "Hello DMA World {}!\r\n", n).unwrap();
37
38 usart.write(s.as_bytes()).await.ok();
39
40 info!("wrote DMA");
41 }
42
43}
44
45struct ZeroClock;
46
47impl Clock for ZeroClock {
48 fn now(&self) -> u64 {
49 0
50 }
51}
52
53static EXECUTOR: Forever<Executor> = Forever::new();
54
55#[entry]
56fn main() -> ! {
57 info!("Hello World!");
58
59 let pp = pac::Peripherals::take().unwrap();
60
61 let pwrcfg = pp.PWR.constrain().freeze();
62
63 let rcc = pp.RCC.constrain();
64
65 rcc.sys_ck(96.mhz())
66 .pclk1(48.mhz())
67 .pclk2(48.mhz())
68 .pclk3(48.mhz())
69 .pclk4(48.mhz())
70 .pll1_q_ck(48.mhz())
71 .freeze(pwrcfg, &pp.SYSCFG);
72
73 let pp = unsafe { pac::Peripherals::steal() };
74
75 pp.DBGMCU.cr.modify(|_, w| {
76 w.dbgsleep_d1().set_bit();
77 w.dbgstby_d1().set_bit();
78 w.dbgstop_d1().set_bit();
79 w.d1dbgcken().set_bit();
80 w
81 });
82
83 pp.RCC.ahb4enr.modify(|_, w| {
84 w.gpioaen().set_bit();
85 w.gpioben().set_bit();
86 w.gpiocen().set_bit();
87 w.gpioden().set_bit();
88 w.gpioeen().set_bit();
89 w.gpiofen().set_bit();
90 w
91 });
92
93 unsafe { embassy::time::set_clock(&ZeroClock) };
94
95 let executor = EXECUTOR.put(Executor::new());
96
97 executor.run(|spawner| {
98 unwrap!(spawner.spawn(main_task()));
99 })
100}
diff --git a/stm32-data b/stm32-data
Subproject 32ca79020ec7523fe4c3fcfc02006cb1ea637a1 Subproject ddd0f206e22143436230dca6d3fcfc0e02e55df