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