Implement full SSD1306 OLED display support: - Splash screen on boot (1.5s) with project name, version, board - Dashboard showing radio state, config, counters, RSSI/SNR - RSSI history sparkline (64-sample ring buffer, 2px-wide bars) - DisplayOn/DisplayOff host commands routed via dedicated channel - Pure render functions against generic DrawTarget (no hardware coupling) - Display on/off control bypasses radio task entirely Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
137 lines
3.3 KiB
Rust
137 lines
3.3 KiB
Rust
//! Macros used by the HAL.
|
|
//!
|
|
//! Most of the macros in this module are hidden and intended for internal use
|
|
//! only. For the list of public macros, see the [procmacros](https://docs.rs/esp-hal-procmacros/latest/esp_hal_procmacros/)
|
|
//! documentation.
|
|
|
|
pub use procmacros::*;
|
|
|
|
#[doc(hidden)]
|
|
/// Helper macro for checking doctest code snippets
|
|
#[macro_export]
|
|
macro_rules! before_snippet {
|
|
() => {
|
|
r#"
|
|
# #![no_std]
|
|
# use esp_hal::prelude::*;
|
|
# use procmacros::handler;
|
|
# use esp_hal::interrupt;
|
|
# macro_rules! println {
|
|
# ($($tt:tt)*) => { };
|
|
# }
|
|
# #[panic_handler]
|
|
# fn panic(_ : &core::panic::PanicInfo) -> ! {
|
|
# loop {}
|
|
# }
|
|
# fn main() {
|
|
# let mut peripherals = esp_hal::init(esp_hal::Config::default());
|
|
"#
|
|
};
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[macro_export]
|
|
macro_rules! trm_markdown_link {
|
|
() => {
|
|
concat!("[Technical Reference Manual](", $crate::trm_link!(), ")")
|
|
};
|
|
($anchor:literal) => {
|
|
concat!(
|
|
"[Technical Reference Manual](",
|
|
$crate::trm_link!(),
|
|
"#",
|
|
$anchor,
|
|
")"
|
|
)
|
|
};
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
/// Shorthand to define enums with From implementations.
|
|
#[macro_export]
|
|
macro_rules! any_enum {
|
|
($(#[$meta:meta])* $vis:vis enum $name:ident {
|
|
$(
|
|
$(#[$variant_meta:meta])*
|
|
$variant:ident($inner:ty)
|
|
),* $(,)?
|
|
}) => {
|
|
$(#[$meta])*
|
|
$vis enum $name {
|
|
$(
|
|
$(#[$variant_meta])*
|
|
$variant($inner),
|
|
)*
|
|
}
|
|
|
|
$(
|
|
$(#[$variant_meta])*
|
|
impl From<$inner> for $name {
|
|
fn from(inner: $inner) -> Self {
|
|
$name::$variant(inner)
|
|
}
|
|
}
|
|
)*
|
|
};
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
/// Shorthand to define AnyPeripheral instances.
|
|
#[macro_export]
|
|
macro_rules! any_peripheral {
|
|
($(#[$meta:meta])* $vis:vis peripheral $name:ident {
|
|
$(
|
|
$(#[cfg($variant_meta:meta)])*
|
|
$variant:ident($inner:ty)
|
|
),* $(,)?
|
|
}) => {
|
|
paste::paste! {
|
|
$(#[$meta])*
|
|
$vis struct $name([< $name Inner >]);
|
|
impl $crate::private::Sealed for $name {}
|
|
|
|
impl $crate::peripheral::Peripheral for $name {
|
|
type P = $name;
|
|
|
|
unsafe fn clone_unchecked(&self) -> Self::P {
|
|
match &self.0 {
|
|
$(
|
|
$(#[cfg($variant_meta)])*
|
|
[<$name Inner>]::$variant(inner) => $name::from(inner.clone_unchecked()),
|
|
)*
|
|
}
|
|
}
|
|
}
|
|
|
|
enum [< $name Inner >] {
|
|
$(
|
|
$(#[cfg($variant_meta)])*
|
|
$variant($inner),
|
|
)*
|
|
}
|
|
|
|
$(
|
|
$(#[cfg($variant_meta)])*
|
|
impl From<$inner> for $name {
|
|
fn from(inner: $inner) -> Self {
|
|
Self([< $name Inner >]::$variant(inner))
|
|
}
|
|
}
|
|
)*
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Macro to choose between two expressions. Useful for implementing "else" for
|
|
/// `$()?` macro syntax.
|
|
#[macro_export]
|
|
#[doc(hidden)]
|
|
macro_rules! if_set {
|
|
(, $not_set:expr) => {
|
|
$not_set
|
|
};
|
|
($set:expr, $not_set:expr) => {
|
|
$set
|
|
};
|
|
}
|