diff options
| -rw-r--r-- | embassy-nrf/src/lib.rs | 48 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi.rs | 143 |
2 files changed, 191 insertions, 0 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 9e5132c59..1bcaf5483 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -97,6 +97,7 @@ pub mod buffered_uarte; | |||
| 97 | pub mod gpio; | 97 | pub mod gpio; |
| 98 | pub mod gpiote; | 98 | pub mod gpiote; |
| 99 | pub mod interrupt; | 99 | pub mod interrupt; |
| 100 | pub mod ppi; | ||
| 100 | #[cfg(feature = "52840")] | 101 | #[cfg(feature = "52840")] |
| 101 | pub mod qspi; | 102 | pub mod qspi; |
| 102 | pub mod rtc; | 103 | pub mod rtc; |
| @@ -145,6 +146,53 @@ embassy_extras::peripherals! { | |||
| 145 | GPIOTE_CH6, | 146 | GPIOTE_CH6, |
| 146 | GPIOTE_CH7, | 147 | GPIOTE_CH7, |
| 147 | 148 | ||
| 149 | // PPI | ||
| 150 | PPI_CH0, | ||
| 151 | PPI_CH1, | ||
| 152 | PPI_CH2, | ||
| 153 | PPI_CH3, | ||
| 154 | PPI_CH4, | ||
| 155 | PPI_CH5, | ||
| 156 | PPI_CH6, | ||
| 157 | PPI_CH7, | ||
| 158 | PPI_CH8, | ||
| 159 | PPI_CH9, | ||
| 160 | PPI_CH10, | ||
| 161 | PPI_CH11, | ||
| 162 | PPI_CH12, | ||
| 163 | PPI_CH13, | ||
| 164 | PPI_CH14, | ||
| 165 | PPI_CH15, | ||
| 166 | #[cfg(not(feature = "51"))] | ||
| 167 | PPI_CH16, | ||
| 168 | #[cfg(not(feature = "51"))] | ||
| 169 | PPI_CH17, | ||
| 170 | #[cfg(not(feature = "51"))] | ||
| 171 | PPI_CH18, | ||
| 172 | #[cfg(not(feature = "51"))] | ||
| 173 | PPI_CH19, | ||
| 174 | PPI_CH20, | ||
| 175 | PPI_CH21, | ||
| 176 | PPI_CH22, | ||
| 177 | PPI_CH23, | ||
| 178 | PPI_CH24, | ||
| 179 | PPI_CH25, | ||
| 180 | PPI_CH26, | ||
| 181 | PPI_CH27, | ||
| 182 | PPI_CH28, | ||
| 183 | PPI_CH29, | ||
| 184 | PPI_CH30, | ||
| 185 | PPI_CH31, | ||
| 186 | |||
| 187 | PPI_GROUP0, | ||
| 188 | PPI_GROUP1, | ||
| 189 | PPI_GROUP2, | ||
| 190 | PPI_GROUP3, | ||
| 191 | #[cfg(not(feature = "51"))] | ||
| 192 | PPI_GROUP4, | ||
| 193 | #[cfg(not(feature = "51"))] | ||
| 194 | PPI_GROUP5, | ||
| 195 | |||
| 148 | // GPIO port 0 | 196 | // GPIO port 0 |
| 149 | P0_00, | 197 | P0_00, |
| 150 | P0_01, | 198 | P0_01, |
diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs new file mode 100644 index 000000000..c06b212c1 --- /dev/null +++ b/embassy-nrf/src/ppi.rs | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | //! HAL interface for the PPI peripheral. | ||
| 2 | //! | ||
| 3 | //! The Programmable Peripheral Interconnect interface allows for an autonomous interoperability | ||
| 4 | //! between peripherals through their events and tasks. There are fixed PPI channels and fully | ||
| 5 | //! configurable ones, fixed channels can only connect specific events to specific tasks. For fully | ||
| 6 | //! configurable channels, it is possible to choose, via software, the event and the task that it | ||
| 7 | //! will triggered by the event. | ||
| 8 | //! | ||
| 9 | //! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task | ||
| 10 | //! to be triggered by the same event, even fixed PPI channels have a configurable fork task. | ||
| 11 | |||
| 12 | use embassy_extras::impl_unborrow; | ||
| 13 | |||
| 14 | use crate::peripherals; | ||
| 15 | |||
| 16 | // ====================== | ||
| 17 | // traits | ||
| 18 | |||
| 19 | mod sealed { | ||
| 20 | pub trait ConfigurableChannel {} | ||
| 21 | pub trait Channel {} | ||
| 22 | pub trait Group {} | ||
| 23 | } | ||
| 24 | |||
| 25 | pub trait Channel: sealed::Channel + Sized { | ||
| 26 | fn number(&self) -> usize; | ||
| 27 | fn degrade(self) -> AnyChannel { | ||
| 28 | AnyChannel { | ||
| 29 | number: self.number() as u8, | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | pub trait ConfigurableChannel: Channel + sealed::ConfigurableChannel {} | ||
| 34 | |||
| 35 | pub trait Group: sealed::Group + Sized { | ||
| 36 | fn number(&self) -> usize; | ||
| 37 | fn degrade(self) -> AnyGroup { | ||
| 38 | AnyGroup { | ||
| 39 | number: self.number() as u8, | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | // ====================== | ||
| 45 | // channels | ||
| 46 | |||
| 47 | pub struct AnyChannel { | ||
| 48 | number: u8, | ||
| 49 | } | ||
| 50 | impl_unborrow!(AnyChannel); | ||
| 51 | impl sealed::Channel for AnyChannel {} | ||
| 52 | impl Channel for AnyChannel { | ||
| 53 | fn number(&self) -> usize { | ||
| 54 | self.number as usize | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | macro_rules! impl_channel { | ||
| 59 | ($type:ident, $number:expr, configurable) => { | ||
| 60 | impl_channel!($type, $number); | ||
| 61 | impl sealed::ConfigurableChannel for peripherals::$type {} | ||
| 62 | impl ConfigurableChannel for peripherals::$type {} | ||
| 63 | }; | ||
| 64 | ($type:ident, $number:expr) => { | ||
| 65 | impl sealed::Channel for peripherals::$type {} | ||
| 66 | impl Channel for peripherals::$type { | ||
| 67 | fn number(&self) -> usize { | ||
| 68 | $number | ||
| 69 | } | ||
| 70 | } | ||
| 71 | }; | ||
| 72 | } | ||
| 73 | |||
| 74 | impl_channel!(PPI_CH0, 0, configurable); | ||
| 75 | impl_channel!(PPI_CH1, 1, configurable); | ||
| 76 | impl_channel!(PPI_CH2, 2, configurable); | ||
| 77 | impl_channel!(PPI_CH3, 3, configurable); | ||
| 78 | impl_channel!(PPI_CH4, 4, configurable); | ||
| 79 | impl_channel!(PPI_CH5, 5, configurable); | ||
| 80 | impl_channel!(PPI_CH6, 6, configurable); | ||
| 81 | impl_channel!(PPI_CH7, 7, configurable); | ||
| 82 | impl_channel!(PPI_CH8, 8, configurable); | ||
| 83 | impl_channel!(PPI_CH9, 9, configurable); | ||
| 84 | impl_channel!(PPI_CH10, 10, configurable); | ||
| 85 | impl_channel!(PPI_CH11, 11, configurable); | ||
| 86 | impl_channel!(PPI_CH12, 12, configurable); | ||
| 87 | impl_channel!(PPI_CH13, 13, configurable); | ||
| 88 | impl_channel!(PPI_CH14, 14, configurable); | ||
| 89 | impl_channel!(PPI_CH15, 15, configurable); | ||
| 90 | #[cfg(not(feature = "51"))] | ||
| 91 | impl_channel!(PPI_CH16, 16, configurable); | ||
| 92 | #[cfg(not(feature = "51"))] | ||
| 93 | impl_channel!(PPI_CH17, 17, configurable); | ||
| 94 | #[cfg(not(feature = "51"))] | ||
| 95 | impl_channel!(PPI_CH18, 18, configurable); | ||
| 96 | #[cfg(not(feature = "51"))] | ||
| 97 | impl_channel!(PPI_CH19, 19, configurable); | ||
| 98 | impl_channel!(PPI_CH20, 20); | ||
| 99 | impl_channel!(PPI_CH21, 21); | ||
| 100 | impl_channel!(PPI_CH22, 22); | ||
| 101 | impl_channel!(PPI_CH23, 23); | ||
| 102 | impl_channel!(PPI_CH24, 24); | ||
| 103 | impl_channel!(PPI_CH25, 25); | ||
| 104 | impl_channel!(PPI_CH26, 26); | ||
| 105 | impl_channel!(PPI_CH27, 27); | ||
| 106 | impl_channel!(PPI_CH28, 28); | ||
| 107 | impl_channel!(PPI_CH29, 29); | ||
| 108 | impl_channel!(PPI_CH30, 30); | ||
| 109 | impl_channel!(PPI_CH31, 31); | ||
| 110 | |||
| 111 | // ====================== | ||
| 112 | // groups | ||
| 113 | |||
| 114 | pub struct AnyGroup { | ||
| 115 | number: u8, | ||
| 116 | } | ||
| 117 | impl_unborrow!(AnyGroup); | ||
| 118 | impl sealed::Group for AnyGroup {} | ||
| 119 | impl Group for AnyGroup { | ||
| 120 | fn number(&self) -> usize { | ||
| 121 | self.number as usize | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | macro_rules! impl_group { | ||
| 126 | ($type:ident, $number:expr) => { | ||
| 127 | impl sealed::Group for peripherals::$type {} | ||
| 128 | impl Group for peripherals::$type { | ||
| 129 | fn number(&self) -> usize { | ||
| 130 | $number | ||
| 131 | } | ||
| 132 | } | ||
| 133 | }; | ||
| 134 | } | ||
| 135 | |||
| 136 | impl_group!(PPI_GROUP0, 0); | ||
| 137 | impl_group!(PPI_GROUP1, 1); | ||
| 138 | impl_group!(PPI_GROUP2, 2); | ||
| 139 | impl_group!(PPI_GROUP3, 3); | ||
| 140 | #[cfg(not(feature = "51"))] | ||
| 141 | impl_group!(PPI_GROUP4, 4); | ||
| 142 | #[cfg(not(feature = "51"))] | ||
| 143 | impl_group!(PPI_GROUP5, 5); | ||
