embassy_nrf/
egu.rs

1//! EGU driver.
2//!
3//! The event generator driver provides a higher level API for task triggering
4//! and events to use with PPI.
5
6#![macro_use]
7
8use core::marker::PhantomData;
9
10use embassy_hal_internal::PeripheralType;
11
12use crate::ppi::{Event, Task};
13use crate::{interrupt, pac, Peri};
14
15/// An instance of the EGU.
16pub struct Egu<'d> {
17    r: pac::egu::Egu,
18    _phantom: PhantomData<&'d ()>,
19}
20
21impl<'d> Egu<'d> {
22    /// Create a new EGU instance.
23    pub fn new<T: Instance>(_p: Peri<'d, T>) -> Self {
24        Self {
25            r: T::regs(),
26            _phantom: PhantomData,
27        }
28    }
29
30    /// Get a handle to a trigger for the EGU.
31    pub fn trigger(&mut self, number: TriggerNumber) -> Trigger<'d> {
32        Trigger {
33            number,
34            r: self.r,
35            _phantom: PhantomData,
36        }
37    }
38}
39
40pub(crate) trait SealedInstance {
41    fn regs() -> pac::egu::Egu;
42}
43
44/// Basic Egu instance.
45#[allow(private_bounds)]
46pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
47    /// Interrupt for this peripheral.
48    type Interrupt: interrupt::typelevel::Interrupt;
49}
50
51macro_rules! impl_egu {
52    ($type:ident, $pac_type:ident, $irq:ident) => {
53        impl crate::egu::SealedInstance for peripherals::$type {
54            fn regs() -> pac::egu::Egu {
55                pac::$pac_type
56            }
57        }
58        impl crate::egu::Instance for peripherals::$type {
59            type Interrupt = crate::interrupt::typelevel::$irq;
60        }
61    };
62}
63
64/// Represents a trigger within the EGU.
65pub struct Trigger<'d> {
66    number: TriggerNumber,
67    r: pac::egu::Egu,
68    _phantom: PhantomData<&'d ()>,
69}
70
71impl<'d> Trigger<'d> {
72    /// Get task for this trigger to use with PPI.
73    pub fn task(&self) -> Task<'d> {
74        let nr = self.number as usize;
75        Task::from_reg(self.r.tasks_trigger(nr))
76    }
77
78    /// Get event for this trigger to use with PPI.
79    pub fn event(&self) -> Event<'d> {
80        let nr = self.number as usize;
81        Event::from_reg(self.r.events_triggered(nr))
82    }
83
84    /// Enable interrupts for this trigger
85    pub fn enable_interrupt(&mut self) {
86        self.r
87            .intenset()
88            .modify(|w| w.set_triggered(self.number as usize, true));
89    }
90
91    /// Enable interrupts for this trigger
92    pub fn disable_interrupt(&mut self) {
93        self.r
94            .intenset()
95            .modify(|w| w.set_triggered(self.number as usize, false));
96    }
97}
98
99/// Represents a trigger within an EGU.
100#[allow(missing_docs)]
101#[derive(Clone, Copy, PartialEq)]
102#[repr(u8)]
103pub enum TriggerNumber {
104    Trigger0 = 0,
105    Trigger1 = 1,
106    Trigger2 = 2,
107    Trigger3 = 3,
108    Trigger4 = 4,
109    Trigger5 = 5,
110    Trigger6 = 6,
111    Trigger7 = 7,
112    Trigger8 = 8,
113    Trigger9 = 9,
114    Trigger10 = 10,
115    Trigger11 = 11,
116    Trigger12 = 12,
117    Trigger13 = 13,
118    Trigger14 = 14,
119    Trigger15 = 15,
120}