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