diff options
Diffstat (limited to 'embassy-nrf/src/ppi')
| -rw-r--r-- | embassy-nrf/src/ppi/dppi.rs | 11 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi/mod.rs | 123 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi/ppi.rs | 2 |
3 files changed, 92 insertions, 44 deletions
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 078d2fd1c..d43a25c4e 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 2 | use crate::{pac, Peri}; | 2 | use crate::Peri; |
| 3 | 3 | ||
| 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; |
| 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; |
| 6 | 6 | ||
| 7 | pub(crate) fn regs() -> pac::dppic::Dppic { | 7 | #[cfg(not(feature = "_nrf54l"))] |
| 8 | pac::DPPIC | 8 | pub(crate) fn regs() -> crate::pac::dppic::Dppic { |
| 9 | crate::pac::DPPIC | ||
| 9 | } | 10 | } |
| 10 | 11 | ||
| 11 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { | 12 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { |
| @@ -49,13 +50,13 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, | |||
| 49 | /// Enables the channel. | 50 | /// Enables the channel. |
| 50 | pub fn enable(&mut self) { | 51 | pub fn enable(&mut self) { |
| 51 | let n = self.ch.number(); | 52 | let n = self.ch.number(); |
| 52 | regs().chenset().write(|w| w.0 = 1 << n); | 53 | self.ch.regs().chenset().write(|w| w.0 = 1 << n); |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | /// Disables the channel. | 56 | /// Disables the channel. |
| 56 | pub fn disable(&mut self) { | 57 | pub fn disable(&mut self) { |
| 57 | let n = self.ch.number(); | 58 | let n = self.ch.number(); |
| 58 | regs().chenclr().write(|w| w.0 = 1 << n); | 59 | self.ch.regs().chenclr().write(|w| w.0 = 1 << n); |
| 59 | } | 60 | } |
| 60 | } | 61 | } |
| 61 | 62 | ||
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 2bcf72e9c..a880d3188 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs | |||
| @@ -18,14 +18,16 @@ | |||
| 18 | use core::marker::PhantomData; | 18 | use core::marker::PhantomData; |
| 19 | use core::ptr::NonNull; | 19 | use core::ptr::NonNull; |
| 20 | 20 | ||
| 21 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 21 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 22 | 22 | ||
| 23 | use crate::pac::common::{Reg, RW, W}; | 23 | use crate::pac::common::{RW, Reg, W}; |
| 24 | use crate::peripherals; | 24 | use crate::pac::{self}; |
| 25 | 25 | ||
| 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] | 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] |
| 27 | #[cfg_attr(feature = "_ppi", path = "ppi.rs")] | 27 | #[cfg_attr(feature = "_ppi", path = "ppi.rs")] |
| 28 | mod _version; | 28 | mod _version; |
| 29 | |||
| 30 | #[allow(unused_imports)] | ||
| 29 | pub(crate) use _version::*; | 31 | pub(crate) use _version::*; |
| 30 | 32 | ||
| 31 | /// PPI channel driver. | 33 | /// PPI channel driver. |
| @@ -47,7 +49,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 47 | /// | 49 | /// |
| 48 | /// The group is initialized as containing no channels. | 50 | /// The group is initialized as containing no channels. |
| 49 | pub fn new(g: Peri<'d, G>) -> Self { | 51 | pub fn new(g: Peri<'d, G>) -> Self { |
| 50 | let r = regs(); | 52 | let r = g.regs(); |
| 51 | let n = g.number(); | 53 | let n = g.number(); |
| 52 | r.chg(n).write(|_| ()); | 54 | r.chg(n).write(|_| ()); |
| 53 | 55 | ||
| @@ -61,7 +63,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 61 | &mut self, | 63 | &mut self, |
| 62 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, | 64 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, |
| 63 | ) { | 65 | ) { |
| 64 | let r = regs(); | 66 | let r = self.g.regs(); |
| 65 | let ng = self.g.number(); | 67 | let ng = self.g.number(); |
| 66 | let nc = ch.ch.number(); | 68 | let nc = ch.ch.number(); |
| 67 | r.chg(ng).modify(|w| w.set_ch(nc, true)); | 69 | r.chg(ng).modify(|w| w.set_ch(nc, true)); |
| @@ -74,7 +76,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 74 | &mut self, | 76 | &mut self, |
| 75 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, | 77 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, |
| 76 | ) { | 78 | ) { |
| 77 | let r = regs(); | 79 | let r = self.g.regs(); |
| 78 | let ng = self.g.number(); | 80 | let ng = self.g.number(); |
| 79 | let nc = ch.ch.number(); | 81 | let nc = ch.ch.number(); |
| 80 | r.chg(ng).modify(|w| w.set_ch(nc, false)); | 82 | r.chg(ng).modify(|w| w.set_ch(nc, false)); |
| @@ -83,13 +85,13 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 83 | /// Enable all the channels in this group. | 85 | /// Enable all the channels in this group. |
| 84 | pub fn enable_all(&mut self) { | 86 | pub fn enable_all(&mut self) { |
| 85 | let n = self.g.number(); | 87 | let n = self.g.number(); |
| 86 | regs().tasks_chg(n).en().write_value(1); | 88 | self.g.regs().tasks_chg(n).en().write_value(1); |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | /// Disable all the channels in this group. | 91 | /// Disable all the channels in this group. |
| 90 | pub fn disable_all(&mut self) { | 92 | pub fn disable_all(&mut self) { |
| 91 | let n = self.g.number(); | 93 | let n = self.g.number(); |
| 92 | regs().tasks_chg(n).dis().write_value(1); | 94 | self.g.regs().tasks_chg(n).dis().write_value(1); |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | /// Get a reference to the "enable all" task. | 97 | /// Get a reference to the "enable all" task. |
| @@ -97,7 +99,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 97 | /// When triggered, it will enable all the channels in this group. | 99 | /// When triggered, it will enable all the channels in this group. |
| 98 | pub fn task_enable_all(&self) -> Task<'d> { | 100 | pub fn task_enable_all(&self) -> Task<'d> { |
| 99 | let n = self.g.number(); | 101 | let n = self.g.number(); |
| 100 | Task::from_reg(regs().tasks_chg(n).en()) | 102 | Task::from_reg(self.g.regs().tasks_chg(n).en()) |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | /// Get a reference to the "disable all" task. | 105 | /// Get a reference to the "disable all" task. |
| @@ -105,7 +107,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 105 | /// When triggered, it will disable all the channels in this group. | 107 | /// When triggered, it will disable all the channels in this group. |
| 106 | pub fn task_disable_all(&self) -> Task<'d> { | 108 | pub fn task_disable_all(&self) -> Task<'d> { |
| 107 | let n = self.g.number(); | 109 | let n = self.g.number(); |
| 108 | Task::from_reg(regs().tasks_chg(n).dis()) | 110 | Task::from_reg(self.g.regs().tasks_chg(n).dis()) |
| 109 | } | 111 | } |
| 110 | } | 112 | } |
| 111 | impl<G: Group> PpiGroup<'static, G> { | 113 | impl<G: Group> PpiGroup<'static, G> { |
| @@ -119,7 +121,7 @@ impl<G: Group> PpiGroup<'static, G> { | |||
| 119 | 121 | ||
| 120 | impl<'d, G: Group> Drop for PpiGroup<'d, G> { | 122 | impl<'d, G: Group> Drop for PpiGroup<'d, G> { |
| 121 | fn drop(&mut self) { | 123 | fn drop(&mut self) { |
| 122 | let r = regs(); | 124 | let r = self.g.regs(); |
| 123 | let n = self.g.number(); | 125 | let n = self.g.number(); |
| 124 | r.chg(n).write(|_| ()); | 126 | r.chg(n).write(|_| ()); |
| 125 | } | 127 | } |
| @@ -211,8 +213,16 @@ unsafe impl Send for Event<'_> {} | |||
| 211 | // ====================== | 213 | // ====================== |
| 212 | // traits | 214 | // traits |
| 213 | 215 | ||
| 214 | pub(crate) trait SealedChannel {} | 216 | pub(crate) trait SealedChannel { |
| 215 | pub(crate) trait SealedGroup {} | 217 | #[cfg(feature = "_dppi")] |
| 218 | fn regs(&self) -> pac::dppic::Dppic; | ||
| 219 | } | ||
| 220 | pub(crate) trait SealedGroup { | ||
| 221 | #[cfg(feature = "_dppi")] | ||
| 222 | fn regs(&self) -> pac::dppic::Dppic; | ||
| 223 | #[cfg(not(feature = "_dppi"))] | ||
| 224 | fn regs(&self) -> pac::ppi::Ppi; | ||
| 225 | } | ||
| 216 | 226 | ||
| 217 | /// Interface for PPI channels. | 227 | /// Interface for PPI channels. |
| 218 | #[allow(private_bounds)] | 228 | #[allow(private_bounds)] |
| @@ -241,9 +251,16 @@ pub trait Group: SealedGroup + PeripheralType + Into<AnyGroup> + Sized + 'static | |||
| 241 | /// This can be used to have fewer generic parameters in some places. | 251 | /// This can be used to have fewer generic parameters in some places. |
| 242 | pub struct AnyStaticChannel { | 252 | pub struct AnyStaticChannel { |
| 243 | pub(crate) number: u8, | 253 | pub(crate) number: u8, |
| 254 | #[cfg(feature = "_dppi")] | ||
| 255 | pub(crate) regs: pac::dppic::Dppic, | ||
| 244 | } | 256 | } |
| 245 | impl_peripheral!(AnyStaticChannel); | 257 | impl_peripheral!(AnyStaticChannel); |
| 246 | impl SealedChannel for AnyStaticChannel {} | 258 | impl SealedChannel for AnyStaticChannel { |
| 259 | #[cfg(feature = "_dppi")] | ||
| 260 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 261 | self.regs | ||
| 262 | } | ||
| 263 | } | ||
| 247 | impl Channel for AnyStaticChannel { | 264 | impl Channel for AnyStaticChannel { |
| 248 | fn number(&self) -> usize { | 265 | fn number(&self) -> usize { |
| 249 | self.number as usize | 266 | self.number as usize |
| @@ -255,9 +272,16 @@ impl StaticChannel for AnyStaticChannel {} | |||
| 255 | /// This can be used to have fewer generic parameters in some places. | 272 | /// This can be used to have fewer generic parameters in some places. |
| 256 | pub struct AnyConfigurableChannel { | 273 | pub struct AnyConfigurableChannel { |
| 257 | pub(crate) number: u8, | 274 | pub(crate) number: u8, |
| 275 | #[cfg(feature = "_dppi")] | ||
| 276 | pub(crate) regs: pac::dppic::Dppic, | ||
| 258 | } | 277 | } |
| 259 | impl_peripheral!(AnyConfigurableChannel); | 278 | impl_peripheral!(AnyConfigurableChannel); |
| 260 | impl SealedChannel for AnyConfigurableChannel {} | 279 | impl SealedChannel for AnyConfigurableChannel { |
| 280 | #[cfg(feature = "_dppi")] | ||
| 281 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 282 | self.regs | ||
| 283 | } | ||
| 284 | } | ||
| 261 | impl Channel for AnyConfigurableChannel { | 285 | impl Channel for AnyConfigurableChannel { |
| 262 | fn number(&self) -> usize { | 286 | fn number(&self) -> usize { |
| 263 | self.number as usize | 287 | self.number as usize |
| @@ -267,32 +291,41 @@ impl ConfigurableChannel for AnyConfigurableChannel {} | |||
| 267 | 291 | ||
| 268 | #[cfg(not(feature = "_nrf51"))] | 292 | #[cfg(not(feature = "_nrf51"))] |
| 269 | macro_rules! impl_ppi_channel { | 293 | macro_rules! impl_ppi_channel { |
| 270 | ($type:ident, $number:expr) => { | 294 | ($type:ident, $inst:ident, $number:expr) => { |
| 271 | impl crate::ppi::SealedChannel for peripherals::$type {} | 295 | impl crate::ppi::SealedChannel for peripherals::$type { |
| 296 | #[cfg(feature = "_dppi")] | ||
| 297 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 298 | pac::$inst | ||
| 299 | } | ||
| 300 | } | ||
| 272 | impl crate::ppi::Channel for peripherals::$type { | 301 | impl crate::ppi::Channel for peripherals::$type { |
| 273 | fn number(&self) -> usize { | 302 | fn number(&self) -> usize { |
| 274 | $number | 303 | $number |
| 275 | } | 304 | } |
| 276 | } | 305 | } |
| 277 | }; | 306 | }; |
| 278 | ($type:ident, $number:expr => static) => { | 307 | ($type:ident, $inst:ident, $number:expr => static) => { |
| 279 | impl_ppi_channel!($type, $number); | 308 | impl_ppi_channel!($type, $inst, $number); |
| 280 | impl crate::ppi::StaticChannel for peripherals::$type {} | 309 | impl crate::ppi::StaticChannel for peripherals::$type {} |
| 281 | impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { | 310 | impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { |
| 282 | fn from(val: peripherals::$type) -> Self { | 311 | fn from(val: peripherals::$type) -> Self { |
| 283 | Self { | 312 | Self { |
| 284 | number: crate::ppi::Channel::number(&val) as u8, | 313 | number: crate::ppi::Channel::number(&val) as u8, |
| 314 | #[cfg(feature = "_dppi")] | ||
| 315 | regs: pac::$inst, | ||
| 285 | } | 316 | } |
| 286 | } | 317 | } |
| 287 | } | 318 | } |
| 288 | }; | 319 | }; |
| 289 | ($type:ident, $number:expr => configurable) => { | 320 | ($type:ident, $inst:ident, $number:expr => configurable) => { |
| 290 | impl_ppi_channel!($type, $number); | 321 | impl_ppi_channel!($type, $inst, $number); |
| 291 | impl crate::ppi::ConfigurableChannel for peripherals::$type {} | 322 | impl crate::ppi::ConfigurableChannel for peripherals::$type {} |
| 292 | impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { | 323 | impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { |
| 293 | fn from(val: peripherals::$type) -> Self { | 324 | fn from(val: peripherals::$type) -> Self { |
| 294 | Self { | 325 | Self { |
| 295 | number: crate::ppi::Channel::number(&val) as u8, | 326 | number: crate::ppi::Channel::number(&val) as u8, |
| 327 | #[cfg(feature = "_dppi")] | ||
| 328 | regs: pac::$inst, | ||
| 296 | } | 329 | } |
| 297 | } | 330 | } |
| 298 | } | 331 | } |
| @@ -304,40 +337,54 @@ macro_rules! impl_ppi_channel { | |||
| 304 | 337 | ||
| 305 | /// A type erased PPI group. | 338 | /// A type erased PPI group. |
| 306 | pub struct AnyGroup { | 339 | pub struct AnyGroup { |
| 307 | number: u8, | 340 | pub(crate) number: u8, |
| 341 | #[cfg(feature = "_dppi")] | ||
| 342 | pub(crate) regs: pac::dppic::Dppic, | ||
| 343 | #[cfg(not(feature = "_dppi"))] | ||
| 344 | pub(crate) regs: pac::ppi::Ppi, | ||
| 308 | } | 345 | } |
| 309 | impl_peripheral!(AnyGroup); | 346 | impl_peripheral!(AnyGroup); |
| 310 | impl SealedGroup for AnyGroup {} | 347 | impl SealedGroup for AnyGroup { |
| 348 | #[cfg(feature = "_dppi")] | ||
| 349 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 350 | self.regs | ||
| 351 | } | ||
| 352 | #[cfg(not(feature = "_dppi"))] | ||
| 353 | fn regs(&self) -> pac::ppi::Ppi { | ||
| 354 | self.regs | ||
| 355 | } | ||
| 356 | } | ||
| 311 | impl Group for AnyGroup { | 357 | impl Group for AnyGroup { |
| 312 | fn number(&self) -> usize { | 358 | fn number(&self) -> usize { |
| 313 | self.number as usize | 359 | self.number as usize |
| 314 | } | 360 | } |
| 315 | } | 361 | } |
| 316 | 362 | ||
| 317 | macro_rules! impl_group { | 363 | macro_rules! impl_ppi_group { |
| 318 | ($type:ident, $number:expr) => { | 364 | ($type:ident, $inst:ident, $number:expr) => { |
| 319 | impl SealedGroup for peripherals::$type {} | 365 | impl crate::ppi::SealedGroup for crate::peripherals::$type { |
| 320 | impl Group for peripherals::$type { | 366 | #[cfg(feature = "_dppi")] |
| 367 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 368 | pac::$inst | ||
| 369 | } | ||
| 370 | #[cfg(not(feature = "_dppi"))] | ||
| 371 | fn regs(&self) -> pac::ppi::Ppi { | ||
| 372 | pac::$inst | ||
| 373 | } | ||
| 374 | } | ||
| 375 | impl crate::ppi::Group for crate::peripherals::$type { | ||
| 321 | fn number(&self) -> usize { | 376 | fn number(&self) -> usize { |
| 322 | $number | 377 | $number |
| 323 | } | 378 | } |
| 324 | } | 379 | } |
| 325 | 380 | ||
| 326 | impl From<peripherals::$type> for crate::ppi::AnyGroup { | 381 | impl From<crate::peripherals::$type> for crate::ppi::AnyGroup { |
| 327 | fn from(val: peripherals::$type) -> Self { | 382 | fn from(val: crate::peripherals::$type) -> Self { |
| 328 | Self { | 383 | Self { |
| 329 | number: crate::ppi::Group::number(&val) as u8, | 384 | number: crate::ppi::Group::number(&val) as u8, |
| 385 | regs: pac::$inst, | ||
| 330 | } | 386 | } |
| 331 | } | 387 | } |
| 332 | } | 388 | } |
| 333 | }; | 389 | }; |
| 334 | } | 390 | } |
| 335 | |||
| 336 | impl_group!(PPI_GROUP0, 0); | ||
| 337 | impl_group!(PPI_GROUP1, 1); | ||
| 338 | impl_group!(PPI_GROUP2, 2); | ||
| 339 | impl_group!(PPI_GROUP3, 3); | ||
| 340 | #[cfg(not(feature = "_nrf51"))] | ||
| 341 | impl_group!(PPI_GROUP4, 4); | ||
| 342 | #[cfg(not(feature = "_nrf51"))] | ||
| 343 | impl_group!(PPI_GROUP5, 5); | ||
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index 531c25444..18bc8b8db 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 2 | use crate::{pac, Peri}; | 2 | use crate::{Peri, pac}; |
| 3 | 3 | ||
| 4 | impl<'d> Task<'d> { | 4 | impl<'d> Task<'d> { |
| 5 | fn reg_val(&self) -> u32 { | 5 | fn reg_val(&self) -> u32 { |
