feat: add display UI with splash screen, dashboard, and RSSI sparkline
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>
This commit is contained in:
17624 files changed
+4564928
-38
No files matched your search
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
//! Interrupts
|
||||
|
||||
// NOTE: Adapted from cortex-m/src/interrupt.rs
|
||||
|
||||
use crate::result::Result;
|
||||
|
||||
// re-export useful riscv-pac traits
|
||||
pub use riscv_pac::{CoreInterruptNumber, ExceptionNumber, InterruptNumber};
|
||||
|
||||
pub mod machine;
|
||||
pub mod supervisor;
|
||||
|
||||
#[cfg(not(feature = "s-mode"))]
|
||||
pub use machine::*;
|
||||
#[cfg(feature = "s-mode")]
|
||||
pub use supervisor::*;
|
||||
|
||||
/// Trap Cause.
|
||||
///
|
||||
/// This enum represents the cause of a trap. It can be either an interrupt or an exception.
|
||||
/// The [`mcause`](crate::register::mcause::Mcause::cause) and
|
||||
/// [`scause`](crate::register::scause::Scause::cause) registers return a value of this type.
|
||||
/// However, the trap cause is represented as raw numbers. To get a target-specific trap cause,
|
||||
/// use [`Trap::try_into`] with your target-specific M-Mode or S-Mode trap cause types.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// In targets that comply with the RISC-V standard, you can use the standard
|
||||
/// [`Interrupt`] and [`Exception`] enums to represent the trap cause:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use riscv::interrupt::{Trap, Interrupt, Exception};
|
||||
/// use riscv::register::mcause;
|
||||
///
|
||||
/// let raw_trap: Trap<usize, usize> = mcause::read().cause();
|
||||
/// let standard_trap: Trap<Interrupt, Exception> = raw_trap.try_into().unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// Targets that do not comply with the RISC-V standard usually have their own interrupt and exceptions.
|
||||
/// You can find these types in the target-specific PAC. If it has been generated with `svd2rust`,
|
||||
/// you can use the `pac::interrupt::CoreInterrupt` and `pac::interrupt::Exception` enums:
|
||||
///
|
||||
/// ```ignore,no_run
|
||||
/// use riscv::interrupt::Trap;
|
||||
/// use pac::interrupt::{CoreInterrupt, Exception}; // pac is the target-specific PAC
|
||||
///
|
||||
/// let standard_trap: Trap<CoreInterrupt, Exception> = pac::interrupt::cause();
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Trap<I, E> {
|
||||
Interrupt(I),
|
||||
Exception(E),
|
||||
}
|
||||
|
||||
/// Trap Error
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum TrapError {
|
||||
InvalidInterrupt(usize),
|
||||
InvalidException(usize),
|
||||
}
|
||||
|
||||
impl Trap<usize, usize> {
|
||||
/// Converts a target-specific trap cause to a generic trap cause
|
||||
#[inline]
|
||||
pub fn from<I: CoreInterruptNumber, E: ExceptionNumber>(trap: Trap<I, E>) -> Self {
|
||||
match trap {
|
||||
Trap::Interrupt(interrupt) => Trap::Interrupt(interrupt.number()),
|
||||
Trap::Exception(exception) => Trap::Exception(exception.number()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to convert the generic trap cause to a target-specific trap cause
|
||||
#[inline]
|
||||
pub fn try_into<I, E>(self) -> Result<Trap<I, E>>
|
||||
where
|
||||
I: CoreInterruptNumber,
|
||||
E: ExceptionNumber,
|
||||
{
|
||||
match self {
|
||||
Trap::Interrupt(code) => Ok(Trap::Interrupt(I::from_number(code)?)),
|
||||
Trap::Exception(code) => Ok(Trap::Exception(E::from_number(code)?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: CoreInterruptNumber, E: ExceptionNumber> Trap<I, E> {
|
||||
/// Converts a target-specific trap cause to a generic trap cause
|
||||
#[inline]
|
||||
pub fn into(self) -> Trap<usize, usize> {
|
||||
Trap::from(self)
|
||||
}
|
||||
|
||||
/// Tries to convert the generic trap cause to a target-specific trap cause
|
||||
#[inline]
|
||||
pub fn try_from(trap: Trap<usize, usize>) -> Result<Self> {
|
||||
trap.try_into()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user