assign_resources/lib.rs
1#![no_std]
2
3/// Extract the specified fields from the `Peripherals` struct into several named
4/// structs which can be passed to other tasks to provide them with all their
5/// resources, including pins, peripherals, DMA channels, etc.
6///
7/// The `peripherals` module must be in scope when `resource_assigs!{}` is called,
8/// and it defines a new macro `split_resources!()` which uses the `Peripherals` struct
9/// and returns a new struct with a field for each of the structs named in `resource_assigs!{}`.
10///
11/// Defines new structs containing the specified structs from the `peripherals` module,
12/// a top-level struct called `AssignedResources` that contains an instance of each of these new structs,
13/// and a macro that creates the top-level struct and populates it with fields from
14/// a `Peripherals` instance.
15///
16/// # Example
17///
18/// ```
19/// use assign_resources::assign_resources;
20/// use embassy_stm32::{Peri, peripherals};
21///
22/// assign_resources! {
23/// usb: UsbResources {
24/// dp: PA12,
25/// dm: PA11,
26/// usb: USB,
27/// }
28/// leds: LedResources {
29/// r: PA2,
30/// g: PA3,
31/// b: PA4,
32/// tim2: TIM2,
33/// }
34/// }
35///
36/// #[embassy_executor::task]
37/// async fn usb_task(r: UsbResources) {
38/// // use r.dp, r.dm, r.usb
39/// }
40///
41/// #[embassy_executor::task]
42/// async fn led_task(r: LedResources) {
43/// // use r.r, r.g, r.b, r.tim2
44/// }
45///
46/// #[embassy_executor::main]
47/// async fn main(spawner: embassy_executor::Spawner) {
48/// let p = embassy_stm32::init(Default::default());
49/// let r = split_resources!(p);
50/// spawner.spawn(usb_task(r.usb)).unwrap();
51/// spawner.spawn(led_task(r.leds)).unwrap();
52///
53/// // can still use p.PA0, p.PA1, etc
54/// }
55/// ```
56#[macro_export]
57macro_rules! assign_resources {
58 {
59 $(
60 $(#[$outer:meta])*
61 $group_name:ident : $group_struct:ident {
62 $(
63 $(#[$inner:meta])*
64 $resource_name:ident : $resource_field:ident $(=$resource_alias:ident)?),*
65 $(,)?
66 }
67 $(,)?
68 )+
69 } => {
70 #[allow(dead_code,non_snake_case,missing_docs)]
71 pub struct AssignedResources {
72 $(pub $group_name : $group_struct),*
73 }
74 $(
75 #[allow(dead_code,non_snake_case)]
76 $(#[$outer])*
77 pub struct $group_struct {
78 $(
79 $(#[$inner])*
80 pub $resource_name: Peri<'static, peripherals::$resource_field>
81 ),*
82 }
83 )+
84
85
86 $($($(
87 #[allow(missing_docs)]
88 pub type $resource_alias = Peri<'static, peripherals::$resource_field>;
89 )?)*)*
90
91 #[macro_export]
92 /// `split_resources!` macro
93 macro_rules! split_resources (
94 ($p:ident) => {
95 AssignedResources {
96 $($group_name: $group_struct {
97 $($resource_name: $p.$resource_field),*
98 }),*
99 }
100 }
101 );
102 }
103}