diff options
| author | Dion Dokter <[email protected]> | 2021-10-19 10:13:08 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-10-26 14:47:31 +0200 |
| commit | a6c84cb91552fc0442a28126d3fae60031aa6622 (patch) | |
| tree | 260555ec0c58eb5e2053f4031889b4260bb9ebea /embassy-nrf/src | |
| parent | 531dfcffb3c203dff15dcb53fe25577c121c7784 (diff) | |
- Interconnect is now PPI again
- Scary pointer math is now contained in the tasks and events
- ppi now sets the tasks and events immediately and the struct is now zero-sized
- StaticToOne is renamed to ZeroToOne
- Used DPPI tasks and events now panic when enabled twice
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/interconnect/dppi.rs | 47 | ||||
| -rw-r--r-- | embassy-nrf/src/interconnect/ppi.rs | 65 | ||||
| -rw-r--r-- | embassy-nrf/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi/dppi.rs | 61 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi/mod.rs (renamed from embassy-nrf/src/interconnect/mod.rs) | 119 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi/ppi.rs | 77 | ||||
| -rw-r--r-- | embassy-nrf/src/timer.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 2 |
10 files changed, 206 insertions, 173 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 7c9a2344e..1dc04f4f6 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -14,8 +14,8 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; | |||
| 14 | 14 | ||
| 15 | use crate::gpio::sealed::Pin as _; | 15 | use crate::gpio::sealed::Pin as _; |
| 16 | use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; | 16 | use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; |
| 17 | use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; | ||
| 18 | use crate::pac; | 17 | use crate::pac; |
| 18 | use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; | ||
| 19 | use crate::timer::Instance as TimerInstance; | 19 | use crate::timer::Instance as TimerInstance; |
| 20 | use crate::timer::{Frequency, Timer}; | 20 | use crate::timer::{Frequency, Timer}; |
| 21 | use crate::uarte::{Config, Instance as UarteInstance}; | 21 | use crate::uarte::{Config, Instance as UarteInstance}; |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 6703bfc60..7ec072ac8 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -11,8 +11,8 @@ use futures::future::poll_fn; | |||
| 11 | 11 | ||
| 12 | use crate::gpio::sealed::Pin as _; | 12 | use crate::gpio::sealed::Pin as _; |
| 13 | use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin}; | 13 | use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin}; |
| 14 | use crate::interconnect::{Event, Task}; | ||
| 15 | use crate::pac; | 14 | use crate::pac; |
| 15 | use crate::ppi::{Event, Task}; | ||
| 16 | use crate::{interrupt, peripherals}; | 16 | use crate::{interrupt, peripherals}; |
| 17 | 17 | ||
| 18 | pub const CHANNEL_COUNT: usize = 8; | 18 | pub const CHANNEL_COUNT: usize = 8; |
diff --git a/embassy-nrf/src/interconnect/dppi.rs b/embassy-nrf/src/interconnect/dppi.rs deleted file mode 100644 index 60f19fca0..000000000 --- a/embassy-nrf/src/interconnect/dppi.rs +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | use super::{Channel, Event, Ppi, Task}; | ||
| 2 | |||
| 3 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | ||
| 4 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | ||
| 5 | const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>(); | ||
| 6 | |||
| 7 | impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> | ||
| 8 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 9 | { | ||
| 10 | pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) { | ||
| 11 | unsafe { | ||
| 12 | task.0 | ||
| 13 | .as_ptr() | ||
| 14 | .add(REGISTER_DPPI_CONFIG_OFFSET) | ||
| 15 | .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) { | ||
| 20 | unsafe { | ||
| 21 | task.0 | ||
| 22 | .as_ptr() | ||
| 23 | .add(REGISTER_DPPI_CONFIG_OFFSET) | ||
| 24 | .write_volatile(0); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { | ||
| 29 | unsafe { | ||
| 30 | event | ||
| 31 | .0 | ||
| 32 | .as_ptr() | ||
| 33 | .add(REGISTER_DPPI_CONFIG_OFFSET) | ||
| 34 | .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) { | ||
| 39 | unsafe { | ||
| 40 | event | ||
| 41 | .0 | ||
| 42 | .as_ptr() | ||
| 43 | .add(REGISTER_DPPI_CONFIG_OFFSET) | ||
| 44 | .write_volatile(0); | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/embassy-nrf/src/interconnect/ppi.rs b/embassy-nrf/src/interconnect/ppi.rs deleted file mode 100644 index 91ff811fe..000000000 --- a/embassy-nrf/src/interconnect/ppi.rs +++ /dev/null | |||
| @@ -1,65 +0,0 @@ | |||
| 1 | use super::{Channel, Event, Ppi, Task}; | ||
| 2 | use crate::pac; | ||
| 3 | |||
| 4 | impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> | ||
| 5 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 6 | { | ||
| 7 | pub(super) fn enable_task(task: &Task, channel: &C, index: usize) { | ||
| 8 | match (index, channel.is_task_configurable()) { | ||
| 9 | (0, false) => Self::set_fork_task(Some(task), channel.number()), // Static channel with fork | ||
| 10 | (0, true) => Self::set_main_task(Some(task), channel.number()), // Configurable channel without fork | ||
| 11 | (1, true) => Self::set_fork_task(Some(task), channel.number()), // Configurable channel with fork | ||
| 12 | _ => unreachable!("{}, {}", index, channel.is_task_configurable()), // Not available with the PPI, so should not be constructable | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | pub(super) fn disable_task(_task: &Task, channel: &C, index: usize) { | ||
| 17 | match (index, channel.is_task_configurable()) { | ||
| 18 | (0, false) => Self::set_fork_task(None, channel.number()), // Static channel with fork | ||
| 19 | (0, true) => Self::set_main_task(None, channel.number()), // Configurable channel without fork | ||
| 20 | (1, true) => Self::set_fork_task(None, channel.number()), // Configurable channel with fork | ||
| 21 | _ => unreachable!(), // Not available with the PPI, so should not be constructable | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { | ||
| 26 | Self::set_event(Some(event), channel.number()) | ||
| 27 | } | ||
| 28 | |||
| 29 | pub(super) fn disable_event(_event: &Event, channel: &C, _index: usize) { | ||
| 30 | Self::set_event(None, channel.number()) | ||
| 31 | } | ||
| 32 | |||
| 33 | fn set_main_task(task: Option<&Task>, channel: usize) { | ||
| 34 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 35 | if let Some(task) = task { | ||
| 36 | r.ch[channel] | ||
| 37 | .tep | ||
| 38 | .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) | ||
| 39 | } else { | ||
| 40 | r.ch[channel].tep.write(|w| unsafe { w.bits(0) }) | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | fn set_fork_task(task: Option<&Task>, channel: usize) { | ||
| 45 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 46 | if let Some(task) = task { | ||
| 47 | r.fork[channel] | ||
| 48 | .tep | ||
| 49 | .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) | ||
| 50 | } else { | ||
| 51 | r.fork[channel].tep.write(|w| unsafe { w.bits(0) }) | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | fn set_event(event: Option<&Event>, channel: usize) { | ||
| 56 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 57 | if let Some(event) = event { | ||
| 58 | r.ch[channel] | ||
| 59 | .eep | ||
| 60 | .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) | ||
| 61 | } else { | ||
| 62 | r.ch[channel].eep.write(|w| unsafe { w.bits(0) }) | ||
| 63 | } | ||
| 64 | } | ||
| 65 | } | ||
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 39f3e4a4a..c21c4d398 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -31,7 +31,7 @@ pub mod gpio; | |||
| 31 | pub mod gpiote; | 31 | pub mod gpiote; |
| 32 | #[cfg(not(feature = "nrf9160"))] | 32 | #[cfg(not(feature = "nrf9160"))] |
| 33 | pub mod nvmc; | 33 | pub mod nvmc; |
| 34 | pub mod interconnect; | 34 | pub mod ppi; |
| 35 | #[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] | 35 | #[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] |
| 36 | pub mod pwm; | 36 | pub mod pwm; |
| 37 | #[cfg(feature = "nrf52840")] | 37 | #[cfg(feature = "nrf52840")] |
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs new file mode 100644 index 000000000..083ec858a --- /dev/null +++ b/embassy-nrf/src/ppi/dppi.rs | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | use super::{Channel, Event, Ppi, Task}; | ||
| 2 | |||
| 3 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | ||
| 4 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | ||
| 5 | |||
| 6 | impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> | ||
| 7 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 8 | { | ||
| 9 | pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) { | ||
| 10 | unsafe { | ||
| 11 | if task.subscribe_reg().read_volatile() != 0 { | ||
| 12 | panic!("Task is already in use"); | ||
| 13 | } | ||
| 14 | task.subscribe_reg() | ||
| 15 | .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) { | ||
| 20 | unsafe { | ||
| 21 | task.subscribe_reg().write_volatile(0); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { | ||
| 26 | unsafe { | ||
| 27 | if event.publish_reg().read_volatile() != 0 { | ||
| 28 | panic!("Task is already in use"); | ||
| 29 | } | ||
| 30 | event | ||
| 31 | .publish_reg() | ||
| 32 | .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) { | ||
| 37 | unsafe { | ||
| 38 | event.publish_reg().write_volatile(0); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | /// Enables all tasks and events | ||
| 43 | pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { | ||
| 44 | for (index, task) in tasks.iter().enumerate() { | ||
| 45 | Self::enable_task(task, channel, index); | ||
| 46 | } | ||
| 47 | for (index, event) in events.iter().enumerate() { | ||
| 48 | Self::enable_event(event, channel, index); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Disable all tasks and events | ||
| 53 | pub(super) fn disable_all(&self) { | ||
| 54 | for (index, task) in self.tasks.iter().enumerate() { | ||
| 55 | Self::disable_task(task, &self.ch, index); | ||
| 56 | } | ||
| 57 | for (index, event) in self.events.iter().enumerate() { | ||
| 58 | Self::disable_event(event, &self.ch, index); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
diff --git a/embassy-nrf/src/interconnect/mod.rs b/embassy-nrf/src/ppi/mod.rs index 8cb505bdc..ffb6af020 100644 --- a/embassy-nrf/src/interconnect/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs | |||
| @@ -28,12 +28,14 @@ mod ppi; | |||
| 28 | 28 | ||
| 29 | pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { | 29 | pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { |
| 30 | ch: C, | 30 | ch: C, |
| 31 | #[cfg(feature = "_dppi")] | ||
| 31 | events: [Event; EVENT_COUNT], | 32 | events: [Event; EVENT_COUNT], |
| 33 | #[cfg(feature = "_dppi")] | ||
| 32 | tasks: [Task; TASK_COUNT], | 34 | tasks: [Task; TASK_COUNT], |
| 33 | phantom: PhantomData<&'d mut C>, | 35 | phantom: PhantomData<&'d mut C>, |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> | 38 | impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> |
| 37 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | 39 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> |
| 38 | { | 40 | { |
| 39 | pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { | 41 | pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { |
| @@ -43,7 +45,9 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> | |||
| 43 | #[cfg(feature = "_ppi")] | 45 | #[cfg(feature = "_ppi")] |
| 44 | has_configurable_task: self.ch.is_task_configurable(), | 46 | has_configurable_task: self.ch.is_task_configurable(), |
| 45 | }, | 47 | }, |
| 48 | #[cfg(feature = "_dppi")] | ||
| 46 | events: self.events, | 49 | events: self.events, |
| 50 | #[cfg(feature = "_dppi")] | ||
| 47 | tasks: self.tasks, | 51 | tasks: self.tasks, |
| 48 | phantom: PhantomData, | 52 | phantom: PhantomData, |
| 49 | } | 53 | } |
| @@ -62,26 +66,6 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> | |||
| 62 | r.chenclr | 66 | r.chenclr |
| 63 | .write(|w| unsafe { w.bits(1 << self.ch.number()) }); | 67 | .write(|w| unsafe { w.bits(1 << self.ch.number()) }); |
| 64 | } | 68 | } |
| 65 | |||
| 66 | /// Enables all tasks and events | ||
| 67 | fn enable_all(&self) { | ||
| 68 | for (index, task) in self.tasks.iter().enumerate() { | ||
| 69 | Self::enable_task(task, &self.ch, index); | ||
| 70 | } | ||
| 71 | for (index, event) in self.events.iter().enumerate() { | ||
| 72 | Self::enable_event(event, &self.ch, index); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | /// Disable all tasks and events | ||
| 77 | fn disable_all(&self) { | ||
| 78 | for (index, task) in self.tasks.iter().enumerate() { | ||
| 79 | Self::disable_task(task, &self.ch, index); | ||
| 80 | } | ||
| 81 | for (index, event) in self.events.iter().enumerate() { | ||
| 82 | Self::disable_event(event, &self.ch, index); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | 69 | } |
| 86 | 70 | ||
| 87 | impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop | 71 | impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop |
| @@ -93,19 +77,23 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop | |||
| 93 | } | 77 | } |
| 94 | } | 78 | } |
| 95 | 79 | ||
| 96 | impl<'d, C: StaticToOneChannel> Ppi<'d, C, 0, 1> { | 80 | impl<'d, C: ZeroToOneChannel> Ppi<'d, C, 0, 1> { |
| 97 | pub fn new_static_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self { | 81 | pub fn new_static_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self { |
| 98 | unborrow!(ch); | 82 | unborrow!(ch); |
| 99 | 83 | ||
| 100 | let s = Self { | 84 | let events = []; |
| 85 | let tasks = [task]; | ||
| 86 | |||
| 87 | Self::enable_all(&tasks, &events, &ch); | ||
| 88 | |||
| 89 | Self { | ||
| 101 | ch, | 90 | ch, |
| 102 | events: [], | 91 | #[cfg(feature = "_dppi")] |
| 103 | tasks: [task], | 92 | events, |
| 93 | #[cfg(feature = "_dppi")] | ||
| 94 | tasks, | ||
| 104 | phantom: PhantomData, | 95 | phantom: PhantomData, |
| 105 | }; | 96 | } |
| 106 | |||
| 107 | s.enable_all(); | ||
| 108 | s | ||
| 109 | } | 97 | } |
| 110 | } | 98 | } |
| 111 | 99 | ||
| @@ -113,15 +101,19 @@ impl<'d, C: OneToOneChannel> Ppi<'d, C, 1, 1> { | |||
| 113 | pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self { | 101 | pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self { |
| 114 | unborrow!(ch); | 102 | unborrow!(ch); |
| 115 | 103 | ||
| 116 | let s = Self { | 104 | let events = [event]; |
| 105 | let tasks = [task]; | ||
| 106 | |||
| 107 | Self::enable_all(&tasks, &events, &ch); | ||
| 108 | |||
| 109 | Self { | ||
| 117 | ch, | 110 | ch, |
| 118 | events: [event], | 111 | #[cfg(feature = "_dppi")] |
| 119 | tasks: [task], | 112 | events, |
| 113 | #[cfg(feature = "_dppi")] | ||
| 114 | tasks, | ||
| 120 | phantom: PhantomData, | 115 | phantom: PhantomData, |
| 121 | }; | 116 | } |
| 122 | |||
| 123 | s.enable_all(); | ||
| 124 | s | ||
| 125 | } | 117 | } |
| 126 | } | 118 | } |
| 127 | 119 | ||
| @@ -134,15 +126,19 @@ impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> { | |||
| 134 | ) -> Self { | 126 | ) -> Self { |
| 135 | unborrow!(ch); | 127 | unborrow!(ch); |
| 136 | 128 | ||
| 137 | let s = Self { | 129 | let events = [event]; |
| 130 | let tasks = [task1, task2]; | ||
| 131 | |||
| 132 | Self::enable_all(&tasks, &events, &ch); | ||
| 133 | |||
| 134 | Self { | ||
| 138 | ch, | 135 | ch, |
| 139 | events: [event], | 136 | #[cfg(feature = "_dppi")] |
| 140 | tasks: [task1, task2], | 137 | events, |
| 138 | #[cfg(feature = "_dppi")] | ||
| 139 | tasks, | ||
| 141 | phantom: PhantomData, | 140 | phantom: PhantomData, |
| 142 | }; | 141 | } |
| 143 | |||
| 144 | s.enable_all(); | ||
| 145 | s | ||
| 146 | } | 142 | } |
| 147 | } | 143 | } |
| 148 | 144 | ||
| @@ -156,18 +152,21 @@ impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize | |||
| 156 | ) -> Self { | 152 | ) -> Self { |
| 157 | unborrow!(ch); | 153 | unborrow!(ch); |
| 158 | 154 | ||
| 159 | let s = Self { | 155 | Self::enable_all(&tasks, &events, &ch); |
| 156 | |||
| 157 | Self { | ||
| 160 | ch, | 158 | ch, |
| 159 | #[cfg(feature = "_dppi")] | ||
| 161 | events, | 160 | events, |
| 161 | #[cfg(feature = "_dppi")] | ||
| 162 | tasks, | 162 | tasks, |
| 163 | phantom: PhantomData, | 163 | phantom: PhantomData, |
| 164 | }; | 164 | } |
| 165 | |||
| 166 | s.enable_all(); | ||
| 167 | s | ||
| 168 | } | 165 | } |
| 169 | } | 166 | } |
| 170 | 167 | ||
| 168 | const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>(); | ||
| 169 | |||
| 171 | /// Represents a task that a peripheral can do. | 170 | /// Represents a task that a peripheral can do. |
| 172 | /// When a task is subscribed to a PPI channel it will run when the channel is triggered by | 171 | /// When a task is subscribed to a PPI channel it will run when the channel is triggered by |
| 173 | /// a published event. | 172 | /// a published event. |
| @@ -179,6 +178,10 @@ impl Task { | |||
| 179 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | 178 | pub(crate) fn from_reg<T>(reg: &T) -> Self { |
| 180 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) | 179 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) |
| 181 | } | 180 | } |
| 181 | |||
| 182 | pub fn subscribe_reg(&self) -> *mut u32 { | ||
| 183 | unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) } | ||
| 184 | } | ||
| 182 | } | 185 | } |
| 183 | 186 | ||
| 184 | /// # Safety | 187 | /// # Safety |
| @@ -196,6 +199,10 @@ impl Event { | |||
| 196 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | 199 | pub(crate) fn from_reg<T>(reg: &T) -> Self { |
| 197 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) | 200 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) |
| 198 | } | 201 | } |
| 202 | |||
| 203 | pub fn publish_reg(&self) -> *mut u32 { | ||
| 204 | unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) } | ||
| 205 | } | ||
| 199 | } | 206 | } |
| 200 | 207 | ||
| 201 | /// # Safety | 208 | /// # Safety |
| @@ -218,8 +225,8 @@ pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized { | |||
| 218 | fn is_task_configurable(&self) -> bool; | 225 | fn is_task_configurable(&self) -> bool; |
| 219 | } | 226 | } |
| 220 | 227 | ||
| 221 | pub trait StaticToOneChannel: Channel {} | 228 | pub trait ZeroToOneChannel: Channel {} |
| 222 | pub trait OneToOneChannel: StaticToOneChannel {} | 229 | pub trait OneToOneChannel: ZeroToOneChannel {} |
| 223 | pub trait OneToTwoChannel: OneToOneChannel {} | 230 | pub trait OneToTwoChannel: OneToOneChannel {} |
| 224 | pub trait ManyToManyChannel: OneToTwoChannel {} | 231 | pub trait ManyToManyChannel: OneToTwoChannel {} |
| 225 | 232 | ||
| @@ -250,8 +257,8 @@ impl Channel for AnyChannel { | |||
| 250 | 257 | ||
| 251 | macro_rules! impl_ppi_channel { | 258 | macro_rules! impl_ppi_channel { |
| 252 | ($type:ident, $number:expr, $has_configurable_task:expr) => { | 259 | ($type:ident, $number:expr, $has_configurable_task:expr) => { |
| 253 | impl crate::interconnect::sealed::Channel for peripherals::$type {} | 260 | impl crate::ppi::sealed::Channel for peripherals::$type {} |
| 254 | impl crate::interconnect::Channel for peripherals::$type { | 261 | impl crate::ppi::Channel for peripherals::$type { |
| 255 | fn number(&self) -> usize { | 262 | fn number(&self) -> usize { |
| 256 | $number | 263 | $number |
| 257 | } | 264 | } |
| @@ -267,19 +274,19 @@ macro_rules! impl_ppi_channel { | |||
| 267 | }; | 274 | }; |
| 268 | ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { | 275 | ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { |
| 269 | impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); | 276 | impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); |
| 270 | impl crate::interconnect::StaticToOneChannel for peripherals::$type {} | 277 | impl crate::ppi::ZeroToOneChannel for peripherals::$type {} |
| 271 | }; | 278 | }; |
| 272 | ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { | 279 | ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { |
| 273 | impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); | 280 | impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); |
| 274 | impl crate::interconnect::OneToOneChannel for peripherals::$type {} | 281 | impl crate::ppi::OneToOneChannel for peripherals::$type {} |
| 275 | }; | 282 | }; |
| 276 | ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { | 283 | ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { |
| 277 | impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); | 284 | impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); |
| 278 | impl crate::interconnect::OneToTwoChannel for peripherals::$type {} | 285 | impl crate::ppi::OneToTwoChannel for peripherals::$type {} |
| 279 | }; | 286 | }; |
| 280 | ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { | 287 | ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { |
| 281 | impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); | 288 | impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); |
| 282 | impl crate::interconnect::ManyToManyChannel for peripherals::$type {} | 289 | impl crate::ppi::ManyToManyChannel for peripherals::$type {} |
| 283 | }; | 290 | }; |
| 284 | } | 291 | } |
| 285 | 292 | ||
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs new file mode 100644 index 000000000..67d2086c3 --- /dev/null +++ b/embassy-nrf/src/ppi/ppi.rs | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | use super::{Channel, Event, Ppi, Task}; | ||
| 2 | use crate::pac; | ||
| 3 | |||
| 4 | impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> | ||
| 5 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 6 | { | ||
| 7 | fn set_main_task(task: Option<&Task>, channel: usize) { | ||
| 8 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 9 | if let Some(task) = task { | ||
| 10 | r.ch[channel] | ||
| 11 | .tep | ||
| 12 | .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) | ||
| 13 | } else { | ||
| 14 | r.ch[channel].tep.write(|w| unsafe { w.bits(0) }) | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | fn set_fork_task(task: Option<&Task>, channel: usize) { | ||
| 19 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 20 | if let Some(task) = task { | ||
| 21 | r.fork[channel] | ||
| 22 | .tep | ||
| 23 | .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) | ||
| 24 | } else { | ||
| 25 | r.fork[channel].tep.write(|w| unsafe { w.bits(0) }) | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | fn set_event(event: Option<&Event>, channel: usize) { | ||
| 30 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 31 | if let Some(event) = event { | ||
| 32 | r.ch[channel] | ||
| 33 | .eep | ||
| 34 | .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) | ||
| 35 | } else { | ||
| 36 | r.ch[channel].eep.write(|w| unsafe { w.bits(0) }) | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | /// Enables all tasks and events | ||
| 41 | pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { | ||
| 42 | // One configurable task, no fork | ||
| 43 | if channel.is_task_configurable() && TASK_COUNT == 1 { | ||
| 44 | Self::set_main_task(Some(&tasks[0]), channel.number()); | ||
| 45 | } | ||
| 46 | |||
| 47 | // One configurable task, as fork | ||
| 48 | if !channel.is_task_configurable() && TASK_COUNT == 1 { | ||
| 49 | Self::set_fork_task(Some(&tasks[0]), channel.number()); | ||
| 50 | } | ||
| 51 | |||
| 52 | // Two configurable tasks (main + fork) | ||
| 53 | if TASK_COUNT == 2 { | ||
| 54 | Self::set_main_task(Some(&tasks[0]), channel.number()); | ||
| 55 | Self::set_fork_task(Some(&tasks[1]), channel.number()); | ||
| 56 | } | ||
| 57 | |||
| 58 | if EVENT_COUNT == 1 { | ||
| 59 | Self::set_event(Some(&events[0]), channel.number()); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | /// Disable all tasks and events | ||
| 64 | pub(super) fn disable_all(&self) { | ||
| 65 | if self.ch.is_task_configurable() { | ||
| 66 | Self::set_main_task(None, self.ch.number()); | ||
| 67 | } | ||
| 68 | |||
| 69 | if TASK_COUNT == 1 && !self.ch.is_task_configurable() || TASK_COUNT == 2 { | ||
| 70 | Self::set_fork_task(None, self.ch.number()); | ||
| 71 | } | ||
| 72 | |||
| 73 | if EVENT_COUNT == 1 { | ||
| 74 | Self::set_event(None, self.ch.number()); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | } | ||
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 27f8e715e..9173338b6 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -11,8 +11,8 @@ use embassy_hal_common::drop::OnDrop; | |||
| 11 | use embassy_hal_common::unborrow; | 11 | use embassy_hal_common::unborrow; |
| 12 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 13 | 13 | ||
| 14 | use crate::interconnect::{Event, Task}; | ||
| 15 | use crate::pac; | 14 | use crate::pac; |
| 15 | use crate::ppi::{Event, Task}; | ||
| 16 | 16 | ||
| 17 | pub(crate) mod sealed { | 17 | pub(crate) mod sealed { |
| 18 | 18 | ||
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 17e60ce22..36cf65d89 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -16,9 +16,9 @@ use futures::future::poll_fn; | |||
| 16 | use crate::chip::EASY_DMA_SIZE; | 16 | use crate::chip::EASY_DMA_SIZE; |
| 17 | use crate::gpio::sealed::Pin as _; | 17 | use crate::gpio::sealed::Pin as _; |
| 18 | use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; | 18 | use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; |
| 19 | use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; | ||
| 20 | use crate::interrupt::Interrupt; | 19 | use crate::interrupt::Interrupt; |
| 21 | use crate::pac; | 20 | use crate::pac; |
| 21 | use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; | ||
| 22 | use crate::timer::Instance as TimerInstance; | 22 | use crate::timer::Instance as TimerInstance; |
| 23 | use crate::timer::{Frequency, Timer}; | 23 | use crate::timer::{Frequency, Timer}; |
| 24 | 24 | ||
