embassy_hal_internal/
macros.rs

1/// Types for the peripheral singletons.
2#[macro_export]
3macro_rules! peripherals_definition {
4    ($($(#[$cfg:meta])? $name:ident),*$(,)?) => {
5        /// Types for the peripheral singletons.
6        pub mod peripherals {
7            $(
8                $(#[$cfg])?
9                #[allow(non_camel_case_types)]
10                #[doc = concat!(stringify!($name), " peripheral")]
11                pub struct $name { _private: () }
12
13                $(#[$cfg])?
14                impl $name {
15                    /// Unsafely create an instance of this peripheral out of thin air.
16                    ///
17                    /// # Safety
18                    ///
19                    /// You must ensure that you're only using one instance of this type at a time.
20                    #[inline]
21                    pub unsafe fn steal() -> Self {
22                        Self{ _private: ()}
23                    }
24                }
25
26                $(#[$cfg])?
27                $crate::impl_peripheral!($name);
28            )*
29        }
30    };
31}
32
33/// Define the peripherals struct.
34#[macro_export]
35macro_rules! peripherals_struct {
36    ($($(#[$cfg:meta])? $name:ident),*$(,)?) => {
37        /// Struct containing all the peripheral singletons.
38        ///
39        /// To obtain the peripherals, you must initialize the HAL, by calling [`crate::init`].
40        #[allow(non_snake_case)]
41        pub struct Peripherals {
42            $(
43                #[doc = concat!(stringify!($name), " peripheral")]
44                $(#[$cfg])?
45                pub $name: peripherals::$name,
46            )*
47        }
48
49        impl Peripherals {
50            ///Returns all the peripherals *once*
51            #[inline]
52            pub(crate) fn take() -> Self {
53                critical_section::with(Self::take_with_cs)
54            }
55
56            ///Returns all the peripherals *once*
57            #[inline]
58            pub(crate) fn take_with_cs(_cs: critical_section::CriticalSection) -> Self {
59                #[no_mangle]
60                static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;
61
62                // safety: OK because we're inside a CS.
63                unsafe {
64                    if _EMBASSY_DEVICE_PERIPHERALS {
65                        panic!("init called more than once!")
66                    }
67                    _EMBASSY_DEVICE_PERIPHERALS = true;
68                    Self::steal()
69                }
70            }
71        }
72
73        impl Peripherals {
74            /// Unsafely create an instance of this peripheral out of thin air.
75            ///
76            /// # Safety
77            ///
78            /// You must ensure that you're only using one instance of this type at a time.
79            #[inline]
80            pub unsafe fn steal() -> Self {
81                Self {
82                    $(
83                        $(#[$cfg])?
84                        $name: peripherals::$name::steal(),
85                    )*
86                }
87            }
88        }
89    };
90}
91
92/// Defining peripheral type.
93#[macro_export]
94macro_rules! peripherals {
95    ($($(#[$cfg:meta])? $name:ident),*$(,)?) => {
96        $crate::peripherals_definition!(
97            $(
98                $(#[$cfg])?
99                $name,
100            )*
101        );
102        $crate::peripherals_struct!(
103            $(
104                $(#[$cfg])?
105                $name,
106            )*
107        );
108    };
109}
110
111/// Convenience converting into reference.
112#[macro_export]
113macro_rules! into_ref {
114    ($($name:ident),*) => {
115        $(
116            let mut $name = $name.into_ref();
117        )*
118    }
119}
120
121/// Implement the peripheral trait.
122#[macro_export]
123macro_rules! impl_peripheral {
124    ($type:ident) => {
125        impl $crate::Peripheral for $type {
126            type P = $type;
127
128            #[inline]
129            unsafe fn clone_unchecked(&self) -> Self::P {
130                #[allow(clippy::needless_update)]
131                $type { ..*self }
132            }
133        }
134    };
135}