aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2021-03-27 17:27:39 -0500
committerxoviat <[email protected]>2021-03-27 17:27:39 -0500
commit6ee9e012fcfc9a0a901f78885d19ae3c3d10570c (patch)
tree238212e294c9c5d7fc7c4e2acf15c3724c996895
parent19b959b0f8690d7eead40df699c48a37345639b3 (diff)
add embassy::main and implement for stm32f4
-rw-r--r--embassy-macros/Cargo.toml4
-rw-r--r--embassy-macros/src/lib.rs117
-rw-r--r--embassy-nrf/Cargo.toml1
-rw-r--r--embassy-stm32/Cargo.toml1
-rw-r--r--embassy-stm32/src/lib.rs206
-rw-r--r--embassy-stm32f4-examples/Cargo.toml1
-rw-r--r--embassy-stm32f4-examples/src/bin/rtc_async.rs49
-rw-r--r--embassy/src/executor/mod.rs2
-rw-r--r--embassy/src/lib.rs1
9 files changed, 343 insertions, 39 deletions
diff --git a/embassy-macros/Cargo.toml b/embassy-macros/Cargo.toml
index 1f3e20aa8..295a57039 100644
--- a/embassy-macros/Cargo.toml
+++ b/embassy-macros/Cargo.toml
@@ -11,3 +11,7 @@ darling = "0.10.2"
11 11
12[lib] 12[lib]
13proc-macro = true 13proc-macro = true
14
15[features]
16stm32 = []
17nrf = [] \ No newline at end of file
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index 0bc5f0035..450edbe43 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -178,3 +178,120 @@ pub fn interrupt_take(item: TokenStream) -> TokenStream {
178 }; 178 };
179 result.into() 179 result.into()
180} 180}
181
182#[derive(Debug, FromMeta)]
183struct MainMacroArgs {
184 #[darling(default)]
185 use_hse: Option<u32>,
186 #[darling(default)]
187 sysclk: Option<u32>,
188 #[darling(default)]
189 pclk1: Option<u32>,
190}
191
192#[proc_macro_attribute]
193pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
194 let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs);
195 let mut task_fn = syn::parse_macro_input!(item as syn::ItemFn);
196
197 let macro_args = match MainMacroArgs::from_list(&macro_args) {
198 Ok(v) => v,
199 Err(e) => {
200 return TokenStream::from(e.write_errors());
201 }
202 };
203
204 let mut fail = false;
205 if task_fn.sig.asyncness.is_none() {
206 task_fn
207 .sig
208 .span()
209 .unwrap()
210 .error("task functions must be async")
211 .emit();
212 fail = true;
213 }
214 if !task_fn.sig.generics.params.is_empty() {
215 task_fn
216 .sig
217 .span()
218 .unwrap()
219 .error("main function must not be generic")
220 .emit();
221 fail = true;
222 }
223
224 let mut arg_names: syn::punctuated::Punctuated<syn::Ident, syn::Token![,]> =
225 syn::punctuated::Punctuated::new();
226 let mut args = task_fn.sig.inputs.clone();
227
228 if args.len() != 1 {
229 task_fn
230 .sig
231 .span()
232 .unwrap()
233 .error("main function must have one argument")
234 .emit();
235 fail = true;
236 }
237
238 if fail {
239 return TokenStream::new();
240 }
241
242 let name = task_fn.sig.ident.clone();
243 let task_fn_body = task_fn.block.clone();
244
245 let mut clock_cfg_args = quote! {};
246 if macro_args.use_hse.is_some() {
247 let mhz = macro_args.use_hse.unwrap();
248 clock_cfg_args = quote! { #clock_cfg_args.use_hse(#mhz.mhz()) };
249 }
250
251 if macro_args.sysclk.is_some() {
252 let mhz = macro_args.sysclk.unwrap();
253 clock_cfg_args = quote! { #clock_cfg_args.sysclk(#mhz.mhz()) };
254 }
255
256 if macro_args.pclk1.is_some() {
257 let mhz = macro_args.pclk1.unwrap();
258 clock_cfg_args = quote! { #clock_cfg_args.pclk1(#mhz.mhz()) };
259 }
260
261 let result = quote! {
262 static __embassy_rtc: embassy::util::Forever<embassy_stm32::rtc::RTC<embassy_stm32::pac::TIM3>> = embassy::util::Forever::new();
263 static __embassy_alarm: embassy::util::Forever<embassy_stm32::rtc::Alarm<embassy_stm32::pac::TIM3>> = embassy::util::Forever::new();
264 static __embassy_executor: embassy::util::Forever<embassy::executor::Executor> = embassy::util::Forever::new();
265
266 #[embassy::executor::task]
267 async fn __embassy_main(#args) {
268 #task_fn_body
269 }
270
271 #[cortex_m_rt::entry]
272 fn main() -> ! {
273 use embassy::executor::Executor;
274 use embassy_stm32::{rtc, interrupt, Peripherals, pac, hal::rcc::RccExt, hal::time::U32Ext};
275
276 let dp = pac::Peripherals::take().unwrap();
277 let rcc = dp.RCC.constrain();
278 let clocks = rcc.cfgr#clock_cfg_args.freeze();
279
280 unsafe { Peripherals::set_peripherals(clocks) };
281
282 let rtc = __embassy_rtc.put(rtc::RTC::new(dp.TIM3, interrupt::take!(TIM3), clocks));
283 rtc.start();
284
285 unsafe { embassy::time::set_clock(rtc) };
286
287 let alarm = __embassy_alarm.put(rtc.alarm1());
288 let executor = __embassy_executor.put(Executor::new());
289 executor.set_alarm(alarm);
290
291 executor.run(|spawner| {
292 spawner.spawn(__embassy_main(spawner)).unwrap();
293 })
294 }
295 };
296 result.into()
297}
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 026e815f7..f26e892d3 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -20,6 +20,7 @@ defmt-error = [ ]
20 20
21[dependencies] 21[dependencies]
22embassy = { version = "0.1.0", path = "../embassy" } 22embassy = { version = "0.1.0", path = "../embassy" }
23embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]}
23embassy-extras = {version = "0.1.0", path = "../embassy-extras" } 24embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
24 25
25defmt = { version = "0.2.0", optional = true } 26defmt = { version = "0.2.0", optional = true }
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 3fae66e9e..437cacb27 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -35,6 +35,7 @@ stm32l0x3 = ["stm32l0xx-hal/stm32l0x3"]
35 35
36[dependencies] 36[dependencies]
37embassy = { version = "0.1.0", path = "../embassy" } 37embassy = { version = "0.1.0", path = "../embassy" }
38embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"]}
38 39
39defmt = { version = "0.2.0", optional = true } 40defmt = { version = "0.2.0", optional = true }
40log = { version = "0.4.11", optional = true } 41log = { version = "0.4.11", optional = true }
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 8a1fe5a36..122761c1e 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -73,3 +73,209 @@ pub mod can;
73 feature = "stm32f479", 73 feature = "stm32f479",
74))] 74))]
75pub mod rtc; 75pub mod rtc;
76
77use core::option::Option;
78use hal::prelude::*;
79use hal::rcc::Clocks;
80
81macro_rules! peripherals {
82 ($($PER:ident,)+) => {
83 #[doc = r"All the peripherals"]
84 #[allow(non_snake_case)]
85 pub struct Peripherals {
86 $(
87 pub $PER: pac::$PER,
88 )+
89 }
90
91 static mut GLOBAL_PERIPHERALS: Option<(Peripherals, Clocks)> = None;
92
93 impl Peripherals {
94 pub fn take() -> Option<(Peripherals, Clocks)> {
95 unsafe { GLOBAL_PERIPHERALS.take() }
96 }
97
98 pub unsafe fn set_peripherals(clocks: Clocks) {
99 let dp = pac::Peripherals::steal();
100 let peripherals = Peripherals {
101 $(
102 $PER: dp.$PER,
103 )+
104 };
105
106 GLOBAL_PERIPHERALS.replace((peripherals, clocks));
107 }
108 }
109 };
110}
111
112#[cfg(feature = "stm32f446")]
113peripherals! {
114 DCMI,
115 FMC,
116 DBGMCU,
117 DMA2,
118 DMA1,
119// RCC,
120 GPIOH,
121 GPIOG,
122 GPIOF,
123 GPIOE,
124 GPIOD,
125 GPIOC,
126 GPIOB,
127 GPIOA,
128 SYSCFG,
129 SPI1,
130 SPI2,
131 SPI3,
132 SPI4,
133 ADC1,
134 ADC2,
135 ADC3,
136 USART6,
137 USART1,
138 USART2,
139 USART3,
140 DAC,
141 I2C3,
142 I2C2,
143 I2C1,
144 IWDG,
145 WWDG,
146 RTC,
147 UART4,
148 UART5,
149 ADC_COMMON,
150 TIM1,
151 TIM2,
152 TIM8,
153// TIM3,
154 TIM4,
155 TIM5,
156 TIM9,
157 TIM12,
158 TIM10,
159 TIM13,
160 TIM14,
161 TIM11,
162 TIM6,
163 TIM7,
164 CRC,
165 OTG_FS_GLOBAL,
166 OTG_FS_HOST,
167 OTG_FS_DEVICE,
168 OTG_FS_PWRCLK,
169 CAN1,
170 CAN2,
171 FLASH,
172 EXTI,
173 OTG_HS_GLOBAL,
174 OTG_HS_HOST,
175 OTG_HS_DEVICE,
176 OTG_HS_PWRCLK,
177 SAI1,
178 SAI2,
179 PWR,
180 QUADSPI,
181 SPDIFRX,
182 SDMMC,
183 HDMI_CEC,
184 FPU,
185 STK,
186 NVIC_STIR,
187 FPU_CPACR,
188 SCB_ACTRL,
189}
190
191#[cfg(feature = "stm32f405")]
192peripherals! {
193 RNG,
194 DCMI,
195 FSMC,
196 DBGMCU,
197 DMA2,
198 DMA1,
199// RCC,
200 GPIOI,
201 GPIOH,
202 GPIOG,
203 GPIOF,
204 GPIOE,
205 GPIOD,
206 GPIOC,
207 GPIOJ,
208 GPIOK,
209 GPIOB,
210 GPIOA,
211 SYSCFG,
212 SPI1,
213 SPI2,
214 SPI3,
215 I2S2EXT,
216 I2S3EXT,
217 SPI4,
218 SPI5,
219 SPI6,
220 SDIO,
221 ADC1,
222 ADC2,
223 ADC3,
224 USART6,
225 USART1,
226 USART2,
227 USART3,
228 DAC,
229 PWR,
230 I2C3,
231 I2C2,
232 I2C1,
233 IWDG,
234 WWDG,
235 RTC,
236 UART4,
237 UART5,
238 UART7,
239 UART8,
240 ADC_COMMON,
241 TIM1,
242 TIM8,
243 TIM2,
244// TIM3,
245 TIM4,
246 TIM5,
247 TIM9,
248 TIM12,
249 TIM10,
250 TIM13,
251 TIM14,
252 TIM11,
253 TIM6,
254 TIM7,
255 ETHERNET_MAC,
256 ETHERNET_MMC,
257 ETHERNET_PTP,
258 ETHERNET_DMA,
259 CRC,
260 OTG_FS_GLOBAL,
261 OTG_FS_HOST,
262 OTG_FS_DEVICE,
263 OTG_FS_PWRCLK,
264 CAN1,
265 CAN2,
266 FLASH,
267 EXTI,
268 OTG_HS_GLOBAL,
269 OTG_HS_HOST,
270 OTG_HS_DEVICE,
271 OTG_HS_PWRCLK,
272 SAI1,
273 LTDC,
274 HASH,
275 CRYP,
276 FPU,
277 STK,
278 NVIC_STIR,
279 FPU_CPACR,
280 SCB_ACTRL,
281}
diff --git a/embassy-stm32f4-examples/Cargo.toml b/embassy-stm32f4-examples/Cargo.toml
index 5bbaecc58..fbdc6d794 100644
--- a/embassy-stm32f4-examples/Cargo.toml
+++ b/embassy-stm32f4-examples/Cargo.toml
@@ -38,6 +38,7 @@ stm32f479 = ["stm32f4xx-hal/stm32f469", "embassy-stm32f4/stm32f469"]
38embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } 38embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] }
39embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] } 39embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] }
40embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4" } 40embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4" }
41embassy-stm32 = { version = "*", path = "../embassy-stm32" }
41 42
42defmt = "0.2.0" 43defmt = "0.2.0"
43defmt-rtt = "0.2.0" 44defmt-rtt = "0.2.0"
diff --git a/embassy-stm32f4-examples/src/bin/rtc_async.rs b/embassy-stm32f4-examples/src/bin/rtc_async.rs
index 41ce2d4f1..1927d01bf 100644
--- a/embassy-stm32f4-examples/src/bin/rtc_async.rs
+++ b/embassy-stm32f4-examples/src/bin/rtc_async.rs
@@ -8,19 +8,19 @@
8mod example_common; 8mod example_common;
9use example_common::*; 9use example_common::*;
10 10
11use cortex_m_rt::entry;
12use defmt::panic; 11use defmt::panic;
13use embassy::executor::{task, Executor}; 12use embassy;
13use embassy::executor::Spawner;
14use embassy::task;
14use embassy::time::{Duration, Timer}; 15use embassy::time::{Duration, Timer};
15use embassy::util::Forever; 16use embassy_stm32f4;
16use embassy_stm32f4::{interrupt, pac, rtc}; 17use embassy_stm32f4::hal;
17use stm32f4xx_hal::prelude::*;
18 18
19#[task] 19#[task]
20async fn run1() { 20async fn run1() {
21 loop { 21 loop {
22 info!("BIG INFREQUENT TICK"); 22 info!("BIG INFREQUENT TICK");
23 Timer::after(Duration::from_ticks(32768 * 2)).await; 23 Timer::after(Duration::from_ticks(32768 * 2 as u64)).await;
24 } 24 }
25} 25}
26 26
@@ -28,40 +28,13 @@ async fn run1() {
28async fn run2() { 28async fn run2() {
29 loop { 29 loop {
30 info!("tick"); 30 info!("tick");
31 Timer::after(Duration::from_ticks(13000)).await; 31 Timer::after(Duration::from_ticks(13000 as u64)).await;
32 } 32 }
33} 33}
34 34
35static RTC: Forever<rtc::RTC<pac::TIM2>> = Forever::new(); 35#[embassy::main(use_hse = 16)]
36static ALARM: Forever<rtc::Alarm<pac::TIM2>> = Forever::new(); 36async fn main(spawner: Spawner) {
37static EXECUTOR: Forever<Executor> = Forever::new(); 37 let (dp, clocks) = embassy_stm32::Peripherals::take().unwrap();
38 38
39#[entry] 39 spawner.spawn(run1()).unwrap();
40fn main() -> ! {
41 info!("Hello World!");
42
43 let p = unwrap!(pac::Peripherals::take());
44
45 p.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled());
46 let rcc = p.RCC.constrain();
47 let clocks = rcc.cfgr.freeze();
48
49 p.DBGMCU.cr.modify(|_, w| {
50 w.dbg_sleep().set_bit();
51 w.dbg_standby().set_bit();
52 w.dbg_stop().set_bit()
53 });
54
55 let rtc = RTC.put(rtc::RTC::new(p.TIM2, interrupt::take!(TIM2), clocks));
56 rtc.start();
57
58 unsafe { embassy::time::set_clock(rtc) };
59
60 let alarm = ALARM.put(rtc.alarm1());
61 let executor = EXECUTOR.put(Executor::new());
62 executor.set_alarm(alarm);
63 executor.run(|spawner| {
64 unwrap!(spawner.spawn(run1()));
65 unwrap!(spawner.spawn(run2()));
66 });
67} 40}
diff --git a/embassy/src/executor/mod.rs b/embassy/src/executor/mod.rs
index fedff73e2..b2c42190f 100644
--- a/embassy/src/executor/mod.rs
+++ b/embassy/src/executor/mod.rs
@@ -1,4 +1,4 @@
1pub use embassy_macros::task; 1pub use embassy_macros::{main, task};
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::ptr::NonNull; 4use core::ptr::NonNull;
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index b6fefc9f7..482d5b367 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -18,6 +18,7 @@ pub mod time;
18pub mod util; 18pub mod util;
19 19
20pub use embassy_traits as traits; 20pub use embassy_traits as traits;
21pub use executor::{main, task};
21 22
22#[doc(hidden)] 23#[doc(hidden)]
23/// Implementation details for embassy macros. DO NOT USE. 24/// Implementation details for embassy macros. DO NOT USE.