embassy/embassy-hal-internal/src/macros.rs

136 lines
3.8 KiB
Rust
Raw Normal View History

/// Types for the peripheral singletons.
#[macro_export]
macro_rules! peripherals_definition {
2021-03-27 03:12:58 +01:00
($($(#[$cfg:meta])? $name:ident),*$(,)?) => {
2023-02-01 00:48:33 +01:00
/// Types for the peripheral singletons.
2021-03-21 21:58:59 +01:00
pub mod peripherals {
$(
$(#[$cfg])?
#[allow(non_camel_case_types)]
2023-02-01 00:48:33 +01:00
#[doc = concat!(stringify!($name), " peripheral")]
2021-03-27 03:12:58 +01:00
pub struct $name { _private: () }
2021-03-21 21:58:59 +01:00
$(#[$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.
2021-03-21 21:58:59 +01:00
#[inline]
pub unsafe fn steal() -> Self {
2021-03-21 21:58:59 +01:00
Self{ _private: ()}
}
}
2021-03-21 21:58:59 +01:00
$(#[$cfg])?
$crate::impl_peripheral!($name);
2021-03-21 21:58:59 +01:00
)*
}
};
}
/// Define the peripherals struct.
#[macro_export]
macro_rules! peripherals_struct {
($($(#[$cfg:meta])? $name:ident),*$(,)?) => {
2023-02-01 00:48:33 +01:00
/// Struct containing all the peripheral singletons.
///
/// To obtain the peripherals, you must initialize the HAL, by calling [`crate::init`].
2021-03-27 03:12:58 +01:00
#[allow(non_snake_case)]
pub struct Peripherals {
$(
2023-02-01 00:48:33 +01:00
#[doc = concat!(stringify!($name), " peripheral")]
$(#[$cfg])?
2021-03-27 03:12:58 +01:00
pub $name: peripherals::$name,
)*
}
impl Peripherals {
2021-03-21 21:58:59 +01:00
///Returns all the peripherals *once*
#[inline]
pub(crate) fn take() -> Self {
critical_section::with(Self::take_with_cs)
}
2021-03-21 21:58:59 +01:00
///Returns all the peripherals *once*
#[inline]
pub(crate) fn take_with_cs(_cs: critical_section::CriticalSection) -> Self {
2021-03-21 21:58:59 +01:00
#[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!")
2021-03-21 21:58:59 +01:00
}
_EMBASSY_DEVICE_PERIPHERALS = true;
Self::steal()
}
2021-03-21 21:58:59 +01:00
}
}
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.
2021-03-21 21:58:59 +01:00
#[inline]
pub unsafe fn steal() -> Self {
Self {
$(
$(#[$cfg])?
$name: peripherals::$name::steal(),
)*
}
}
}
};
}
2021-03-21 22:09:06 +01:00
/// 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.
2021-03-21 22:09:06 +01:00
#[macro_export]
macro_rules! into_ref {
2021-03-21 22:09:06 +01:00
($($name:ident),*) => {
$(
let mut $name = $name.into_ref();
2021-03-21 22:09:06 +01:00
)*
}
}
2021-03-27 03:33:32 +01:00
/// Implement the peripheral trait.
2021-03-27 03:33:32 +01:00
#[macro_export]
macro_rules! impl_peripheral {
2021-03-27 03:33:32 +01:00
($type:ident) => {
impl $crate::Peripheral for $type {
type P = $type;
2022-07-22 15:22:00 +02:00
2021-03-27 03:33:32 +01:00
#[inline]
unsafe fn clone_unchecked(&self) -> Self::P {
2023-08-06 22:00:39 +02:00
#[allow(clippy::needless_update)]
2022-07-22 15:22:00 +02:00
$type { ..*self }
2021-03-27 03:33:32 +01:00
}
}
};
}