aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/egu.rs
blob: 666986115475af3fe1a74509396b43fb6d63b85e (plain)
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
//! EGU driver.
//!
//! The event generator driver provides a higher level API for task triggering
//! and events to use with PPI.

#![macro_use]

use core::marker::PhantomData;

use embassy_hal_internal::PeripheralType;

use crate::ppi::{Event, Task};
use crate::{Peri, interrupt, pac};

/// An instance of the EGU.
pub struct Egu<'d> {
    r: pac::egu::Egu,
    _phantom: PhantomData<&'d ()>,
}

impl<'d> Egu<'d> {
    /// Create a new EGU instance.
    pub fn new<T: Instance>(_p: Peri<'d, T>) -> Self {
        Self {
            r: T::regs(),
            _phantom: PhantomData,
        }
    }

    /// Get a handle to a trigger for the EGU.
    pub fn trigger(&mut self, number: TriggerNumber) -> Trigger<'d> {
        Trigger {
            number,
            r: self.r,
            _phantom: PhantomData,
        }
    }
}

pub(crate) trait SealedInstance {
    fn regs() -> pac::egu::Egu;
}

/// Basic Egu instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
    /// Interrupt for this peripheral.
    type Interrupt: interrupt::typelevel::Interrupt;
}

macro_rules! impl_egu {
    ($type:ident, $pac_type:ident, $irq:ident) => {
        impl crate::egu::SealedInstance for peripherals::$type {
            fn regs() -> pac::egu::Egu {
                pac::$pac_type
            }
        }
        impl crate::egu::Instance for peripherals::$type {
            type Interrupt = crate::interrupt::typelevel::$irq;
        }
    };
}

/// Represents a trigger within the EGU.
pub struct Trigger<'d> {
    number: TriggerNumber,
    r: pac::egu::Egu,
    _phantom: PhantomData<&'d ()>,
}

impl<'d> Trigger<'d> {
    /// Get task for this trigger to use with PPI.
    pub fn task(&self) -> Task<'d> {
        let nr = self.number as usize;
        Task::from_reg(self.r.tasks_trigger(nr))
    }

    /// Get event for this trigger to use with PPI.
    pub fn event(&self) -> Event<'d> {
        let nr = self.number as usize;
        Event::from_reg(self.r.events_triggered(nr))
    }

    /// Enable interrupts for this trigger
    pub fn enable_interrupt(&mut self) {
        self.r
            .intenset()
            .modify(|w| w.set_triggered(self.number as usize, true));
    }

    /// Enable interrupts for this trigger
    pub fn disable_interrupt(&mut self) {
        self.r
            .intenset()
            .modify(|w| w.set_triggered(self.number as usize, false));
    }
}

/// Represents a trigger within an EGU.
#[allow(missing_docs)]
#[derive(Clone, Copy, PartialEq)]
#[repr(u8)]
pub enum TriggerNumber {
    Trigger0 = 0,
    Trigger1 = 1,
    Trigger2 = 2,
    Trigger3 = 3,
    Trigger4 = 4,
    Trigger5 = 5,
    Trigger6 = 6,
    Trigger7 = 7,
    Trigger8 = 8,
    Trigger9 = 9,
    Trigger10 = 10,
    Trigger11 = 11,
    Trigger12 = 12,
    Trigger13 = 13,
    Trigger14 = 14,
    Trigger15 = 15,
}