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}
136