aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--embassy-stm32f4-examples/Cargo.toml39
-rw-r--r--embassy-stm32f4-examples/src/serial.rs64
-rw-r--r--embassy-stm32f4/Cargo.toml43
-rw-r--r--embassy-stm32f4/src/fmt.rs118
-rw-r--r--embassy-stm32f4/src/interrupt.rs193
-rw-r--r--embassy-stm32f4/src/lib.rs317
-rw-r--r--embassy-stm32f4/src/serial.rs224
8 files changed, 1000 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 5ba9ba7d3..3e036b610 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,9 @@
3members = [ 3members = [
4 "embassy", 4 "embassy",
5 "embassy-nrf", 5 "embassy-nrf",
6 "embassy-stm32f4",
6 "embassy-nrf-examples", 7 "embassy-nrf-examples",
8 "embassy-stm32f4-examples",
7 "embassy-macros", 9 "embassy-macros",
8] 10]
9 11
diff --git a/embassy-stm32f4-examples/Cargo.toml b/embassy-stm32f4-examples/Cargo.toml
new file mode 100644
index 000000000..6502a77a5
--- /dev/null
+++ b/embassy-stm32f4-examples/Cargo.toml
@@ -0,0 +1,39 @@
1[package]
2authors = ["Dario Nieuwenhuis <[email protected]>"]
3edition = "2018"
4name = "embassy-stm32f4-examples"
5version = "0.1.0"
6
7[features]
8default = [
9 "defmt-default",
10]
11defmt-default = []
12defmt-trace = []
13defmt-debug = []
14defmt-info = []
15defmt-warn = []
16defmt-error = []
17
18
19[dependencies]
20embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] }
21embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f405"] }
22
23defmt = "0.1.3"
24defmt-rtt = "0.1.0"
25
26cortex-m = { version = "0.6.3" }
27cortex-m-rt = "0.6.13"
28embedded-hal = { version = "0.2.4" }
29panic-probe = "0.1.0"
30stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f405"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
31futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
32cortex-m-rtic = "0.5"
33rtt-target = { version = "0.3", features = ["cortex-m"] }
34
35
36
37[[bin]]
38name = "serial"
39path = "src/serial.rs" \ No newline at end of file
diff --git a/embassy-stm32f4-examples/src/serial.rs b/embassy-stm32f4-examples/src/serial.rs
new file mode 100644
index 000000000..baed2e525
--- /dev/null
+++ b/embassy-stm32f4-examples/src/serial.rs
@@ -0,0 +1,64 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(type_alias_impl_trait)]
5
6// extern crate panic_halt;
7
8use cortex_m::singleton;
9use cortex_m_rt::entry;
10use embassy::executor::{task, Executor};
11use embassy::util::Forever;
12use embassy_stm32f4::interrupt;
13use embassy_stm32f4::serial;
14use stm32f4xx_hal::stm32;
15use stm32f4xx_hal::{prelude::*, serial::config};
16
17#[task]
18async fn run(dp: stm32::Peripherals, cp: cortex_m::Peripherals) {
19 // https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1
20 let gpioa = dp.GPIOA.split();
21 let rcc = dp.RCC.constrain();
22
23 let clocks = rcc
24 .cfgr
25 .use_hse(16.mhz())
26 .sysclk(48.mhz())
27 .pclk1(24.mhz())
28 .freeze();
29
30 let mut serial = serial::Serial::new(
31 gpioa.pa9.into_alternate_af7(),
32 gpioa.pa10.into_alternate_af7(),
33 interrupt::take!(DMA2_STREAM7),
34 interrupt::take!(DMA2_STREAM2),
35 interrupt::take!(USART1),
36 dp.DMA2,
37 dp.USART1,
38 config::Parity::ParityNone,
39 9600.bps(),
40 clocks,
41 );
42
43 let buf = singleton!(: [u8; 30] = [0; 30]).unwrap();
44
45 buf[5] = 0x01;
46
47 serial.send(buf).await;
48}
49
50static EXECUTOR: Forever<Executor> = Forever::new();
51
52#[entry]
53fn main() -> ! {
54 let dp = stm32::Peripherals::take().unwrap();
55 let cp = cortex_m::peripheral::Peripherals::take().unwrap();
56
57 let executor = EXECUTOR.put(Executor::new(cortex_m::asm::sev));
58 executor.spawn(run(dp, cp));
59
60 loop {
61 executor.run();
62 cortex_m::asm::wfe();
63 }
64}
diff --git a/embassy-stm32f4/Cargo.toml b/embassy-stm32f4/Cargo.toml
new file mode 100644
index 000000000..44cf3db9d
--- /dev/null
+++ b/embassy-stm32f4/Cargo.toml
@@ -0,0 +1,43 @@
1[package]
2name = "embassy-stm32f4"
3version = "0.1.0"
4authors = ["Dario Nieuwenhuis <[email protected]>"]
5edition = "2018"
6
7[features]
8defmt-trace = [ ]
9defmt-debug = [ ]
10defmt-info = [ ]
11defmt-warn = [ ]
12defmt-error = [ ]
13
14stm32f401 = ["stm32f4xx-hal/stm32f401"]
15stm32f405 = ["stm32f4xx-hal/stm32f405"]
16stm32f407 = ["stm32f4xx-hal/stm32f407"]
17stm32f410 = ["stm32f4xx-hal/stm32f410"]
18stm32f411 = ["stm32f4xx-hal/stm32f411"]
19stm32f412 = ["stm32f4xx-hal/stm32f412"]
20stm32f413 = ["stm32f4xx-hal/stm32f413"]
21stm32f415 = ["stm32f4xx-hal/stm32f405"]
22stm32f417 = ["stm32f4xx-hal/stm32f407"]
23stm32f423 = ["stm32f4xx-hal/stm32f413"]
24stm32f427 = ["stm32f4xx-hal/stm32f427"]
25stm32f429 = ["stm32f4xx-hal/stm32f429"]
26stm32f437 = ["stm32f4xx-hal/stm32f427"]
27stm32f439 = ["stm32f4xx-hal/stm32f429"]
28stm32f446 = ["stm32f4xx-hal/stm32f446"]
29stm32f469 = ["stm32f4xx-hal/stm32f469"]
30stm32f479 = ["stm32f4xx-hal/stm32f469"]
31
32default = ["stm32f405"]
33
34[dependencies]
35embassy = { version = "0.1.0", path = "../embassy" }
36
37defmt = { version = "0.1.3", optional = true }
38log = { version = "0.4.11", optional = true }
39cortex-m-rt = "0.6.13"
40cortex-m = { version = "0.6.4" }
41embedded-hal = { version = "0.2.4" }
42embedded-dma = { version = "0.1.2" }
43stm32f4xx-hal = { version = "0.8.3", features = ["rt"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
diff --git a/embassy-stm32f4/src/fmt.rs b/embassy-stm32f4/src/fmt.rs
new file mode 100644
index 000000000..4da69766c
--- /dev/null
+++ b/embassy-stm32f4/src/fmt.rs
@@ -0,0 +1,118 @@
1#![macro_use]
2
3#[cfg(all(feature = "defmt", feature = "log"))]
4compile_error!("You may not enable both `defmt` and `log` features.");
5
6pub use fmt::*;
7
8#[cfg(feature = "defmt")]
9mod fmt {
10 pub use defmt::{
11 assert, assert_eq, assert_ne, debug, debug_assert, debug_assert_eq, debug_assert_ne, error,
12 info, panic, todo, trace, unreachable, unwrap, warn,
13 };
14}
15
16#[cfg(feature = "log")]
17mod fmt {
18 pub use core::{
19 assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo,
20 unreachable,
21 };
22 pub use log::{debug, error, info, trace, warn};
23}
24
25#[cfg(not(any(feature = "defmt", feature = "log")))]
26mod fmt {
27 #![macro_use]
28
29 pub use core::{
30 assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo,
31 unreachable,
32 };
33
34 #[macro_export]
35 macro_rules! trace {
36 ($($msg:expr),+ $(,)?) => {
37 ()
38 };
39 }
40
41 #[macro_export]
42 macro_rules! debug {
43 ($($msg:expr),+ $(,)?) => {
44 ()
45 };
46 }
47
48 #[macro_export]
49 macro_rules! info {
50 ($($msg:expr),+ $(,)?) => {
51 ()
52 };
53 }
54
55 #[macro_export]
56 macro_rules! warn {
57 ($($msg:expr),+ $(,)?) => {
58 ()
59 };
60 }
61
62 #[macro_export]
63 macro_rules! error {
64 ($($msg:expr),+ $(,)?) => {
65 ()
66 };
67 }
68}
69
70#[cfg(not(feature = "defmt"))]
71#[macro_export]
72macro_rules! unwrap {
73 ($arg:expr) => {
74 match $crate::fmt::Try::into_result($arg) {
75 ::core::result::Result::Ok(t) => t,
76 ::core::result::Result::Err(e) => {
77 ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
78 }
79 }
80 };
81 ($arg:expr, $($msg:expr),+ $(,)? ) => {
82 match $crate::fmt::Try::into_result($arg) {
83 ::core::result::Result::Ok(t) => t,
84 ::core::result::Result::Err(e) => {
85 ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
86 }
87 }
88 }
89}
90
91#[derive(Debug, Copy, Clone, Eq, PartialEq)]
92pub struct NoneError;
93
94pub trait Try {
95 type Ok;
96 type Error;
97 fn into_result(self) -> Result<Self::Ok, Self::Error>;
98}
99
100impl<T> Try for Option<T> {
101 type Ok = T;
102 type Error = NoneError;
103
104 #[inline]
105 fn into_result(self) -> Result<T, NoneError> {
106 self.ok_or(NoneError)
107 }
108}
109
110impl<T, E> Try for Result<T, E> {
111 type Ok = T;
112 type Error = E;
113
114 #[inline]
115 fn into_result(self) -> Self {
116 self
117 }
118}
diff --git a/embassy-stm32f4/src/interrupt.rs b/embassy-stm32f4/src/interrupt.rs
new file mode 100644
index 000000000..502d666ee
--- /dev/null
+++ b/embassy-stm32f4/src/interrupt.rs
@@ -0,0 +1,193 @@
1//! Interrupt management
2//!
3//! This module implements an API for managing interrupts compatible with
4//! nrf_softdevice::interrupt. Intended for switching between the two at compile-time.
5
6use core::sync::atomic::{compiler_fence, Ordering};
7
8use crate::pac::NVIC_PRIO_BITS;
9
10// Re-exports
11pub use crate::pac::Interrupt;
12pub use crate::pac::Interrupt::*; // needed for cortex-m-rt #[interrupt]
13pub use cortex_m::interrupt::{CriticalSection, Mutex};
14pub use embassy::interrupt::{declare, take, OwnedInterrupt};
15
16#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
17#[cfg_attr(feature = "defmt", derive(defmt::Format))]
18#[repr(u8)]
19pub enum Priority {
20 Level0 = 0,
21 Level1 = 1,
22 Level2 = 2,
23 Level3 = 3,
24 Level4 = 4,
25 Level5 = 5,
26 Level6 = 6,
27 Level7 = 7,
28 Level8 = 8,
29 Level9 = 9,
30 Level10 = 10,
31 Level11 = 11,
32 Level12 = 12,
33 Level13 = 13,
34 Level14 = 14,
35 Level15 = 15,
36}
37
38impl From<u8> for Priority {
39 fn from(priority: u8) -> Self {
40 match priority >> (8 - NVIC_PRIO_BITS) {
41 0 => Self::Level0,
42 1 => Self::Level1,
43 2 => Self::Level2,
44 3 => Self::Level3,
45 4 => Self::Level4,
46 5 => Self::Level5,
47 6 => Self::Level6,
48 7 => Self::Level7,
49 8 => Self::Level8,
50 9 => Self::Level9,
51 10 => Self::Level10,
52 11 => Self::Level11,
53 12 => Self::Level12,
54 13 => Self::Level13,
55 14 => Self::Level14,
56 15 => Self::Level15,
57 _ => unreachable!(),
58 }
59 }
60}
61
62impl From<Priority> for u8 {
63 fn from(p: Priority) -> Self {
64 (p as u8) << (8 - NVIC_PRIO_BITS)
65 }
66}
67
68#[inline]
69pub fn free<F, R>(f: F) -> R
70where
71 F: FnOnce(&CriticalSection) -> R,
72{
73 unsafe {
74 // TODO: assert that we're in privileged level
75 // Needed because disabling irqs in non-privileged level is a noop, which would break safety.
76
77 let primask: u32;
78 asm!("mrs {}, PRIMASK", out(reg) primask);
79
80 asm!("cpsid i");
81
82 // Prevent compiler from reordering operations inside/outside the critical section.
83 compiler_fence(Ordering::SeqCst);
84
85 let r = f(&CriticalSection::new());
86
87 compiler_fence(Ordering::SeqCst);
88
89 if primask & 1 == 0 {
90 asm!("cpsie i");
91 }
92
93 r
94 }
95}
96
97#[cfg(feature = "stm32f405")]
98mod irqs {
99 use super::*;
100 declare!(WWDG);
101 declare!(PVD);
102 declare!(TAMP_STAMP);
103 declare!(RTC_WKUP);
104 // declare!(FLASH);
105 declare!(RCC);
106 declare!(EXTI0);
107 declare!(EXTI1);
108 declare!(EXTI2);
109 declare!(EXTI3);
110 declare!(EXTI4);
111 declare!(DMA1_STREAM0);
112 declare!(DMA1_STREAM1);
113 declare!(DMA1_STREAM2);
114 declare!(DMA1_STREAM3);
115 declare!(DMA1_STREAM4);
116 declare!(DMA1_STREAM5);
117 declare!(DMA1_STREAM6);
118 declare!(ADC);
119 declare!(CAN1_TX);
120 declare!(CAN1_RX0);
121 declare!(CAN1_RX1);
122 declare!(CAN1_SCE);
123 declare!(EXTI9_5);
124 declare!(TIM1_BRK_TIM9);
125 declare!(TIM1_UP_TIM10);
126 declare!(TIM1_TRG_COM_TIM11);
127 declare!(TIM1_CC);
128 declare!(TIM2);
129 declare!(TIM3);
130 declare!(TIM4);
131 declare!(I2C1_EV);
132 declare!(I2C1_ER);
133 declare!(I2C2_EV);
134 declare!(I2C2_ER);
135 declare!(SPI1);
136 declare!(SPI2);
137 declare!(USART1);
138 declare!(USART2);
139 declare!(USART3);
140 declare!(EXTI15_10);
141 declare!(RTC_ALARM);
142 declare!(OTG_FS_WKUP);
143 declare!(TIM8_BRK_TIM12);
144 declare!(TIM8_UP_TIM13);
145 declare!(TIM8_TRG_COM_TIM14);
146 declare!(TIM8_CC);
147 declare!(DMA1_STREAM7);
148 // declare!(FMC);
149 declare!(SDIO);
150 declare!(TIM5);
151 declare!(SPI3);
152 declare!(UART4);
153 declare!(UART5);
154 declare!(TIM6_DAC);
155 declare!(TIM7);
156 declare!(DMA2_STREAM0);
157 declare!(DMA2_STREAM1);
158 declare!(DMA2_STREAM2);
159 declare!(DMA2_STREAM3);
160 declare!(DMA2_STREAM4);
161 declare!(ETH);
162 declare!(ETH_WKUP);
163 declare!(CAN2_TX);
164 declare!(CAN2_RX0);
165 declare!(CAN2_RX1);
166 declare!(CAN2_SCE);
167 declare!(OTG_FS);
168 declare!(DMA2_STREAM5);
169 declare!(DMA2_STREAM6);
170 declare!(DMA2_STREAM7);
171 declare!(USART6);
172 declare!(I2C3_EV);
173 declare!(I2C3_ER);
174 declare!(OTG_HS_EP1_OUT);
175 declare!(OTG_HS_EP1_IN);
176 declare!(OTG_HS_WKUP);
177 declare!(OTG_HS);
178 declare!(DCMI);
179 declare!(CRYP);
180 declare!(HASH_RNG);
181 declare!(FPU);
182 // declare!(UART7);
183 // declare!(UART8);
184 // declare!(SPI4);
185 // declare!(SPI5);
186 // declare!(SPI6);
187 // declare!(SAI1);
188 declare!(LCD_TFT);
189 declare!(LCD_TFT_1);
190 // declare!(DMA2D);
191}
192
193pub use irqs::*;
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs
new file mode 100644
index 000000000..0f4a70bba
--- /dev/null
+++ b/embassy-stm32f4/src/lib.rs
@@ -0,0 +1,317 @@
1#![no_std]
2#![feature(generic_associated_types)]
3#![feature(asm)]
4#![feature(type_alias_impl_trait)]
5#![feature(let_chains)]
6
7#[cfg(not(any(
8 feature = "stm32f401",
9 feature = "stm32f405",
10 feature = "stm32f407",
11 feature = "stm32f410",
12 feature = "stm32f411",
13 feature = "stm32f412",
14 feature = "stm32f413",
15 feature = "stm32f415",
16 feature = "stm32f417",
17 feature = "stm32f423",
18 feature = "stm32f427",
19 feature = "stm32f429",
20 feature = "stm32f437",
21 feature = "stm32f439",
22 feature = "stm32f446",
23 feature = "stm32f469",
24 feature = "stm32f479",
25)))]
26compile_error!(
27 "No chip feature activated. You must activate exactly one of the following features: "
28);
29
30#[cfg(any(
31 all(feature = "stm32f401", feature = "stm32f405"),
32 all(feature = "stm32f401", feature = "stm32f407"),
33 all(feature = "stm32f401", feature = "stm32f410"),
34 all(feature = "stm32f401", feature = "stm32f411"),
35 all(feature = "stm32f401", feature = "stm32f412"),
36 all(feature = "stm32f401", feature = "stm32f413"),
37 all(feature = "stm32f401", feature = "stm32f415"),
38 all(feature = "stm32f401", feature = "stm32f417"),
39 all(feature = "stm32f401", feature = "stm32f423"),
40 all(feature = "stm32f401", feature = "stm32f427"),
41 all(feature = "stm32f401", feature = "stm32f429"),
42 all(feature = "stm32f401", feature = "stm32f437"),
43 all(feature = "stm32f401", feature = "stm32f439"),
44 all(feature = "stm32f401", feature = "stm32f446"),
45 all(feature = "stm32f401", feature = "stm32f469"),
46 all(feature = "stm32f401", feature = "stm32f479"),
47 all(feature = "stm32f405", feature = "stm32f401"),
48 all(feature = "stm32f405", feature = "stm32f407"),
49 all(feature = "stm32f405", feature = "stm32f410"),
50 all(feature = "stm32f405", feature = "stm32f411"),
51 all(feature = "stm32f405", feature = "stm32f412"),
52 all(feature = "stm32f405", feature = "stm32f413"),
53 all(feature = "stm32f405", feature = "stm32f415"),
54 all(feature = "stm32f405", feature = "stm32f417"),
55 all(feature = "stm32f405", feature = "stm32f423"),
56 all(feature = "stm32f405", feature = "stm32f427"),
57 all(feature = "stm32f405", feature = "stm32f429"),
58 all(feature = "stm32f405", feature = "stm32f437"),
59 all(feature = "stm32f405", feature = "stm32f439"),
60 all(feature = "stm32f405", feature = "stm32f446"),
61 all(feature = "stm32f405", feature = "stm32f469"),
62 all(feature = "stm32f405", feature = "stm32f479"),
63 all(feature = "stm32f407", feature = "stm32f401"),
64 all(feature = "stm32f407", feature = "stm32f405"),
65 all(feature = "stm32f407", feature = "stm32f410"),
66 all(feature = "stm32f407", feature = "stm32f411"),
67 all(feature = "stm32f407", feature = "stm32f412"),
68 all(feature = "stm32f407", feature = "stm32f413"),
69 all(feature = "stm32f407", feature = "stm32f415"),
70 all(feature = "stm32f407", feature = "stm32f417"),
71 all(feature = "stm32f407", feature = "stm32f423"),
72 all(feature = "stm32f407", feature = "stm32f427"),
73 all(feature = "stm32f407", feature = "stm32f429"),
74 all(feature = "stm32f407", feature = "stm32f437"),
75 all(feature = "stm32f407", feature = "stm32f439"),
76 all(feature = "stm32f407", feature = "stm32f446"),
77 all(feature = "stm32f407", feature = "stm32f469"),
78 all(feature = "stm32f407", feature = "stm32f479"),
79 all(feature = "stm32f410", feature = "stm32f401"),
80 all(feature = "stm32f410", feature = "stm32f405"),
81 all(feature = "stm32f410", feature = "stm32f407"),
82 all(feature = "stm32f410", feature = "stm32f411"),
83 all(feature = "stm32f410", feature = "stm32f412"),
84 all(feature = "stm32f410", feature = "stm32f413"),
85 all(feature = "stm32f410", feature = "stm32f415"),
86 all(feature = "stm32f410", feature = "stm32f417"),
87 all(feature = "stm32f410", feature = "stm32f423"),
88 all(feature = "stm32f410", feature = "stm32f427"),
89 all(feature = "stm32f410", feature = "stm32f429"),
90 all(feature = "stm32f410", feature = "stm32f437"),
91 all(feature = "stm32f410", feature = "stm32f439"),
92 all(feature = "stm32f410", feature = "stm32f446"),
93 all(feature = "stm32f410", feature = "stm32f469"),
94 all(feature = "stm32f410", feature = "stm32f479"),
95 all(feature = "stm32f411", feature = "stm32f401"),
96 all(feature = "stm32f411", feature = "stm32f405"),
97 all(feature = "stm32f411", feature = "stm32f407"),
98 all(feature = "stm32f411", feature = "stm32f410"),
99 all(feature = "stm32f411", feature = "stm32f412"),
100 all(feature = "stm32f411", feature = "stm32f413"),
101 all(feature = "stm32f411", feature = "stm32f415"),
102 all(feature = "stm32f411", feature = "stm32f417"),
103 all(feature = "stm32f411", feature = "stm32f423"),
104 all(feature = "stm32f411", feature = "stm32f427"),
105 all(feature = "stm32f411", feature = "stm32f429"),
106 all(feature = "stm32f411", feature = "stm32f437"),
107 all(feature = "stm32f411", feature = "stm32f439"),
108 all(feature = "stm32f411", feature = "stm32f446"),
109 all(feature = "stm32f411", feature = "stm32f469"),
110 all(feature = "stm32f411", feature = "stm32f479"),
111 all(feature = "stm32f412", feature = "stm32f401"),
112 all(feature = "stm32f412", feature = "stm32f405"),
113 all(feature = "stm32f412", feature = "stm32f407"),
114 all(feature = "stm32f412", feature = "stm32f410"),
115 all(feature = "stm32f412", feature = "stm32f411"),
116 all(feature = "stm32f412", feature = "stm32f413"),
117 all(feature = "stm32f412", feature = "stm32f415"),
118 all(feature = "stm32f412", feature = "stm32f417"),
119 all(feature = "stm32f412", feature = "stm32f423"),
120 all(feature = "stm32f412", feature = "stm32f427"),
121 all(feature = "stm32f412", feature = "stm32f429"),
122 all(feature = "stm32f412", feature = "stm32f437"),
123 all(feature = "stm32f412", feature = "stm32f439"),
124 all(feature = "stm32f412", feature = "stm32f446"),
125 all(feature = "stm32f412", feature = "stm32f469"),
126 all(feature = "stm32f412", feature = "stm32f479"),
127 all(feature = "stm32f413", feature = "stm32f401"),
128 all(feature = "stm32f413", feature = "stm32f405"),
129 all(feature = "stm32f413", feature = "stm32f407"),
130 all(feature = "stm32f413", feature = "stm32f410"),
131 all(feature = "stm32f413", feature = "stm32f411"),
132 all(feature = "stm32f413", feature = "stm32f412"),
133 all(feature = "stm32f413", feature = "stm32f415"),
134 all(feature = "stm32f413", feature = "stm32f417"),
135 all(feature = "stm32f413", feature = "stm32f423"),
136 all(feature = "stm32f413", feature = "stm32f427"),
137 all(feature = "stm32f413", feature = "stm32f429"),
138 all(feature = "stm32f413", feature = "stm32f437"),
139 all(feature = "stm32f413", feature = "stm32f439"),
140 all(feature = "stm32f413", feature = "stm32f446"),
141 all(feature = "stm32f413", feature = "stm32f469"),
142 all(feature = "stm32f413", feature = "stm32f479"),
143 all(feature = "stm32f415", feature = "stm32f401"),
144 all(feature = "stm32f415", feature = "stm32f405"),
145 all(feature = "stm32f415", feature = "stm32f407"),
146 all(feature = "stm32f415", feature = "stm32f410"),
147 all(feature = "stm32f415", feature = "stm32f411"),
148 all(feature = "stm32f415", feature = "stm32f412"),
149 all(feature = "stm32f415", feature = "stm32f413"),
150 all(feature = "stm32f415", feature = "stm32f417"),
151 all(feature = "stm32f415", feature = "stm32f423"),
152 all(feature = "stm32f415", feature = "stm32f427"),
153 all(feature = "stm32f415", feature = "stm32f429"),
154 all(feature = "stm32f415", feature = "stm32f437"),
155 all(feature = "stm32f415", feature = "stm32f439"),
156 all(feature = "stm32f415", feature = "stm32f446"),
157 all(feature = "stm32f415", feature = "stm32f469"),
158 all(feature = "stm32f415", feature = "stm32f479"),
159 all(feature = "stm32f417", feature = "stm32f401"),
160 all(feature = "stm32f417", feature = "stm32f405"),
161 all(feature = "stm32f417", feature = "stm32f407"),
162 all(feature = "stm32f417", feature = "stm32f410"),
163 all(feature = "stm32f417", feature = "stm32f411"),
164 all(feature = "stm32f417", feature = "stm32f412"),
165 all(feature = "stm32f417", feature = "stm32f413"),
166 all(feature = "stm32f417", feature = "stm32f415"),
167 all(feature = "stm32f417", feature = "stm32f423"),
168 all(feature = "stm32f417", feature = "stm32f427"),
169 all(feature = "stm32f417", feature = "stm32f429"),
170 all(feature = "stm32f417", feature = "stm32f437"),
171 all(feature = "stm32f417", feature = "stm32f439"),
172 all(feature = "stm32f417", feature = "stm32f446"),
173 all(feature = "stm32f417", feature = "stm32f469"),
174 all(feature = "stm32f417", feature = "stm32f479"),
175 all(feature = "stm32f423", feature = "stm32f401"),
176 all(feature = "stm32f423", feature = "stm32f405"),
177 all(feature = "stm32f423", feature = "stm32f407"),
178 all(feature = "stm32f423", feature = "stm32f410"),
179 all(feature = "stm32f423", feature = "stm32f411"),
180 all(feature = "stm32f423", feature = "stm32f412"),
181 all(feature = "stm32f423", feature = "stm32f413"),
182 all(feature = "stm32f423", feature = "stm32f415"),
183 all(feature = "stm32f423", feature = "stm32f417"),
184 all(feature = "stm32f423", feature = "stm32f427"),
185 all(feature = "stm32f423", feature = "stm32f429"),
186 all(feature = "stm32f423", feature = "stm32f437"),
187 all(feature = "stm32f423", feature = "stm32f439"),
188 all(feature = "stm32f423", feature = "stm32f446"),
189 all(feature = "stm32f423", feature = "stm32f469"),
190 all(feature = "stm32f423", feature = "stm32f479"),
191 all(feature = "stm32f427", feature = "stm32f401"),
192 all(feature = "stm32f427", feature = "stm32f405"),
193 all(feature = "stm32f427", feature = "stm32f407"),
194 all(feature = "stm32f427", feature = "stm32f410"),
195 all(feature = "stm32f427", feature = "stm32f411"),
196 all(feature = "stm32f427", feature = "stm32f412"),
197 all(feature = "stm32f427", feature = "stm32f413"),
198 all(feature = "stm32f427", feature = "stm32f415"),
199 all(feature = "stm32f427", feature = "stm32f417"),
200 all(feature = "stm32f427", feature = "stm32f423"),
201 all(feature = "stm32f427", feature = "stm32f429"),
202 all(feature = "stm32f427", feature = "stm32f437"),
203 all(feature = "stm32f427", feature = "stm32f439"),
204 all(feature = "stm32f427", feature = "stm32f446"),
205 all(feature = "stm32f427", feature = "stm32f469"),
206 all(feature = "stm32f427", feature = "stm32f479"),
207 all(feature = "stm32f429", feature = "stm32f401"),
208 all(feature = "stm32f429", feature = "stm32f405"),
209 all(feature = "stm32f429", feature = "stm32f407"),
210 all(feature = "stm32f429", feature = "stm32f410"),
211 all(feature = "stm32f429", feature = "stm32f411"),
212 all(feature = "stm32f429", feature = "stm32f412"),
213 all(feature = "stm32f429", feature = "stm32f413"),
214 all(feature = "stm32f429", feature = "stm32f415"),
215 all(feature = "stm32f429", feature = "stm32f417"),
216 all(feature = "stm32f429", feature = "stm32f423"),
217 all(feature = "stm32f429", feature = "stm32f427"),
218 all(feature = "stm32f429", feature = "stm32f437"),
219 all(feature = "stm32f429", feature = "stm32f439"),
220 all(feature = "stm32f429", feature = "stm32f446"),
221 all(feature = "stm32f429", feature = "stm32f469"),
222 all(feature = "stm32f429", feature = "stm32f479"),
223 all(feature = "stm32f437", feature = "stm32f401"),
224 all(feature = "stm32f437", feature = "stm32f405"),
225 all(feature = "stm32f437", feature = "stm32f407"),
226 all(feature = "stm32f437", feature = "stm32f410"),
227 all(feature = "stm32f437", feature = "stm32f411"),
228 all(feature = "stm32f437", feature = "stm32f412"),
229 all(feature = "stm32f437", feature = "stm32f413"),
230 all(feature = "stm32f437", feature = "stm32f415"),
231 all(feature = "stm32f437", feature = "stm32f417"),
232 all(feature = "stm32f437", feature = "stm32f423"),
233 all(feature = "stm32f437", feature = "stm32f427"),
234 all(feature = "stm32f437", feature = "stm32f429"),
235 all(feature = "stm32f437", feature = "stm32f439"),
236 all(feature = "stm32f437", feature = "stm32f446"),
237 all(feature = "stm32f437", feature = "stm32f469"),
238 all(feature = "stm32f437", feature = "stm32f479"),
239 all(feature = "stm32f439", feature = "stm32f401"),
240 all(feature = "stm32f439", feature = "stm32f405"),
241 all(feature = "stm32f439", feature = "stm32f407"),
242 all(feature = "stm32f439", feature = "stm32f410"),
243 all(feature = "stm32f439", feature = "stm32f411"),
244 all(feature = "stm32f439", feature = "stm32f412"),
245 all(feature = "stm32f439", feature = "stm32f413"),
246 all(feature = "stm32f439", feature = "stm32f415"),
247 all(feature = "stm32f439", feature = "stm32f417"),
248 all(feature = "stm32f439", feature = "stm32f423"),
249 all(feature = "stm32f439", feature = "stm32f427"),
250 all(feature = "stm32f439", feature = "stm32f429"),
251 all(feature = "stm32f439", feature = "stm32f437"),
252 all(feature = "stm32f439", feature = "stm32f446"),
253 all(feature = "stm32f439", feature = "stm32f469"),
254 all(feature = "stm32f439", feature = "stm32f479"),
255 all(feature = "stm32f446", feature = "stm32f401"),
256 all(feature = "stm32f446", feature = "stm32f405"),
257 all(feature = "stm32f446", feature = "stm32f407"),
258 all(feature = "stm32f446", feature = "stm32f410"),
259 all(feature = "stm32f446", feature = "stm32f411"),
260 all(feature = "stm32f446", feature = "stm32f412"),
261 all(feature = "stm32f446", feature = "stm32f413"),
262 all(feature = "stm32f446", feature = "stm32f415"),
263 all(feature = "stm32f446", feature = "stm32f417"),
264 all(feature = "stm32f446", feature = "stm32f423"),
265 all(feature = "stm32f446", feature = "stm32f427"),
266 all(feature = "stm32f446", feature = "stm32f429"),
267 all(feature = "stm32f446", feature = "stm32f437"),
268 all(feature = "stm32f446", feature = "stm32f439"),
269 all(feature = "stm32f446", feature = "stm32f469"),
270 all(feature = "stm32f446", feature = "stm32f479"),
271 all(feature = "stm32f469", feature = "stm32f401"),
272 all(feature = "stm32f469", feature = "stm32f405"),
273 all(feature = "stm32f469", feature = "stm32f407"),
274 all(feature = "stm32f469", feature = "stm32f410"),
275 all(feature = "stm32f469", feature = "stm32f411"),
276 all(feature = "stm32f469", feature = "stm32f412"),
277 all(feature = "stm32f469", feature = "stm32f413"),
278 all(feature = "stm32f469", feature = "stm32f415"),
279 all(feature = "stm32f469", feature = "stm32f417"),
280 all(feature = "stm32f469", feature = "stm32f423"),
281 all(feature = "stm32f469", feature = "stm32f427"),
282 all(feature = "stm32f469", feature = "stm32f429"),
283 all(feature = "stm32f469", feature = "stm32f437"),
284 all(feature = "stm32f469", feature = "stm32f439"),
285 all(feature = "stm32f469", feature = "stm32f446"),
286 all(feature = "stm32f469", feature = "stm32f479"),
287 all(feature = "stm32f479", feature = "stm32f401"),
288 all(feature = "stm32f479", feature = "stm32f405"),
289 all(feature = "stm32f479", feature = "stm32f407"),
290 all(feature = "stm32f479", feature = "stm32f410"),
291 all(feature = "stm32f479", feature = "stm32f411"),
292 all(feature = "stm32f479", feature = "stm32f412"),
293 all(feature = "stm32f479", feature = "stm32f413"),
294 all(feature = "stm32f479", feature = "stm32f415"),
295 all(feature = "stm32f479", feature = "stm32f417"),
296 all(feature = "stm32f479", feature = "stm32f423"),
297 all(feature = "stm32f479", feature = "stm32f427"),
298 all(feature = "stm32f479", feature = "stm32f429"),
299 all(feature = "stm32f479", feature = "stm32f437"),
300 all(feature = "stm32f479", feature = "stm32f439"),
301 all(feature = "stm32f479", feature = "stm32f446"),
302 all(feature = "stm32f479", feature = "stm32f469"),
303))]
304compile_error!(
305 "Multile chip features activated. You must activate exactly one of the following features: "
306);
307
308pub use stm32f4xx_hal as hal;
309pub use stm32f4xx_hal::stm32 as pac;
310
311// This mod MUST go first, so that the others see its macros.
312pub(crate) mod fmt;
313
314pub mod interrupt;
315pub mod serial;
316
317pub use cortex_m_rt::interrupt;
diff --git a/embassy-stm32f4/src/serial.rs b/embassy-stm32f4/src/serial.rs
new file mode 100644
index 000000000..cc55ef325
--- /dev/null
+++ b/embassy-stm32f4/src/serial.rs
@@ -0,0 +1,224 @@
1//! Async low power Serial.
2//!
3//! The peripheral is autmatically enabled and disabled as required to save power.
4//! Lowest power consumption can only be guaranteed if the send receive futures
5//! are dropped correctly (e.g. not using `mem::forget()`).
6
7use core::future::Future;
8use core::ptr;
9use core::sync::atomic::{self, Ordering};
10use core::task::{Context, Poll};
11
12use embassy::interrupt::OwnedInterrupt;
13use embassy::util::Signal;
14use embedded_dma::{StaticReadBuffer, StaticWriteBuffer, WriteBuffer};
15
16use crate::hal::dma::config::DmaConfig;
17use crate::hal::dma::traits::{PeriAddress, Stream};
18use crate::hal::dma::{
19 Channel4, MemoryToPeripheral, PeripheralToMemory, Stream2, Stream7, StreamsTuple, Transfer,
20};
21use crate::hal::gpio::gpioa::{PA10, PA9};
22use crate::hal::gpio::{Alternate, AF7};
23use crate::hal::prelude::*;
24use crate::hal::rcc::Clocks;
25use crate::hal::serial::config::{
26 Config as SerialConfig, DmaConfig as SerialDmaConfig, Parity, StopBits, WordLength,
27};
28use crate::hal::serial::{Event as SerialEvent, Serial as HalSerial};
29use crate::hal::time::Bps;
30
31use crate::interrupt;
32
33use crate::pac::Interrupt;
34use crate::pac::{DMA2, USART1};
35
36/// Interface to the Serial peripheral
37pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> {
38 tx_stream: Option<TSTREAM>,
39 rx_stream: Option<RSTREAM>,
40 usart: Option<USART>,
41 tx_int: interrupt::DMA2_STREAM7Interrupt,
42 rx_int: interrupt::DMA2_STREAM2Interrupt,
43 usart_int: interrupt::USART1Interrupt,
44}
45
46struct State {
47 tx_int: Signal<()>,
48 rx_int: Signal<()>,
49}
50
51static STATE: State = State {
52 tx_int: Signal::new(),
53 rx_int: Signal::new(),
54};
55
56static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut();
57
58impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
59 pub fn new(
60 txd: PA9<Alternate<AF7>>,
61 rxd: PA10<Alternate<AF7>>,
62 tx_int: interrupt::DMA2_STREAM7Interrupt,
63 rx_int: interrupt::DMA2_STREAM2Interrupt,
64 usart_int: interrupt::USART1Interrupt,
65 dma: DMA2,
66 usart: USART1,
67 parity: Parity,
68 baudrate: Bps,
69 clocks: Clocks,
70 ) -> Self {
71 let mut serial = HalSerial::usart1(
72 usart,
73 (txd, rxd),
74 SerialConfig {
75 baudrate: baudrate,
76 wordlength: WordLength::DataBits8,
77 parity: Parity::ParityNone,
78 stopbits: StopBits::STOP1,
79 dma: SerialDmaConfig::TxRx,
80 },
81 clocks,
82 )
83 .unwrap();
84
85 serial.listen(SerialEvent::Idle);
86 // serial.listen(SerialEvent::Txe);
87
88 let (usart, _) = serial.release();
89
90 // Register ISR
91 tx_int.set_handler(Self::on_tx_irq);
92 rx_int.set_handler(Self::on_rx_irq);
93 usart_int.set_handler(Self::on_rx_irq);
94 // usart_int.unpend();
95 // usart_int.enable();
96
97 let streams = StreamsTuple::new(dma);
98
99 Serial {
100 tx_stream: Some(streams.7),
101 rx_stream: Some(streams.2),
102 usart: Some(usart),
103 tx_int: tx_int,
104 rx_int: rx_int,
105 usart_int: usart_int,
106 }
107 }
108
109 unsafe fn on_tx_irq() {
110 let s = &(*INSTANCE);
111
112 s.tx_int.disable();
113
114 STATE.tx_int.signal(());
115 }
116
117 unsafe fn on_rx_irq() {
118 let s = &(*INSTANCE);
119
120 atomic::compiler_fence(Ordering::Acquire);
121 s.rx_int.disable();
122 s.usart_int.disable();
123 atomic::compiler_fence(Ordering::Release);
124
125 STATE.rx_int.signal(());
126 }
127
128 unsafe fn on_usart_irq() {
129 let s = &(*INSTANCE);
130
131 atomic::compiler_fence(Ordering::Acquire);
132 s.rx_int.disable();
133 s.usart_int.disable();
134 atomic::compiler_fence(Ordering::Release);
135
136 STATE.rx_int.signal(());
137 }
138
139 /// Sends serial data.
140 ///
141 /// `tx_buffer` is marked as static as per `embedded-dma` requirements.
142 /// It it safe to use a buffer with a non static lifetime if memory is not
143 /// reused until the future has finished.
144 pub fn send<'a, B: 'a>(&'a mut self, tx_buffer: B) -> impl Future<Output = ()> + 'a
145 where
146 B: StaticWriteBuffer<Word = u8>,
147 {
148 unsafe { INSTANCE = self };
149
150 let tx_stream = self.tx_stream.take().unwrap();
151 let usart = self.usart.take().unwrap();
152 STATE.tx_int.reset();
153
154 async move {
155 let mut tx_transfer = Transfer::init(
156 tx_stream,
157 usart,
158 tx_buffer,
159 None,
160 DmaConfig::default()
161 .transfer_complete_interrupt(true)
162 .memory_increment(true)
163 .double_buffer(false),
164 );
165
166 self.tx_int.unpend();
167 self.tx_int.enable();
168 tx_transfer.start(|_usart| {});
169
170 STATE.tx_int.wait().await;
171
172 let (tx_stream, usart, _buf, _) = tx_transfer.free();
173 self.tx_stream.replace(tx_stream);
174 self.usart.replace(usart);
175 }
176 }
177
178 /// Receives serial data.
179 ///
180 /// The future is pending until the buffer is completely filled.
181 /// A common pattern is to use [`stop()`](ReceiveFuture::stop) to cancel
182 /// unfinished transfers after a timeout to prevent lockup when no more data
183 /// is incoming.
184 ///
185 /// `rx_buffer` is marked as static as per `embedded-dma` requirements.
186 /// It it safe to use a buffer with a non static lifetime if memory is not
187 /// reused until the future has finished.
188 pub fn receive<'a, B: 'a>(&'a mut self, rx_buffer: B) -> impl Future<Output = B> + 'a
189 where
190 B: StaticWriteBuffer<Word = u8> + Unpin,
191 {
192 unsafe { INSTANCE = self };
193
194 let rx_stream = self.rx_stream.take().unwrap();
195 let usart = self.usart.take().unwrap();
196 STATE.rx_int.reset();
197
198 async move {
199 let mut rx_transfer = Transfer::init(
200 rx_stream,
201 usart,
202 rx_buffer,
203 None,
204 DmaConfig::default()
205 .transfer_complete_interrupt(true)
206 .memory_increment(true)
207 .double_buffer(false),
208 );
209
210 self.rx_int.unpend();
211 self.rx_int.enable();
212
213 rx_transfer.start(|_usart| {});
214
215 STATE.rx_int.wait().await;
216
217 let (rx_stream, usart, buf, _) = rx_transfer.free();
218 self.rx_stream.replace(rx_stream);
219 self.usart.replace(usart);
220
221 buf
222 }
223 }
224}