diff options
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 54 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52805.rs | 44 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52810.rs | 64 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52811.rs | 64 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52820.rs | 64 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52832.rs | 64 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52833.rs | 64 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52840.rs | 64 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf9160.rs | 32 | ||||
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 28 | ||||
| -rw-r--r-- | embassy-nrf/src/interconnect/dppi.rs | 47 | ||||
| -rw-r--r-- | embassy-nrf/src/interconnect/mod.rs | 318 | ||||
| -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.rs | 513 | ||||
| -rw-r--r-- | embassy-nrf/src/timer.rs | 38 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 52 | ||||
| -rw-r--r-- | examples/nrf/src/bin/buffered_uart.rs | 4 | ||||
| -rw-r--r-- | examples/nrf/src/bin/ppi.rs | 24 | ||||
| -rw-r--r-- | examples/nrf/src/bin/uart_idle.rs | 4 |
20 files changed, 729 insertions, 880 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 8ec0fb2ce..7c9a2344e 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -14,28 +14,15 @@ 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::ppi::{AnyChannel, Channel, Event, Ppi, Task}; | 17 | use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; |
| 18 | use crate::pac; | ||
| 18 | use crate::timer::Instance as TimerInstance; | 19 | use crate::timer::Instance as TimerInstance; |
| 19 | use crate::timer::{Frequency, Timer}; | 20 | use crate::timer::{Frequency, Timer}; |
| 20 | use crate::uarte::{Config, Instance as UarteInstance}; | 21 | use crate::uarte::{Config, Instance as UarteInstance}; |
| 21 | use crate::{pac, ppi}; | ||
| 22 | 22 | ||
| 23 | // Re-export SVD variants to allow user to directly set values | 23 | // Re-export SVD variants to allow user to directly set values |
| 24 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 24 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; |
| 25 | 25 | ||
| 26 | #[non_exhaustive] | ||
| 27 | #[derive(Clone, Debug)] | ||
| 28 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 29 | pub enum Error { | ||
| 30 | PpiError(ppi::Error), | ||
| 31 | } | ||
| 32 | |||
| 33 | impl From<ppi::Error> for Error { | ||
| 34 | fn from(e: ppi::Error) -> Self { | ||
| 35 | Self::PpiError(e) | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | #[derive(Copy, Clone, Debug, PartialEq)] | 26 | #[derive(Copy, Clone, Debug, PartialEq)] |
| 40 | enum RxState { | 27 | enum RxState { |
| 41 | Idle, | 28 | Idle, |
| @@ -58,8 +45,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { | |||
| 58 | struct StateInner<'d, U: UarteInstance, T: TimerInstance> { | 45 | struct StateInner<'d, U: UarteInstance, T: TimerInstance> { |
| 59 | phantom: PhantomData<&'d mut U>, | 46 | phantom: PhantomData<&'d mut U>, |
| 60 | timer: Timer<'d, T>, | 47 | timer: Timer<'d, T>, |
| 61 | _ppi_ch1: Ppi<'d, AnyChannel>, | 48 | _ppi_ch1: Ppi<'d, AnyChannel, 1, 2>, |
| 62 | _ppi_ch2: Ppi<'d, AnyChannel>, | 49 | _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>, |
| 63 | 50 | ||
| 64 | rx: RingBuffer<'d>, | 51 | rx: RingBuffer<'d>, |
| 65 | rx_state: RxState, | 52 | rx_state: RxState, |
| @@ -79,15 +66,12 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> { | |||
| 79 | 66 | ||
| 80 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | 67 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { |
| 81 | /// unsafe: may not leak self or futures | 68 | /// unsafe: may not leak self or futures |
| 82 | /// | ||
| 83 | /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned | ||
| 84 | /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned | ||
| 85 | pub unsafe fn new( | 69 | pub unsafe fn new( |
| 86 | state: &'d mut State<'d, U, T>, | 70 | state: &'d mut State<'d, U, T>, |
| 87 | _uarte: impl Unborrow<Target = U> + 'd, | 71 | _uarte: impl Unborrow<Target = U> + 'd, |
| 88 | timer: impl Unborrow<Target = T> + 'd, | 72 | timer: impl Unborrow<Target = T> + 'd, |
| 89 | ppi_ch1: impl Unborrow<Target = impl Channel> + 'd, | 73 | ppi_ch1: impl Unborrow<Target = impl OneToTwoChannel + 'd> + 'd, |
| 90 | ppi_ch2: impl Unborrow<Target = impl Channel> + 'd, | 74 | ppi_ch2: impl Unborrow<Target = impl OneToOneChannel + 'd> + 'd, |
| 91 | irq: impl Unborrow<Target = U::Interrupt> + 'd, | 75 | irq: impl Unborrow<Target = U::Interrupt> + 'd, |
| 92 | rxd: impl Unborrow<Target = impl GpioPin> + 'd, | 76 | rxd: impl Unborrow<Target = impl GpioPin> + 'd, |
| 93 | txd: impl Unborrow<Target = impl GpioPin> + 'd, | 77 | txd: impl Unborrow<Target = impl GpioPin> + 'd, |
| @@ -96,7 +80,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 96 | config: Config, | 80 | config: Config, |
| 97 | rx_buffer: &'d mut [u8], | 81 | rx_buffer: &'d mut [u8], |
| 98 | tx_buffer: &'d mut [u8], | 82 | tx_buffer: &'d mut [u8], |
| 99 | ) -> Result<Self, Error> { | 83 | ) -> Self { |
| 100 | unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); | 84 | unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); |
| 101 | 85 | ||
| 102 | let r = U::regs(); | 86 | let r = U::regs(); |
| @@ -160,18 +144,24 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 160 | timer.cc(0).short_compare_clear(); | 144 | timer.cc(0).short_compare_clear(); |
| 161 | timer.cc(0).short_compare_stop(); | 145 | timer.cc(0).short_compare_stop(); |
| 162 | 146 | ||
| 163 | let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); | 147 | let mut ppi_ch1 = Ppi::new_one_to_two( |
| 164 | ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; | 148 | ppi_ch1, |
| 165 | ppi_ch1.subscribe(timer.task_clear())?; | 149 | Event::from_reg(&r.events_rxdrdy), |
| 166 | ppi_ch1.subscribe(timer.task_start())?; | 150 | timer.task_clear(), |
| 151 | timer.task_start(), | ||
| 152 | ) | ||
| 153 | .degrade(); | ||
| 167 | ppi_ch1.enable(); | 154 | ppi_ch1.enable(); |
| 168 | 155 | ||
| 169 | let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); | 156 | let mut ppi_ch2 = Ppi::new_one_to_one( |
| 170 | ppi_ch2.publish(timer.cc(0).event_compare())?; | 157 | ppi_ch2, |
| 171 | ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; | 158 | timer.cc(0).event_compare(), |
| 159 | Task::from_reg(&r.tasks_stoprx), | ||
| 160 | ) | ||
| 161 | .degrade(); | ||
| 172 | ppi_ch2.enable(); | 162 | ppi_ch2.enable(); |
| 173 | 163 | ||
| 174 | Ok(Self { | 164 | Self { |
| 175 | inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner { | 165 | inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner { |
| 176 | phantom: PhantomData, | 166 | phantom: PhantomData, |
| 177 | timer, | 167 | timer, |
| @@ -186,7 +176,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 186 | tx_state: TxState::Idle, | 176 | tx_state: TxState::Idle, |
| 187 | tx_waker: WakerRegistration::new(), | 177 | tx_waker: WakerRegistration::new(), |
| 188 | }), | 178 | }), |
| 189 | }) | 179 | } |
| 190 | } | 180 | } |
| 191 | 181 | ||
| 192 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | 182 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { |
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index 03fc5f307..326f4a8be 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs | |||
| @@ -167,28 +167,28 @@ impl_pin!(P0_29, 0, 29); | |||
| 167 | impl_pin!(P0_30, 0, 30); | 167 | impl_pin!(P0_30, 0, 30); |
| 168 | impl_pin!(P0_31, 0, 31); | 168 | impl_pin!(P0_31, 0, 31); |
| 169 | 169 | ||
| 170 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 170 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 171 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 171 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 172 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 172 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 173 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 173 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 174 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 174 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 175 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 175 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 176 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 176 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 177 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 177 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 178 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 178 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 179 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 179 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 180 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 180 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 181 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 181 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 182 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 182 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 183 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 183 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 184 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 184 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 185 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 185 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 186 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 186 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 187 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 187 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 188 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 188 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 189 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 189 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 190 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 190 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 191 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 191 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 192 | 192 | ||
| 193 | impl_saadc_input!(P0_04, ANALOGINPUT2); | 193 | impl_saadc_input!(P0_04, ANALOGINPUT2); |
| 194 | impl_saadc_input!(P0_05, ANALOGINPUT3); | 194 | impl_saadc_input!(P0_05, ANALOGINPUT3); |
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index e317e4c54..4c16d51a7 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -172,38 +172,38 @@ impl_pin!(P0_29, 0, 29); | |||
| 172 | impl_pin!(P0_30, 0, 30); | 172 | impl_pin!(P0_30, 0, 30); |
| 173 | impl_pin!(P0_31, 0, 31); | 173 | impl_pin!(P0_31, 0, 31); |
| 174 | 174 | ||
| 175 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 175 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 176 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 176 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 177 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 177 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 178 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 178 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 179 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 179 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 180 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 180 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 181 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 181 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 182 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 182 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 183 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 183 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 184 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 184 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 185 | impl_ppi_channel!(PPI_CH10, 10, 2, 1); | 185 | impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); |
| 186 | impl_ppi_channel!(PPI_CH11, 11, 2, 1); | 186 | impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); |
| 187 | impl_ppi_channel!(PPI_CH12, 12, 2, 1); | 187 | impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); |
| 188 | impl_ppi_channel!(PPI_CH13, 13, 2, 1); | 188 | impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); |
| 189 | impl_ppi_channel!(PPI_CH14, 14, 2, 1); | 189 | impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); |
| 190 | impl_ppi_channel!(PPI_CH15, 15, 2, 1); | 190 | impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); |
| 191 | impl_ppi_channel!(PPI_CH16, 16, 2, 1); | 191 | impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); |
| 192 | impl_ppi_channel!(PPI_CH17, 17, 2, 1); | 192 | impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); |
| 193 | impl_ppi_channel!(PPI_CH18, 18, 2, 1); | 193 | impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); |
| 194 | impl_ppi_channel!(PPI_CH19, 19, 2, 1); | 194 | impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); |
| 195 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 195 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 196 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 196 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 197 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 197 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 198 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 198 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 199 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 199 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 200 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 200 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 201 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 201 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 202 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 202 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 203 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 203 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 204 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 204 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 205 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 205 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 206 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 206 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 207 | 207 | ||
| 208 | impl_saadc_input!(P0_02, ANALOGINPUT0); | 208 | impl_saadc_input!(P0_02, ANALOGINPUT0); |
| 209 | impl_saadc_input!(P0_03, ANALOGINPUT1); | 209 | impl_saadc_input!(P0_03, ANALOGINPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 748f5f4ba..0c54d9b9e 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -173,38 +173,38 @@ impl_pin!(P0_29, 0, 29); | |||
| 173 | impl_pin!(P0_30, 0, 30); | 173 | impl_pin!(P0_30, 0, 30); |
| 174 | impl_pin!(P0_31, 0, 31); | 174 | impl_pin!(P0_31, 0, 31); |
| 175 | 175 | ||
| 176 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 176 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 177 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 177 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 178 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 178 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 179 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 179 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 180 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 180 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 181 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 181 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 182 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 182 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 183 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 183 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 184 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 184 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 185 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 185 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 186 | impl_ppi_channel!(PPI_CH10, 10, 2, 1); | 186 | impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); |
| 187 | impl_ppi_channel!(PPI_CH11, 11, 2, 1); | 187 | impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); |
| 188 | impl_ppi_channel!(PPI_CH12, 12, 2, 1); | 188 | impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); |
| 189 | impl_ppi_channel!(PPI_CH13, 13, 2, 1); | 189 | impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); |
| 190 | impl_ppi_channel!(PPI_CH14, 14, 2, 1); | 190 | impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); |
| 191 | impl_ppi_channel!(PPI_CH15, 15, 2, 1); | 191 | impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); |
| 192 | impl_ppi_channel!(PPI_CH16, 16, 2, 1); | 192 | impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); |
| 193 | impl_ppi_channel!(PPI_CH17, 17, 2, 1); | 193 | impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); |
| 194 | impl_ppi_channel!(PPI_CH18, 18, 2, 1); | 194 | impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); |
| 195 | impl_ppi_channel!(PPI_CH19, 19, 2, 1); | 195 | impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); |
| 196 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 196 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 197 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 197 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 198 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 198 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 199 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 199 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 200 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 200 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 201 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 201 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 202 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 202 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 203 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 203 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 204 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 204 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 205 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 205 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 206 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 206 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 207 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 207 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 208 | 208 | ||
| 209 | impl_saadc_input!(P0_02, ANALOGINPUT0); | 209 | impl_saadc_input!(P0_02, ANALOGINPUT0); |
| 210 | impl_saadc_input!(P0_03, ANALOGINPUT1); | 210 | impl_saadc_input!(P0_03, ANALOGINPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 02d2c6103..d52f2f98a 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs | |||
| @@ -168,38 +168,38 @@ impl_pin!(P0_29, 0, 29); | |||
| 168 | impl_pin!(P0_30, 0, 30); | 168 | impl_pin!(P0_30, 0, 30); |
| 169 | impl_pin!(P0_31, 0, 31); | 169 | impl_pin!(P0_31, 0, 31); |
| 170 | 170 | ||
| 171 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 171 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 172 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 172 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 173 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 173 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 174 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 174 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 175 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 175 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 176 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 176 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 177 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 177 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 178 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 178 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 179 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 179 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 180 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 180 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 181 | impl_ppi_channel!(PPI_CH10, 10, 2, 1); | 181 | impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); |
| 182 | impl_ppi_channel!(PPI_CH11, 11, 2, 1); | 182 | impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); |
| 183 | impl_ppi_channel!(PPI_CH12, 12, 2, 1); | 183 | impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); |
| 184 | impl_ppi_channel!(PPI_CH13, 13, 2, 1); | 184 | impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); |
| 185 | impl_ppi_channel!(PPI_CH14, 14, 2, 1); | 185 | impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); |
| 186 | impl_ppi_channel!(PPI_CH15, 15, 2, 1); | 186 | impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); |
| 187 | impl_ppi_channel!(PPI_CH16, 16, 2, 1); | 187 | impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); |
| 188 | impl_ppi_channel!(PPI_CH17, 17, 2, 1); | 188 | impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); |
| 189 | impl_ppi_channel!(PPI_CH18, 18, 2, 1); | 189 | impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); |
| 190 | impl_ppi_channel!(PPI_CH19, 19, 2, 1); | 190 | impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); |
| 191 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 191 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 192 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 192 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 193 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 193 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 194 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 194 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 195 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 195 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 196 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 196 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 197 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 197 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 198 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 198 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 199 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 199 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 200 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 200 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 201 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 201 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 202 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 202 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 203 | 203 | ||
| 204 | pub mod irqs { | 204 | pub mod irqs { |
| 205 | use crate::pac::Interrupt as InterruptEnum; | 205 | use crate::pac::Interrupt as InterruptEnum; |
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 611dbbd50..d97a65350 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -190,38 +190,38 @@ impl_pin!(P0_29, 0, 29); | |||
| 190 | impl_pin!(P0_30, 0, 30); | 190 | impl_pin!(P0_30, 0, 30); |
| 191 | impl_pin!(P0_31, 0, 31); | 191 | impl_pin!(P0_31, 0, 31); |
| 192 | 192 | ||
| 193 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 193 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 194 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 194 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 195 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 195 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 196 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 196 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 197 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 197 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 198 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 198 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 199 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 199 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 200 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 200 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 201 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 201 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 202 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 202 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 203 | impl_ppi_channel!(PPI_CH10, 10, 2, 1); | 203 | impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); |
| 204 | impl_ppi_channel!(PPI_CH11, 11, 2, 1); | 204 | impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); |
| 205 | impl_ppi_channel!(PPI_CH12, 12, 2, 1); | 205 | impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); |
| 206 | impl_ppi_channel!(PPI_CH13, 13, 2, 1); | 206 | impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); |
| 207 | impl_ppi_channel!(PPI_CH14, 14, 2, 1); | 207 | impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); |
| 208 | impl_ppi_channel!(PPI_CH15, 15, 2, 1); | 208 | impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); |
| 209 | impl_ppi_channel!(PPI_CH16, 16, 2, 1); | 209 | impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); |
| 210 | impl_ppi_channel!(PPI_CH17, 17, 2, 1); | 210 | impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); |
| 211 | impl_ppi_channel!(PPI_CH18, 18, 2, 1); | 211 | impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); |
| 212 | impl_ppi_channel!(PPI_CH19, 19, 2, 1); | 212 | impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); |
| 213 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 213 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 214 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 214 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 215 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 215 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 216 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 216 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 217 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 217 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 218 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 218 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 219 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 219 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 220 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 220 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 221 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 221 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 222 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 222 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 223 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 223 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 224 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 224 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 225 | 225 | ||
| 226 | impl_saadc_input!(P0_02, ANALOGINPUT0); | 226 | impl_saadc_input!(P0_02, ANALOGINPUT0); |
| 227 | impl_saadc_input!(P0_03, ANALOGINPUT1); | 227 | impl_saadc_input!(P0_03, ANALOGINPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 6f70f2a47..9bf370c4b 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -226,38 +226,38 @@ impl_pin!(P1_13, 1, 13); | |||
| 226 | impl_pin!(P1_14, 1, 14); | 226 | impl_pin!(P1_14, 1, 14); |
| 227 | impl_pin!(P1_15, 1, 15); | 227 | impl_pin!(P1_15, 1, 15); |
| 228 | 228 | ||
| 229 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 229 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 230 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 230 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 231 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 231 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 232 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 232 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 233 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 233 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 234 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 234 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 235 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 235 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 236 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 236 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 237 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 237 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 238 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 238 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 239 | impl_ppi_channel!(PPI_CH10, 10, 2, 1); | 239 | impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); |
| 240 | impl_ppi_channel!(PPI_CH11, 11, 2, 1); | 240 | impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); |
| 241 | impl_ppi_channel!(PPI_CH12, 12, 2, 1); | 241 | impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); |
| 242 | impl_ppi_channel!(PPI_CH13, 13, 2, 1); | 242 | impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); |
| 243 | impl_ppi_channel!(PPI_CH14, 14, 2, 1); | 243 | impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); |
| 244 | impl_ppi_channel!(PPI_CH15, 15, 2, 1); | 244 | impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); |
| 245 | impl_ppi_channel!(PPI_CH16, 16, 2, 1); | 245 | impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); |
| 246 | impl_ppi_channel!(PPI_CH17, 17, 2, 1); | 246 | impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); |
| 247 | impl_ppi_channel!(PPI_CH18, 18, 2, 1); | 247 | impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); |
| 248 | impl_ppi_channel!(PPI_CH19, 19, 2, 1); | 248 | impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); |
| 249 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 249 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 250 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 250 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 251 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 251 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 252 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 252 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 253 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 253 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 254 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 254 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 255 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 255 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 256 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 256 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 257 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 257 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 258 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 258 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 259 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 259 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 260 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 260 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 261 | 261 | ||
| 262 | impl_saadc_input!(P0_02, ANALOGINPUT0); | 262 | impl_saadc_input!(P0_02, ANALOGINPUT0); |
| 263 | impl_saadc_input!(P0_03, ANALOGINPUT1); | 263 | impl_saadc_input!(P0_03, ANALOGINPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 1b9824151..266328d58 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -231,38 +231,38 @@ impl_pin!(P1_13, 1, 13); | |||
| 231 | impl_pin!(P1_14, 1, 14); | 231 | impl_pin!(P1_14, 1, 14); |
| 232 | impl_pin!(P1_15, 1, 15); | 232 | impl_pin!(P1_15, 1, 15); |
| 233 | 233 | ||
| 234 | impl_ppi_channel!(PPI_CH0, 0, 2, 1); | 234 | impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); |
| 235 | impl_ppi_channel!(PPI_CH1, 1, 2, 1); | 235 | impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); |
| 236 | impl_ppi_channel!(PPI_CH2, 2, 2, 1); | 236 | impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); |
| 237 | impl_ppi_channel!(PPI_CH3, 3, 2, 1); | 237 | impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); |
| 238 | impl_ppi_channel!(PPI_CH4, 4, 2, 1); | 238 | impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); |
| 239 | impl_ppi_channel!(PPI_CH5, 5, 2, 1); | 239 | impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); |
| 240 | impl_ppi_channel!(PPI_CH6, 6, 2, 1); | 240 | impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); |
| 241 | impl_ppi_channel!(PPI_CH7, 7, 2, 1); | 241 | impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); |
| 242 | impl_ppi_channel!(PPI_CH8, 8, 2, 1); | 242 | impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); |
| 243 | impl_ppi_channel!(PPI_CH9, 9, 2, 1); | 243 | impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); |
| 244 | impl_ppi_channel!(PPI_CH10, 10, 2, 1); | 244 | impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); |
| 245 | impl_ppi_channel!(PPI_CH11, 11, 2, 1); | 245 | impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); |
| 246 | impl_ppi_channel!(PPI_CH12, 12, 2, 1); | 246 | impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); |
| 247 | impl_ppi_channel!(PPI_CH13, 13, 2, 1); | 247 | impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); |
| 248 | impl_ppi_channel!(PPI_CH14, 14, 2, 1); | 248 | impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); |
| 249 | impl_ppi_channel!(PPI_CH15, 15, 2, 1); | 249 | impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); |
| 250 | impl_ppi_channel!(PPI_CH16, 16, 2, 1); | 250 | impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); |
| 251 | impl_ppi_channel!(PPI_CH17, 17, 2, 1); | 251 | impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); |
| 252 | impl_ppi_channel!(PPI_CH18, 18, 2, 1); | 252 | impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); |
| 253 | impl_ppi_channel!(PPI_CH19, 19, 2, 1); | 253 | impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); |
| 254 | impl_ppi_channel!(PPI_CH20, 20, 1, 0); | 254 | impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); |
| 255 | impl_ppi_channel!(PPI_CH21, 21, 1, 0); | 255 | impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); |
| 256 | impl_ppi_channel!(PPI_CH22, 22, 1, 0); | 256 | impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); |
| 257 | impl_ppi_channel!(PPI_CH23, 23, 1, 0); | 257 | impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); |
| 258 | impl_ppi_channel!(PPI_CH24, 24, 1, 0); | 258 | impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); |
| 259 | impl_ppi_channel!(PPI_CH25, 25, 1, 0); | 259 | impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); |
| 260 | impl_ppi_channel!(PPI_CH26, 26, 1, 0); | 260 | impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); |
| 261 | impl_ppi_channel!(PPI_CH27, 27, 1, 0); | 261 | impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); |
| 262 | impl_ppi_channel!(PPI_CH28, 28, 1, 0); | 262 | impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); |
| 263 | impl_ppi_channel!(PPI_CH29, 29, 1, 0); | 263 | impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); |
| 264 | impl_ppi_channel!(PPI_CH30, 30, 1, 0); | 264 | impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); |
| 265 | impl_ppi_channel!(PPI_CH31, 31, 1, 0); | 265 | impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); |
| 266 | 266 | ||
| 267 | impl_saadc_input!(P0_02, ANALOGINPUT0); | 267 | impl_saadc_input!(P0_02, ANALOGINPUT0); |
| 268 | impl_saadc_input!(P0_03, ANALOGINPUT1); | 268 | impl_saadc_input!(P0_03, ANALOGINPUT1); |
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 42053d081..7357e9e22 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs | |||
| @@ -184,22 +184,22 @@ impl_pin!(P0_29, 0, 29); | |||
| 184 | impl_pin!(P0_30, 0, 30); | 184 | impl_pin!(P0_30, 0, 30); |
| 185 | impl_pin!(P0_31, 0, 31); | 185 | impl_pin!(P0_31, 0, 31); |
| 186 | 186 | ||
| 187 | impl_ppi_channel!(PPI_CH0, 0); | 187 | impl_ppi_channel!(PPI_CH0, 0, true, many, many); |
| 188 | impl_ppi_channel!(PPI_CH1, 1); | 188 | impl_ppi_channel!(PPI_CH1, 1, true, many, many); |
| 189 | impl_ppi_channel!(PPI_CH2, 2); | 189 | impl_ppi_channel!(PPI_CH2, 2, true, many, many); |
| 190 | impl_ppi_channel!(PPI_CH3, 3); | 190 | impl_ppi_channel!(PPI_CH3, 3, true, many, many); |
| 191 | impl_ppi_channel!(PPI_CH4, 4); | 191 | impl_ppi_channel!(PPI_CH4, 4, true, many, many); |
| 192 | impl_ppi_channel!(PPI_CH5, 5); | 192 | impl_ppi_channel!(PPI_CH5, 5, true, many, many); |
| 193 | impl_ppi_channel!(PPI_CH6, 6); | 193 | impl_ppi_channel!(PPI_CH6, 6, true, many, many); |
| 194 | impl_ppi_channel!(PPI_CH7, 7); | 194 | impl_ppi_channel!(PPI_CH7, 7, true, many, many); |
| 195 | impl_ppi_channel!(PPI_CH8, 8); | 195 | impl_ppi_channel!(PPI_CH8, 8, true, many, many); |
| 196 | impl_ppi_channel!(PPI_CH9, 9); | 196 | impl_ppi_channel!(PPI_CH9, 9, true, many, many); |
| 197 | impl_ppi_channel!(PPI_CH10, 10); | 197 | impl_ppi_channel!(PPI_CH10, 10, true, many, many); |
| 198 | impl_ppi_channel!(PPI_CH11, 11); | 198 | impl_ppi_channel!(PPI_CH11, 11, true, many, many); |
| 199 | impl_ppi_channel!(PPI_CH12, 12); | 199 | impl_ppi_channel!(PPI_CH12, 12, true, many, many); |
| 200 | impl_ppi_channel!(PPI_CH13, 13); | 200 | impl_ppi_channel!(PPI_CH13, 13, true, many, many); |
| 201 | impl_ppi_channel!(PPI_CH14, 14); | 201 | impl_ppi_channel!(PPI_CH14, 14, true, many, many); |
| 202 | impl_ppi_channel!(PPI_CH15, 15); | 202 | impl_ppi_channel!(PPI_CH15, 15, true, many, many); |
| 203 | 203 | ||
| 204 | impl_saadc_input!(P0_13, ANALOGINPUT0); | 204 | impl_saadc_input!(P0_13, ANALOGINPUT0); |
| 205 | impl_saadc_input!(P0_14, ANALOGINPUT1); | 205 | impl_saadc_input!(P0_14, ANALOGINPUT1); |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 943ff530b..6703bfc60 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}; | ||
| 14 | use crate::pac; | 15 | 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; |
| @@ -190,13 +190,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { | |||
| 190 | /// Returns the IN event, for use with PPI. | 190 | /// Returns the IN event, for use with PPI. |
| 191 | pub fn event_in(&self) -> Event { | 191 | pub fn event_in(&self) -> Event { |
| 192 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 192 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 193 | 193 | Event::from_reg(&g.events_in[self.ch.number()]) | |
| 194 | #[cfg(feature = "_ppi")] | ||
| 195 | let reg = &g.events_in[self.ch.number()]; | ||
| 196 | #[cfg(feature = "_dppi")] | ||
| 197 | let reg = &g.publish_in[self.ch.number()]; | ||
| 198 | |||
| 199 | Event::from_reg(reg) | ||
| 200 | } | 194 | } |
| 201 | } | 195 | } |
| 202 | 196 | ||
| @@ -277,33 +271,21 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { | |||
| 277 | /// Returns the OUT task, for use with PPI. | 271 | /// Returns the OUT task, for use with PPI. |
| 278 | pub fn task_out(&self) -> Task { | 272 | pub fn task_out(&self) -> Task { |
| 279 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 273 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 280 | #[cfg(feature = "_ppi")] | 274 | Task::from_reg(&g.tasks_out[self.ch.number()]) |
| 281 | let reg = &g.tasks_out[self.ch.number()]; | ||
| 282 | #[cfg(feature = "_dppi")] | ||
| 283 | let reg = &g.subscribe_out[self.ch.number()]; | ||
| 284 | Task::from_reg(reg) | ||
| 285 | } | 275 | } |
| 286 | 276 | ||
| 287 | /// Returns the CLR task, for use with PPI. | 277 | /// Returns the CLR task, for use with PPI. |
| 288 | #[cfg(not(feature = "nrf51"))] | 278 | #[cfg(not(feature = "nrf51"))] |
| 289 | pub fn task_clr(&self) -> Task { | 279 | pub fn task_clr(&self) -> Task { |
| 290 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 280 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 291 | #[cfg(feature = "_ppi")] | 281 | Task::from_reg(&g.tasks_clr[self.ch.number()]) |
| 292 | let reg = &g.tasks_clr[self.ch.number()]; | ||
| 293 | #[cfg(feature = "_dppi")] | ||
| 294 | let reg = &g.subscribe_clr[self.ch.number()]; | ||
| 295 | Task::from_reg(reg) | ||
| 296 | } | 282 | } |
| 297 | 283 | ||
| 298 | /// Returns the SET task, for use with PPI. | 284 | /// Returns the SET task, for use with PPI. |
| 299 | #[cfg(not(feature = "nrf51"))] | 285 | #[cfg(not(feature = "nrf51"))] |
| 300 | pub fn task_set(&self) -> Task { | 286 | pub fn task_set(&self) -> Task { |
| 301 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 287 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 302 | #[cfg(feature = "_ppi")] | 288 | Task::from_reg(&g.tasks_set[self.ch.number()]) |
| 303 | let reg = &g.tasks_set[self.ch.number()]; | ||
| 304 | #[cfg(feature = "_dppi")] | ||
| 305 | let reg = &g.subscribe_set[self.ch.number()]; | ||
| 306 | Task::from_reg(reg) | ||
| 307 | } | 289 | } |
| 308 | } | 290 | } |
| 309 | 291 | ||
diff --git a/embassy-nrf/src/interconnect/dppi.rs b/embassy-nrf/src/interconnect/dppi.rs new file mode 100644 index 000000000..60f19fca0 --- /dev/null +++ b/embassy-nrf/src/interconnect/dppi.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 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/mod.rs b/embassy-nrf/src/interconnect/mod.rs new file mode 100644 index 000000000..23cc45270 --- /dev/null +++ b/embassy-nrf/src/interconnect/mod.rs | |||
| @@ -0,0 +1,318 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | //! HAL interface for the PPI and DPPI peripheral. | ||
| 4 | //! | ||
| 5 | //! The (Distributed) Programmable Peripheral Interconnect interface allows for an autonomous interoperability | ||
| 6 | //! between peripherals through their events and tasks. There are fixed PPI channels and fully | ||
| 7 | //! configurable ones. Fixed channels can only connect specific events to specific tasks. For fully | ||
| 8 | //! configurable channels, it is possible to choose, via software, the event and the task that it | ||
| 9 | //! will triggered by the event. | ||
| 10 | //! | ||
| 11 | //! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task | ||
| 12 | //! to be triggered by the same event, even fixed PPI channels have a configurable fork task. | ||
| 13 | //! | ||
| 14 | //! The DPPI for nRF53 and nRF91 devices works in a different way. Every channel can support infinitely | ||
| 15 | //! many tasks and events, but any single task or event can only be coupled with one channel. | ||
| 16 | //! | ||
| 17 | |||
| 18 | use crate::{pac, peripherals}; | ||
| 19 | use core::marker::PhantomData; | ||
| 20 | use core::ptr::NonNull; | ||
| 21 | use embassy::util::Unborrow; | ||
| 22 | use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; | ||
| 23 | |||
| 24 | #[cfg(feature = "_dppi")] | ||
| 25 | mod dppi; | ||
| 26 | #[cfg(feature = "_ppi")] | ||
| 27 | mod ppi; | ||
| 28 | |||
| 29 | pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { | ||
| 30 | ch: C, | ||
| 31 | events: [Event; EVENT_COUNT], | ||
| 32 | tasks: [Task; TASK_COUNT], | ||
| 33 | phantom: PhantomData<&'d mut C>, | ||
| 34 | } | ||
| 35 | |||
| 36 | impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> | ||
| 37 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 38 | { | ||
| 39 | pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { | ||
| 40 | Ppi { | ||
| 41 | ch: AnyChannel { | ||
| 42 | number: self.ch.number() as u8, | ||
| 43 | #[cfg(feature = "_ppi")] | ||
| 44 | has_configurable_task: self.ch.is_task_configurable(), | ||
| 45 | }, | ||
| 46 | events: self.events, | ||
| 47 | tasks: self.tasks, | ||
| 48 | phantom: PhantomData, | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Enables the channel. | ||
| 53 | pub fn enable(&mut self) { | ||
| 54 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 55 | r.chenset | ||
| 56 | .write(|w| unsafe { w.bits(1 << self.ch.number()) }); | ||
| 57 | } | ||
| 58 | |||
| 59 | /// Disables the channel. | ||
| 60 | pub fn disable(&mut self) { | ||
| 61 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 62 | r.chenclr | ||
| 63 | .write(|w| unsafe { w.bits(1 << self.ch.number()) }); | ||
| 64 | } | ||
| 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 | } | ||
| 86 | |||
| 87 | impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop | ||
| 88 | for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 89 | { | ||
| 90 | fn drop(&mut self) { | ||
| 91 | self.disable(); | ||
| 92 | self.disable_all(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | impl<'d, C: StaticToOneChannel> Ppi<'d, C, 0, 1> { | ||
| 97 | pub fn new_static_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self { | ||
| 98 | unborrow!(ch); | ||
| 99 | |||
| 100 | let s = Self { | ||
| 101 | ch, | ||
| 102 | events: [], | ||
| 103 | tasks: [task], | ||
| 104 | phantom: PhantomData, | ||
| 105 | }; | ||
| 106 | |||
| 107 | s.enable_all(); | ||
| 108 | s | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | 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 { | ||
| 114 | unborrow!(ch); | ||
| 115 | |||
| 116 | let s = Self { | ||
| 117 | ch, | ||
| 118 | events: [event], | ||
| 119 | tasks: [task], | ||
| 120 | phantom: PhantomData, | ||
| 121 | }; | ||
| 122 | |||
| 123 | s.enable_all(); | ||
| 124 | s | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> { | ||
| 129 | pub fn new_one_to_two( | ||
| 130 | ch: impl Unborrow<Target = C> + 'd, | ||
| 131 | event: Event, | ||
| 132 | task1: Task, | ||
| 133 | task2: Task, | ||
| 134 | ) -> Self { | ||
| 135 | unborrow!(ch); | ||
| 136 | |||
| 137 | let s = Self { | ||
| 138 | ch, | ||
| 139 | events: [event], | ||
| 140 | tasks: [task1, task2], | ||
| 141 | phantom: PhantomData, | ||
| 142 | }; | ||
| 143 | |||
| 144 | s.enable_all(); | ||
| 145 | s | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize> | ||
| 150 | Ppi<'d, C, EVENT_COUNT, TASK_COUNT> | ||
| 151 | { | ||
| 152 | pub fn new_many_to_many( | ||
| 153 | ch: impl Unborrow<Target = C> + 'd, | ||
| 154 | events: [Event; EVENT_COUNT], | ||
| 155 | tasks: [Task; TASK_COUNT], | ||
| 156 | ) -> Self { | ||
| 157 | unborrow!(ch); | ||
| 158 | |||
| 159 | let s = Self { | ||
| 160 | ch, | ||
| 161 | events, | ||
| 162 | tasks, | ||
| 163 | phantom: PhantomData, | ||
| 164 | }; | ||
| 165 | |||
| 166 | s.enable_all(); | ||
| 167 | s | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | /// 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 | ||
| 173 | /// a published event. | ||
| 174 | /// | ||
| 175 | /// The pointer is to a task register | ||
| 176 | #[derive(PartialEq, Eq, Clone, Copy)] | ||
| 177 | pub struct Task(pub NonNull<u32>); | ||
| 178 | impl Task { | ||
| 179 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | ||
| 180 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | /// # Safety | ||
| 185 | /// | ||
| 186 | /// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core. | ||
| 187 | unsafe impl Send for Task {} | ||
| 188 | |||
| 189 | /// Represents an event that a peripheral can publish. | ||
| 190 | /// An event can be set to publish on a PPI channel when the event happens. | ||
| 191 | /// | ||
| 192 | /// The pointer is to an event register | ||
| 193 | #[derive(PartialEq, Eq, Clone, Copy)] | ||
| 194 | pub struct Event(pub NonNull<u32>); | ||
| 195 | impl Event { | ||
| 196 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | ||
| 197 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | /// # Safety | ||
| 202 | /// | ||
| 203 | /// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core. | ||
| 204 | unsafe impl Send for Event {} | ||
| 205 | |||
| 206 | // ====================== | ||
| 207 | // traits | ||
| 208 | |||
| 209 | pub(crate) mod sealed { | ||
| 210 | pub trait Channel {} | ||
| 211 | pub trait Group {} | ||
| 212 | } | ||
| 213 | |||
| 214 | pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized { | ||
| 215 | /// Returns the number of the channel | ||
| 216 | fn number(&self) -> usize; | ||
| 217 | #[cfg(feature = "_ppi")] | ||
| 218 | fn is_task_configurable(&self) -> bool; | ||
| 219 | } | ||
| 220 | |||
| 221 | pub trait StaticToOneChannel: Channel {} | ||
| 222 | pub trait OneToOneChannel: StaticToOneChannel {} | ||
| 223 | pub trait OneToTwoChannel: OneToOneChannel {} | ||
| 224 | pub trait ManyToManyChannel: OneToTwoChannel {} | ||
| 225 | |||
| 226 | pub trait Group: sealed::Group + Sized { | ||
| 227 | fn number(&self) -> usize; | ||
| 228 | } | ||
| 229 | |||
| 230 | // ====================== | ||
| 231 | // channels | ||
| 232 | |||
| 233 | pub struct AnyChannel { | ||
| 234 | number: u8, | ||
| 235 | #[cfg(feature = "_ppi")] | ||
| 236 | has_configurable_task: bool, | ||
| 237 | } | ||
| 238 | unsafe_impl_unborrow!(AnyChannel); | ||
| 239 | impl sealed::Channel for AnyChannel {} | ||
| 240 | impl Channel for AnyChannel { | ||
| 241 | fn number(&self) -> usize { | ||
| 242 | self.number as usize | ||
| 243 | } | ||
| 244 | |||
| 245 | #[cfg(feature = "_ppi")] | ||
| 246 | fn is_task_configurable(&self) -> bool { | ||
| 247 | self.has_configurable_task | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | macro_rules! impl_ppi_channel { | ||
| 252 | ($type:ident, $number:expr, $has_configurable_task:expr) => { | ||
| 253 | impl crate::interconnect::sealed::Channel for peripherals::$type {} | ||
| 254 | impl crate::interconnect::Channel for peripherals::$type { | ||
| 255 | fn number(&self) -> usize { | ||
| 256 | $number | ||
| 257 | } | ||
| 258 | |||
| 259 | #[cfg(feature = "_ppi")] | ||
| 260 | fn is_task_configurable(&self) -> bool { | ||
| 261 | $has_configurable_task | ||
| 262 | } | ||
| 263 | } | ||
| 264 | }; | ||
| 265 | ($type:ident, $number:expr, $has_configurable_task:expr, 0, 0) => { | ||
| 266 | impl_ppi_channel!($type, $number, $has_configurable_task); | ||
| 267 | }; | ||
| 268 | ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { | ||
| 269 | impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); | ||
| 270 | impl crate::interconnect::StaticToOneChannel for peripherals::$type {} | ||
| 271 | }; | ||
| 272 | ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { | ||
| 273 | impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); | ||
| 274 | impl crate::interconnect::OneToOneChannel for peripherals::$type {} | ||
| 275 | }; | ||
| 276 | ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { | ||
| 277 | impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); | ||
| 278 | impl crate::interconnect::OneToTwoChannel for peripherals::$type {} | ||
| 279 | }; | ||
| 280 | ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { | ||
| 281 | impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); | ||
| 282 | impl crate::interconnect::ManyToManyChannel for peripherals::$type {} | ||
| 283 | }; | ||
| 284 | } | ||
| 285 | |||
| 286 | // ====================== | ||
| 287 | // groups | ||
| 288 | |||
| 289 | pub struct AnyGroup { | ||
| 290 | number: u8, | ||
| 291 | } | ||
| 292 | unsafe_impl_unborrow!(AnyGroup); | ||
| 293 | impl sealed::Group for AnyGroup {} | ||
| 294 | impl Group for AnyGroup { | ||
| 295 | fn number(&self) -> usize { | ||
| 296 | self.number as usize | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | macro_rules! impl_group { | ||
| 301 | ($type:ident, $number:expr) => { | ||
| 302 | impl sealed::Group for peripherals::$type {} | ||
| 303 | impl Group for peripherals::$type { | ||
| 304 | fn number(&self) -> usize { | ||
| 305 | $number | ||
| 306 | } | ||
| 307 | } | ||
| 308 | }; | ||
| 309 | } | ||
| 310 | |||
| 311 | impl_group!(PPI_GROUP0, 0); | ||
| 312 | impl_group!(PPI_GROUP1, 1); | ||
| 313 | impl_group!(PPI_GROUP2, 2); | ||
| 314 | impl_group!(PPI_GROUP3, 3); | ||
| 315 | #[cfg(not(feature = "nrf51"))] | ||
| 316 | impl_group!(PPI_GROUP4, 4); | ||
| 317 | #[cfg(not(feature = "nrf51"))] | ||
| 318 | impl_group!(PPI_GROUP5, 5); | ||
diff --git a/embassy-nrf/src/interconnect/ppi.rs b/embassy-nrf/src/interconnect/ppi.rs new file mode 100644 index 000000000..91ff811fe --- /dev/null +++ b/embassy-nrf/src/interconnect/ppi.rs | |||
| @@ -0,0 +1,65 @@ | |||
| 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 c21c4d398..39f3e4a4a 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 ppi; | 34 | pub mod interconnect; |
| 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.rs b/embassy-nrf/src/ppi.rs deleted file mode 100644 index 7aaf17ee5..000000000 --- a/embassy-nrf/src/ppi.rs +++ /dev/null | |||
| @@ -1,513 +0,0 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | //! HAL interface for the PPI peripheral. | ||
| 4 | //! | ||
| 5 | //! The Programmable Peripheral Interconnect interface allows for an autonomous interoperability | ||
| 6 | //! between peripherals through their events and tasks. There are fixed PPI channels and fully | ||
| 7 | //! configurable ones, fixed channels can only connect specific events to specific tasks. For fully | ||
| 8 | //! configurable channels, it is possible to choose, via software, the event and the task that it | ||
| 9 | //! will triggered by the event. | ||
| 10 | //! | ||
| 11 | //! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task | ||
| 12 | //! to be triggered by the same event, even fixed PPI channels have a configurable fork task. | ||
| 13 | |||
| 14 | use crate::{pac, peripherals}; | ||
| 15 | use core::marker::PhantomData; | ||
| 16 | use core::ptr::NonNull; | ||
| 17 | use embassy::util::Unborrow; | ||
| 18 | use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; | ||
| 19 | |||
| 20 | // ====================== | ||
| 21 | // driver | ||
| 22 | |||
| 23 | /// Error type of the PPI driver | ||
| 24 | #[non_exhaustive] | ||
| 25 | #[derive(Clone, Debug)] | ||
| 26 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 27 | pub enum Error { | ||
| 28 | /// There is no capacity to enable this task or event (nRF51 & nRF52 only) | ||
| 29 | NoCapacityLeft, | ||
| 30 | /// This task or event is not in use by the current channel | ||
| 31 | NotInUseByChannel, | ||
| 32 | /// This task or event is already enabled on another channel (nRF53 & nRF91 only) | ||
| 33 | AlreadyInUse, | ||
| 34 | } | ||
| 35 | |||
| 36 | pub struct Ppi<'d, C: Channel> { | ||
| 37 | ch: C, | ||
| 38 | phantom: PhantomData<&'d mut C>, | ||
| 39 | } | ||
| 40 | |||
| 41 | impl<'d, C: Channel> Ppi<'d, C> { | ||
| 42 | pub fn new(ch: impl Unborrow<Target = C> + 'd) -> Self { | ||
| 43 | unborrow!(ch); | ||
| 44 | |||
| 45 | Self { | ||
| 46 | ch, | ||
| 47 | phantom: PhantomData, | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | /// Enables the channel. | ||
| 52 | pub fn enable(&mut self) { | ||
| 53 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 54 | r.chenset | ||
| 55 | .write(|w| unsafe { w.bits(1 << self.ch.number()) }); | ||
| 56 | } | ||
| 57 | |||
| 58 | /// Disables the channel. | ||
| 59 | pub fn disable(&mut self) { | ||
| 60 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 61 | r.chenclr | ||
| 62 | .write(|w| unsafe { w.bits(1 << self.ch.number()) }); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | #[cfg(feature = "_ppi")] | ||
| 67 | impl<'d, C: Channel> Ppi<'d, C> { | ||
| 68 | /// Makes it so that the given task is subscribed to this channel | ||
| 69 | pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { | ||
| 70 | if self.is_main_task_free() { | ||
| 71 | self.set_main_task(Some(task)); | ||
| 72 | Ok(()) | ||
| 73 | } else if self.is_fork_task_free() { | ||
| 74 | self.set_fork_task(Some(task)); | ||
| 75 | Ok(()) | ||
| 76 | } else { | ||
| 77 | Err(Error::NoCapacityLeft) | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | /// Makes it so that the given task is not subscribed to this channel | ||
| 82 | pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { | ||
| 83 | if self.get_main_task() == Some(task) { | ||
| 84 | // If there is a fork task, we move that to the main task for consistency | ||
| 85 | // If there is no fork task, then the main task is set to 0 | ||
| 86 | let fork_task = self.get_fork_task(); | ||
| 87 | self.set_main_task(fork_task); | ||
| 88 | |||
| 89 | if self.has_fork_task() { | ||
| 90 | // The fork task was copied to the main task, so reset the fork task | ||
| 91 | self.set_fork_task(None); | ||
| 92 | } | ||
| 93 | Ok(()) | ||
| 94 | } else if self.get_fork_task() == Some(task) { | ||
| 95 | // Reset the fork task | ||
| 96 | self.set_fork_task(None); | ||
| 97 | Ok(()) | ||
| 98 | } else { | ||
| 99 | Err(Error::NotInUseByChannel) | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | /// Makes it so that the given event is published on this channel | ||
| 104 | pub fn publish(&mut self, event: Event) -> Result<(), Error> { | ||
| 105 | if self.is_event_free() { | ||
| 106 | self.set_event(Some(event)); | ||
| 107 | Ok(()) | ||
| 108 | } else { | ||
| 109 | Err(Error::NoCapacityLeft) | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | /// Makes it so that the given event is not published on this channel | ||
| 114 | pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { | ||
| 115 | if self.get_event() == Some(event) { | ||
| 116 | self.set_event(None); | ||
| 117 | Ok(()) | ||
| 118 | } else { | ||
| 119 | Err(Error::NotInUseByChannel) | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | fn set_main_task(&mut self, task: Option<Task>) { | ||
| 124 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 125 | if let Some(task) = task { | ||
| 126 | r.ch[self.ch.number()] | ||
| 127 | .tep | ||
| 128 | .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) | ||
| 129 | } else { | ||
| 130 | r.ch[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | fn get_main_task(&mut self) -> Option<Task> { | ||
| 135 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 136 | |||
| 137 | if !self.has_main_task() { | ||
| 138 | return None; | ||
| 139 | } | ||
| 140 | |||
| 141 | let bits = r.ch[self.ch.number()].tep.read().tep().bits(); | ||
| 142 | |||
| 143 | if bits == 0 { | ||
| 144 | None | ||
| 145 | } else { | ||
| 146 | unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) } | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | fn set_fork_task(&mut self, task: Option<Task>) { | ||
| 151 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 152 | if let Some(task) = task { | ||
| 153 | r.fork[self.ch.number()] | ||
| 154 | .tep | ||
| 155 | .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) | ||
| 156 | } else { | ||
| 157 | r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | fn get_fork_task(&mut self) -> Option<Task> { | ||
| 162 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 163 | |||
| 164 | if !self.has_fork_task() { | ||
| 165 | return None; | ||
| 166 | } | ||
| 167 | |||
| 168 | let bits = r.fork[self.ch.number()].tep.read().tep().bits(); | ||
| 169 | |||
| 170 | if bits == 0 { | ||
| 171 | None | ||
| 172 | } else { | ||
| 173 | unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) } | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | fn has_main_task(&self) -> bool { | ||
| 178 | match (self.ch.task_capacity(), self.ch.event_capacity()) { | ||
| 179 | (0, 0) => false, // Static task | ||
| 180 | (1, 0) => false, // Static task with fork | ||
| 181 | (1 | 2, 1) => true, // Configurable task with possibly a fork | ||
| 182 | _ => unreachable!(), // Every PPI config is covered | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | fn has_fork_task(&self) -> bool { | ||
| 187 | match (self.ch.task_capacity(), self.ch.event_capacity()) { | ||
| 188 | (0, 0) => false, // Static task | ||
| 189 | (1, 0) => true, // Static task with fork | ||
| 190 | (1, 1) => false, // Configurable task without fork | ||
| 191 | (2, 1) => true, // Configurable task with fork | ||
| 192 | _ => unreachable!(), // Every PPI config is covered | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | fn is_main_task_free(&mut self) -> bool { | ||
| 197 | self.get_main_task().is_none() | ||
| 198 | } | ||
| 199 | |||
| 200 | fn is_fork_task_free(&mut self) -> bool { | ||
| 201 | self.get_fork_task().is_none() | ||
| 202 | } | ||
| 203 | |||
| 204 | fn set_event(&mut self, event: Option<Event>) { | ||
| 205 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 206 | if let Some(event) = event { | ||
| 207 | r.ch[self.ch.number()] | ||
| 208 | .eep | ||
| 209 | .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) | ||
| 210 | } else { | ||
| 211 | r.ch[self.ch.number()].eep.write(|w| unsafe { w.bits(0) }) | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | fn get_event(&mut self) -> Option<Event> { | ||
| 216 | let r = unsafe { &*pac::PPI::ptr() }; | ||
| 217 | |||
| 218 | if !self.has_event() { | ||
| 219 | return None; | ||
| 220 | } | ||
| 221 | |||
| 222 | let bits = r.ch[self.ch.number()].eep.read().eep().bits(); | ||
| 223 | |||
| 224 | if bits == 0 { | ||
| 225 | None | ||
| 226 | } else { | ||
| 227 | unsafe { Some(Event(NonNull::new_unchecked(bits as *mut _))) } | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | fn has_event(&self) -> bool { | ||
| 232 | match (self.ch.task_capacity(), self.ch.event_capacity()) { | ||
| 233 | (_, 0) => false, // Static event | ||
| 234 | (_, 1) => true, // Configurable event | ||
| 235 | _ => unreachable!(), // Every PPI config is covered | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | fn is_event_free(&mut self) -> bool { | ||
| 240 | self.get_event().is_none() | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | #[cfg(feature = "_dppi")] | ||
| 245 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | ||
| 246 | #[cfg(feature = "_dppi")] | ||
| 247 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | ||
| 248 | |||
| 249 | #[cfg(feature = "_dppi")] | ||
| 250 | impl<'d, C: Channel> Ppi<'d, C> { | ||
| 251 | /// Makes it so that the given task is subscribed to this channel | ||
| 252 | pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { | ||
| 253 | unsafe { | ||
| 254 | if Self::is_register_enabled(task.0) { | ||
| 255 | Err(Error::AlreadyInUse) | ||
| 256 | } else { | ||
| 257 | Self::set_register_active(task.0, self.ch.number() as u8); | ||
| 258 | Ok(()) | ||
| 259 | } | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | /// Makes it so that the given task is not subscribed to this channel | ||
| 264 | pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { | ||
| 265 | unsafe { | ||
| 266 | if Self::get_register_channel(task.0) != self.ch.number() as u8 { | ||
| 267 | Err(Error::NotInUseByChannel) | ||
| 268 | } else { | ||
| 269 | Self::set_register_inactive(task.0); | ||
| 270 | Ok(()) | ||
| 271 | } | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | /// Makes it so that the given event is published on this channel | ||
| 276 | pub fn publish(&mut self, event: Event) -> Result<(), Error> { | ||
| 277 | unsafe { | ||
| 278 | if Self::is_register_enabled(event.0) { | ||
| 279 | Err(Error::AlreadyInUse) | ||
| 280 | } else { | ||
| 281 | Self::set_register_active(event.0, self.ch.number() as u8); | ||
| 282 | Ok(()) | ||
| 283 | } | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | /// Makes it so that the given event is not published on this channel | ||
| 288 | pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { | ||
| 289 | unsafe { | ||
| 290 | if Self::get_register_channel(event.0) != self.ch.number() as u8 { | ||
| 291 | Err(Error::NotInUseByChannel) | ||
| 292 | } else { | ||
| 293 | Self::set_register_inactive(event.0); | ||
| 294 | Ok(()) | ||
| 295 | } | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | /// Checks if the DPPI_ENABLE_BIT is set in the register | ||
| 300 | /// | ||
| 301 | /// # Safety | ||
| 302 | /// | ||
| 303 | /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals | ||
| 304 | unsafe fn is_register_enabled(register: NonNull<u32>) -> bool { | ||
| 305 | let bits = register.as_ptr().read_volatile(); | ||
| 306 | bits & DPPI_ENABLE_BIT > 0 | ||
| 307 | } | ||
| 308 | |||
| 309 | /// Sets the register to the given channel and enables it | ||
| 310 | /// | ||
| 311 | /// # Safety | ||
| 312 | /// | ||
| 313 | /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals | ||
| 314 | unsafe fn set_register_active(register: NonNull<u32>, channel: u8) { | ||
| 315 | register | ||
| 316 | .as_ptr() | ||
| 317 | .write_volatile(DPPI_ENABLE_BIT | (channel as u32 & DPPI_CHANNEL_MASK)); | ||
| 318 | } | ||
| 319 | |||
| 320 | /// Resets the channel number and disables the register | ||
| 321 | /// | ||
| 322 | /// # Safety | ||
| 323 | /// | ||
| 324 | /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals | ||
| 325 | unsafe fn set_register_inactive(register: NonNull<u32>) { | ||
| 326 | register.as_ptr().write_volatile(0); | ||
| 327 | } | ||
| 328 | |||
| 329 | /// Gets the current configured channel number of the register | ||
| 330 | /// | ||
| 331 | /// # Safety | ||
| 332 | /// | ||
| 333 | /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals | ||
| 334 | unsafe fn get_register_channel(register: NonNull<u32>) -> u8 { | ||
| 335 | let bits = register.as_ptr().read_volatile(); | ||
| 336 | (bits & DPPI_CHANNEL_MASK) as u8 | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | impl<'d, C: Channel> Drop for Ppi<'d, C> { | ||
| 341 | fn drop(&mut self) { | ||
| 342 | self.disable() | ||
| 343 | } | ||
| 344 | } | ||
| 345 | |||
| 346 | /// Represents a task that a peripheral can do. | ||
| 347 | /// When a task is subscribed to a PPI channel it will run when the channel is triggered by | ||
| 348 | /// a published event. | ||
| 349 | /// | ||
| 350 | /// The pointer in the task can point to two different kinds of register: | ||
| 351 | /// - PPI *(nRF51 & nRF52)*: A pointer to a task register of the task of the peripheral that has | ||
| 352 | /// to be registered with the PPI to subscribe to a channel | ||
| 353 | /// - DPPI *(nRF53 & nRF91)*: A pointer to the subscribe register of the task of the peripheral | ||
| 354 | /// that has to have the channel number and enable bit written tp it to subscribe to a channel | ||
| 355 | #[derive(PartialEq, Eq, Clone, Copy)] | ||
| 356 | pub struct Task(pub NonNull<u32>); | ||
| 357 | impl Task { | ||
| 358 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | ||
| 359 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | /// Represents an event that a peripheral can publish. | ||
| 364 | /// An event can be set to publish on a PPI channel when the event happens. | ||
| 365 | /// | ||
| 366 | /// The pointer in the event can point to two different kinds of register: | ||
| 367 | /// - PPI *(nRF51 & nRF52)*: A pointer to an event register of the event of the peripheral that has | ||
| 368 | /// to be registered with the PPI to publish to a channel | ||
| 369 | /// - DPPI *(nRF53 & nRF91)*: A pointer to the publish register of the event of the peripheral | ||
| 370 | /// that has to have the channel number and enable bit written tp it to publish to a channel | ||
| 371 | #[derive(PartialEq, Eq, Clone, Copy)] | ||
| 372 | pub struct Event(pub NonNull<u32>); | ||
| 373 | impl Event { | ||
| 374 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | ||
| 375 | Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | // ====================== | ||
| 380 | // traits | ||
| 381 | |||
| 382 | pub(crate) mod sealed { | ||
| 383 | pub trait Channel {} | ||
| 384 | pub trait Group {} | ||
| 385 | } | ||
| 386 | |||
| 387 | pub trait Channel: sealed::Channel + Sized { | ||
| 388 | /// Returns the number of the channel | ||
| 389 | fn number(&self) -> usize; | ||
| 390 | |||
| 391 | /// Returns the amount of configurable tasks this channel has. | ||
| 392 | /// | ||
| 393 | /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91) | ||
| 394 | /// - 0 for static channel without fork (nRF51) | ||
| 395 | /// - 1 for static channel with fork (nRF52) or for configurable channel (nRF51) | ||
| 396 | /// - 2 for configurable channel with fork (nRF52) | ||
| 397 | fn task_capacity(&self) -> usize; | ||
| 398 | |||
| 399 | /// Returns the amount of configurable events this channels has | ||
| 400 | /// | ||
| 401 | /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91) | ||
| 402 | /// - 0 for static channel (nRF51 & nRF52) | ||
| 403 | /// - 1 for configurable channel (nRF51 & nRF52) | ||
| 404 | fn event_capacity(&self) -> usize; | ||
| 405 | |||
| 406 | fn degrade(self) -> AnyChannel { | ||
| 407 | pub trait ConfigurableChannel {} | ||
| 408 | |||
| 409 | AnyChannel { | ||
| 410 | number: self.number() as u8, | ||
| 411 | task_capacity: self.task_capacity() as _, | ||
| 412 | event_capacity: self.event_capacity() as _, | ||
| 413 | } | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | pub trait Group: sealed::Group + Sized { | ||
| 418 | fn number(&self) -> usize; | ||
| 419 | fn degrade(self) -> AnyGroup { | ||
| 420 | AnyGroup { | ||
| 421 | number: self.number() as u8, | ||
| 422 | } | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | // ====================== | ||
| 427 | // channels | ||
| 428 | |||
| 429 | pub struct AnyChannel { | ||
| 430 | number: u8, | ||
| 431 | task_capacity: u8, | ||
| 432 | event_capacity: u8, | ||
| 433 | } | ||
| 434 | unsafe_impl_unborrow!(AnyChannel); | ||
| 435 | impl sealed::Channel for AnyChannel {} | ||
| 436 | impl Channel for AnyChannel { | ||
| 437 | fn number(&self) -> usize { | ||
| 438 | self.number as usize | ||
| 439 | } | ||
| 440 | |||
| 441 | fn task_capacity(&self) -> usize { | ||
| 442 | self.task_capacity as _ | ||
| 443 | } | ||
| 444 | |||
| 445 | fn event_capacity(&self) -> usize { | ||
| 446 | self.event_capacity as _ | ||
| 447 | } | ||
| 448 | } | ||
| 449 | |||
| 450 | macro_rules! impl_ppi_channel { | ||
| 451 | ($type:ident, $number:expr, $task_capacity:expr, $event_capacity:expr) => { | ||
| 452 | impl crate::ppi::sealed::Channel for peripherals::$type {} | ||
| 453 | impl crate::ppi::Channel for peripherals::$type { | ||
| 454 | fn number(&self) -> usize { | ||
| 455 | $number | ||
| 456 | } | ||
| 457 | fn task_capacity(&self) -> usize { | ||
| 458 | $task_capacity | ||
| 459 | } | ||
| 460 | fn event_capacity(&self) -> usize { | ||
| 461 | $event_capacity | ||
| 462 | } | ||
| 463 | } | ||
| 464 | }; | ||
| 465 | ($type:ident, $number:expr) => { | ||
| 466 | impl crate::ppi::sealed::Channel for peripherals::$type {} | ||
| 467 | impl crate::ppi::Channel for peripherals::$type { | ||
| 468 | fn number(&self) -> usize { | ||
| 469 | $number | ||
| 470 | } | ||
| 471 | fn task_capacity(&self) -> usize { | ||
| 472 | usize::MAX | ||
| 473 | } | ||
| 474 | fn event_capacity(&self) -> usize { | ||
| 475 | usize::MAX | ||
| 476 | } | ||
| 477 | } | ||
| 478 | }; | ||
| 479 | } | ||
| 480 | |||
| 481 | // ====================== | ||
| 482 | // groups | ||
| 483 | |||
| 484 | pub struct AnyGroup { | ||
| 485 | number: u8, | ||
| 486 | } | ||
| 487 | unsafe_impl_unborrow!(AnyGroup); | ||
| 488 | impl sealed::Group for AnyGroup {} | ||
| 489 | impl Group for AnyGroup { | ||
| 490 | fn number(&self) -> usize { | ||
| 491 | self.number as usize | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | macro_rules! impl_group { | ||
| 496 | ($type:ident, $number:expr) => { | ||
| 497 | impl sealed::Group for peripherals::$type {} | ||
| 498 | impl Group for peripherals::$type { | ||
| 499 | fn number(&self) -> usize { | ||
| 500 | $number | ||
| 501 | } | ||
| 502 | } | ||
| 503 | }; | ||
| 504 | } | ||
| 505 | |||
| 506 | impl_group!(PPI_GROUP0, 0); | ||
| 507 | impl_group!(PPI_GROUP1, 1); | ||
| 508 | impl_group!(PPI_GROUP2, 2); | ||
| 509 | impl_group!(PPI_GROUP3, 3); | ||
| 510 | #[cfg(not(feature = "nrf51"))] | ||
| 511 | impl_group!(PPI_GROUP4, 4); | ||
| 512 | #[cfg(not(feature = "nrf51"))] | ||
| 513 | impl_group!(PPI_GROUP5, 5); | ||
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index e62120aef..27f8e715e 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -11,9 +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}; | ||
| 14 | use crate::pac; | 15 | use crate::pac; |
| 15 | use crate::ppi::Event; | ||
| 16 | use crate::ppi::Task; | ||
| 17 | 16 | ||
| 18 | pub(crate) mod sealed { | 17 | pub(crate) mod sealed { |
| 19 | 18 | ||
| @@ -184,36 +183,21 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | |||
| 184 | /// | 183 | /// |
| 185 | /// When triggered, this task starts the timer. | 184 | /// When triggered, this task starts the timer. |
| 186 | pub fn task_start(&self) -> Task { | 185 | pub fn task_start(&self) -> Task { |
| 187 | #[cfg(feature = "_ppi")] | 186 | Task::from_reg(&T::regs().tasks_start) |
| 188 | let reg = &T::regs().tasks_start; | ||
| 189 | #[cfg(feature = "_dppi")] | ||
| 190 | let reg = &T::regs().subscribe_start; | ||
| 191 | |||
| 192 | Task::from_reg(reg) | ||
| 193 | } | 187 | } |
| 194 | 188 | ||
| 195 | /// Returns the STOP task, for use with PPI. | 189 | /// Returns the STOP task, for use with PPI. |
| 196 | /// | 190 | /// |
| 197 | /// When triggered, this task stops the timer. | 191 | /// When triggered, this task stops the timer. |
| 198 | pub fn task_stop(&self) -> Task { | 192 | pub fn task_stop(&self) -> Task { |
| 199 | #[cfg(feature = "_ppi")] | 193 | Task::from_reg(&T::regs().tasks_stop) |
| 200 | let reg = &T::regs().tasks_stop; | ||
| 201 | #[cfg(feature = "_dppi")] | ||
| 202 | let reg = &T::regs().subscribe_stop; | ||
| 203 | |||
| 204 | Task::from_reg(reg) | ||
| 205 | } | 194 | } |
| 206 | 195 | ||
| 207 | /// Returns the CLEAR task, for use with PPI. | 196 | /// Returns the CLEAR task, for use with PPI. |
| 208 | /// | 197 | /// |
| 209 | /// When triggered, this task resets the timer's counter to 0. | 198 | /// When triggered, this task resets the timer's counter to 0. |
| 210 | pub fn task_clear(&self) -> Task { | 199 | pub fn task_clear(&self) -> Task { |
| 211 | #[cfg(feature = "_ppi")] | 200 | Task::from_reg(&T::regs().tasks_clear) |
| 212 | let reg = &T::regs().tasks_clear; | ||
| 213 | #[cfg(feature = "_dppi")] | ||
| 214 | let reg = &T::regs().subscribe_clear; | ||
| 215 | |||
| 216 | Task::from_reg(reg) | ||
| 217 | } | 201 | } |
| 218 | 202 | ||
| 219 | /// Change the timer's frequency. | 203 | /// Change the timer's frequency. |
| @@ -334,24 +318,14 @@ impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { | |||
| 334 | /// | 318 | /// |
| 335 | /// When triggered, this task will capture the current value of the timer's counter in this register. | 319 | /// When triggered, this task will capture the current value of the timer's counter in this register. |
| 336 | pub fn task_capture(&self) -> Task { | 320 | pub fn task_capture(&self) -> Task { |
| 337 | #[cfg(feature = "_ppi")] | 321 | Task::from_reg(&T::regs().tasks_capture) |
| 338 | let reg = &T::regs().tasks_capture; | ||
| 339 | #[cfg(feature = "_dppi")] | ||
| 340 | let reg = &T::regs().subscribe_capture; | ||
| 341 | |||
| 342 | Task::from_reg(reg) | ||
| 343 | } | 322 | } |
| 344 | 323 | ||
| 345 | /// Returns this CC register's COMPARE event, for use with PPI. | 324 | /// Returns this CC register's COMPARE event, for use with PPI. |
| 346 | /// | 325 | /// |
| 347 | /// This event will fire when the timer's counter reaches the value in this CC register. | 326 | /// This event will fire when the timer's counter reaches the value in this CC register. |
| 348 | pub fn event_compare(&self) -> Event { | 327 | pub fn event_compare(&self) -> Event { |
| 349 | #[cfg(feature = "_ppi")] | 328 | Event::from_reg(&T::regs().events_compare[self.n]) |
| 350 | let reg = &T::regs().events_compare[self.n]; | ||
| 351 | #[cfg(feature = "_dppi")] | ||
| 352 | let reg = &T::regs().publish_compare[self.n]; | ||
| 353 | |||
| 354 | Event::from_reg(reg) | ||
| 355 | } | 329 | } |
| 356 | 330 | ||
| 357 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 331 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 71401a561..17e60ce22 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}; | ||
| 19 | use crate::interrupt::Interrupt; | 20 | use crate::interrupt::Interrupt; |
| 20 | use crate::pac; | 21 | use crate::pac; |
| 21 | use crate::ppi::{AnyChannel, Channel, Event, 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 | ||
| @@ -26,19 +26,6 @@ use crate::timer::{Frequency, Timer}; | |||
| 26 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 26 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; |
| 27 | 27 | ||
| 28 | #[non_exhaustive] | 28 | #[non_exhaustive] |
| 29 | #[derive(Clone, Debug)] | ||
| 30 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 31 | pub enum Error { | ||
| 32 | PpiError(crate::ppi::Error), | ||
| 33 | } | ||
| 34 | |||
| 35 | impl From<crate::ppi::Error> for Error { | ||
| 36 | fn from(e: crate::ppi::Error) -> Self { | ||
| 37 | Self::PpiError(e) | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | #[non_exhaustive] | ||
| 42 | pub struct Config { | 29 | pub struct Config { |
| 43 | pub parity: Parity, | 30 | pub parity: Parity, |
| 44 | pub baudrate: Baudrate, | 31 | pub baudrate: Baudrate, |
| @@ -344,17 +331,14 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { | |||
| 344 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { | 331 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { |
| 345 | uarte: Uarte<'d, U>, | 332 | uarte: Uarte<'d, U>, |
| 346 | timer: Timer<'d, T>, | 333 | timer: Timer<'d, T>, |
| 347 | ppi_ch1: Ppi<'d, AnyChannel>, | 334 | ppi_ch1: Ppi<'d, AnyChannel, 1, 2>, |
| 348 | _ppi_ch2: Ppi<'d, AnyChannel>, | 335 | _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>, |
| 349 | } | 336 | } |
| 350 | 337 | ||
| 351 | impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | 338 | impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { |
| 352 | /// Creates the interface to a UARTE instance. | 339 | /// Creates the interface to a UARTE instance. |
| 353 | /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. | 340 | /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. |
| 354 | /// | 341 | /// |
| 355 | /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned | ||
| 356 | /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned | ||
| 357 | /// | ||
| 358 | /// # Safety | 342 | /// # Safety |
| 359 | /// | 343 | /// |
| 360 | /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) | 344 | /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) |
| @@ -364,15 +348,15 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | |||
| 364 | pub unsafe fn new( | 348 | pub unsafe fn new( |
| 365 | uarte: impl Unborrow<Target = U> + 'd, | 349 | uarte: impl Unborrow<Target = U> + 'd, |
| 366 | timer: impl Unborrow<Target = T> + 'd, | 350 | timer: impl Unborrow<Target = T> + 'd, |
| 367 | ppi_ch1: impl Unborrow<Target = impl Channel> + 'd, | 351 | ppi_ch1: impl Unborrow<Target = impl OneToTwoChannel + 'd> + 'd, |
| 368 | ppi_ch2: impl Unborrow<Target = impl Channel> + 'd, | 352 | ppi_ch2: impl Unborrow<Target = impl OneToOneChannel + 'd> + 'd, |
| 369 | irq: impl Unborrow<Target = U::Interrupt> + 'd, | 353 | irq: impl Unborrow<Target = U::Interrupt> + 'd, |
| 370 | rxd: impl Unborrow<Target = impl GpioPin> + 'd, | 354 | rxd: impl Unborrow<Target = impl GpioPin> + 'd, |
| 371 | txd: impl Unborrow<Target = impl GpioPin> + 'd, | 355 | txd: impl Unborrow<Target = impl GpioPin> + 'd, |
| 372 | cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | 356 | cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, |
| 373 | rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | 357 | rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, |
| 374 | config: Config, | 358 | config: Config, |
| 375 | ) -> Result<Self, Error> { | 359 | ) -> Self { |
| 376 | let baudrate = config.baudrate; | 360 | let baudrate = config.baudrate; |
| 377 | let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); | 361 | let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); |
| 378 | let mut timer = Timer::new(timer); | 362 | let mut timer = Timer::new(timer); |
| @@ -394,23 +378,29 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | |||
| 394 | timer.cc(0).short_compare_clear(); | 378 | timer.cc(0).short_compare_clear(); |
| 395 | timer.cc(0).short_compare_stop(); | 379 | timer.cc(0).short_compare_stop(); |
| 396 | 380 | ||
| 397 | let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); | 381 | let mut ppi_ch1 = Ppi::new_one_to_two( |
| 398 | ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; | 382 | ppi_ch1, |
| 399 | ppi_ch1.subscribe(timer.task_clear())?; | 383 | Event::from_reg(&r.events_rxdrdy), |
| 400 | ppi_ch1.subscribe(timer.task_start())?; | 384 | timer.task_clear(), |
| 385 | timer.task_start(), | ||
| 386 | ) | ||
| 387 | .degrade(); | ||
| 401 | ppi_ch1.enable(); | 388 | ppi_ch1.enable(); |
| 402 | 389 | ||
| 403 | let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); | 390 | let mut ppi_ch2 = Ppi::new_one_to_one( |
| 404 | ppi_ch2.publish(timer.cc(0).event_compare())?; | 391 | ppi_ch2, |
| 405 | ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; | 392 | timer.cc(0).event_compare(), |
| 393 | Task::from_reg(&r.tasks_stoprx), | ||
| 394 | ) | ||
| 395 | .degrade(); | ||
| 406 | ppi_ch2.enable(); | 396 | ppi_ch2.enable(); |
| 407 | 397 | ||
| 408 | Ok(Self { | 398 | Self { |
| 409 | uarte, | 399 | uarte, |
| 410 | timer, | 400 | timer, |
| 411 | ppi_ch1: ppi_ch1, | 401 | ppi_ch1: ppi_ch1, |
| 412 | _ppi_ch2: ppi_ch2, | 402 | _ppi_ch2: ppi_ch2, |
| 413 | }) | 403 | } |
| 414 | } | 404 | } |
| 415 | } | 405 | } |
| 416 | 406 | ||
diff --git a/examples/nrf/src/bin/buffered_uart.rs b/examples/nrf/src/bin/buffered_uart.rs index b01c83ce3..69c7de93b 100644 --- a/examples/nrf/src/bin/buffered_uart.rs +++ b/examples/nrf/src/bin/buffered_uart.rs | |||
| @@ -26,7 +26,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 26 | let irq = interrupt::take!(UARTE0_UART0); | 26 | let irq = interrupt::take!(UARTE0_UART0); |
| 27 | let mut state = State::new(); | 27 | let mut state = State::new(); |
| 28 | let u = unsafe { | 28 | let u = unsafe { |
| 29 | unwrap!(BufferedUarte::new( | 29 | BufferedUarte::new( |
| 30 | &mut state, | 30 | &mut state, |
| 31 | p.UARTE0, | 31 | p.UARTE0, |
| 32 | p.TIMER0, | 32 | p.TIMER0, |
| @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 40 | config, | 40 | config, |
| 41 | &mut rx_buffer, | 41 | &mut rx_buffer, |
| 42 | &mut tx_buffer, | 42 | &mut tx_buffer, |
| 43 | )) | 43 | ) |
| 44 | }; | 44 | }; |
| 45 | pin_mut!(u); | 45 | pin_mut!(u); |
| 46 | 46 | ||
diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs index 550893968..4edb5d7c0 100644 --- a/examples/nrf/src/bin/ppi.rs +++ b/examples/nrf/src/bin/ppi.rs | |||
| @@ -10,7 +10,7 @@ use core::future::pending; | |||
| 10 | use embassy::executor::Spawner; | 10 | use embassy::executor::Spawner; |
| 11 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 11 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 12 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; | 12 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; |
| 13 | use embassy_nrf::ppi::Ppi; | 13 | use embassy_nrf::interconnect::Ppi; |
| 14 | use embassy_nrf::Peripherals; | 14 | use embassy_nrf::Peripherals; |
| 15 | use gpiote::{OutputChannel, OutputChannelPolarity}; | 15 | use gpiote::{OutputChannel, OutputChannelPolarity}; |
| 16 | 16 | ||
| @@ -51,25 +51,21 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 51 | OutputChannelPolarity::Toggle, | 51 | OutputChannelPolarity::Toggle, |
| 52 | ); | 52 | ); |
| 53 | 53 | ||
| 54 | let mut ppi = Ppi::new(p.PPI_CH0); | 54 | let mut ppi = Ppi::new_one_to_one(p.PPI_CH0, button1.event_in(), led1.task_out()); |
| 55 | ppi.publish(button1.event_in()).unwrap(); | ||
| 56 | ppi.subscribe(led1.task_out()).unwrap(); | ||
| 57 | ppi.enable(); | 55 | ppi.enable(); |
| 58 | 56 | ||
| 59 | let mut ppi = Ppi::new(p.PPI_CH1); | 57 | let mut ppi = Ppi::new_one_to_one(p.PPI_CH1, button2.event_in(), led1.task_clr()); |
| 60 | ppi.publish(button2.event_in()).unwrap(); | ||
| 61 | ppi.subscribe(led1.task_clr()).unwrap(); | ||
| 62 | ppi.enable(); | 58 | ppi.enable(); |
| 63 | 59 | ||
| 64 | let mut ppi = Ppi::new(p.PPI_CH2); | 60 | let mut ppi = Ppi::new_one_to_one(p.PPI_CH2, button3.event_in(), led1.task_set()); |
| 65 | ppi.publish(button3.event_in()).unwrap(); | ||
| 66 | ppi.subscribe(led1.task_set()).unwrap(); | ||
| 67 | ppi.enable(); | 61 | ppi.enable(); |
| 68 | 62 | ||
| 69 | let mut ppi = Ppi::new(p.PPI_CH3); | 63 | let mut ppi = Ppi::new_one_to_two( |
| 70 | ppi.publish(button4.event_in()).unwrap(); | 64 | p.PPI_CH3, |
| 71 | ppi.subscribe(led1.task_out()).unwrap(); | 65 | button4.event_in(), |
| 72 | ppi.subscribe(led2.task_out()).unwrap(); | 66 | led1.task_out(), |
| 67 | led2.task_out(), | ||
| 68 | ); | ||
| 73 | ppi.enable(); | 69 | ppi.enable(); |
| 74 | 70 | ||
| 75 | info!("PPI setup!"); | 71 | info!("PPI setup!"); |
diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs index e04e5cf04..e9f4a285a 100644 --- a/examples/nrf/src/bin/uart_idle.rs +++ b/examples/nrf/src/bin/uart_idle.rs | |||
| @@ -21,9 +21,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 21 | 21 | ||
| 22 | let irq = interrupt::take!(UARTE0_UART0); | 22 | let irq = interrupt::take!(UARTE0_UART0); |
| 23 | let mut uart = unsafe { | 23 | let mut uart = unsafe { |
| 24 | unwrap!(uarte::UarteWithIdle::new( | 24 | uarte::UarteWithIdle::new( |
| 25 | p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config, | 25 | p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config, |
| 26 | )) | 26 | ) |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | info!("uarte initialized!"); | 29 | info!("uarte initialized!"); |
