diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-05 20:50:45 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-03-06 00:17:51 +0100 |
| commit | f8f1d3bcf09045616f5b63a08a9623cd14acd045 (patch) | |
| tree | 4510489b071c37638f3f8805d0b3d4b5543d2696 | |
| parent | 34563b74aa48c53622344541153266b0227fc9bf (diff) | |
nrf/pdm: make available on all chips, use Instance trait, switch to new interrupt binding.
| -rw-r--r-- | embassy-nrf/src/chips/nrf52810.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52811.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52832.rs | 5 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52833.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52840.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf5340_app.rs | 7 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf9160.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/pdm.rs | 131 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/pdm.rs | 10 |
10 files changed, 116 insertions, 49 deletions
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 6b5c134b8..c6ccb6a0e 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -148,6 +148,8 @@ impl_twis!(TWI0, TWIS0, TWIM0_TWIS0_TWI0); | |||
| 148 | 148 | ||
| 149 | impl_pwm!(PWM0, PWM0, PWM0); | 149 | impl_pwm!(PWM0, PWM0, PWM0); |
| 150 | 150 | ||
| 151 | impl_pdm!(PDM, PDM, PDM); | ||
| 152 | |||
| 151 | impl_timer!(TIMER0, TIMER0, TIMER0); | 153 | impl_timer!(TIMER0, TIMER0, TIMER0); |
| 152 | impl_timer!(TIMER1, TIMER1, TIMER1); | 154 | impl_timer!(TIMER1, TIMER1, TIMER1); |
| 153 | impl_timer!(TIMER2, TIMER2, TIMER2); | 155 | impl_timer!(TIMER2, TIMER2, TIMER2); |
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index c5de9a447..7d1bce1c0 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -150,6 +150,8 @@ impl_twis!(TWISPI0, TWIS0, TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0); | |||
| 150 | 150 | ||
| 151 | impl_pwm!(PWM0, PWM0, PWM0); | 151 | impl_pwm!(PWM0, PWM0, PWM0); |
| 152 | 152 | ||
| 153 | impl_pdm!(PDM, PDM, PDM); | ||
| 154 | |||
| 153 | impl_timer!(TIMER0, TIMER0, TIMER0); | 155 | impl_timer!(TIMER0, TIMER0, TIMER0); |
| 154 | impl_timer!(TIMER1, TIMER1, TIMER1); | 156 | impl_timer!(TIMER1, TIMER1, TIMER1); |
| 155 | impl_timer!(TIMER2, TIMER2, TIMER2); | 157 | impl_timer!(TIMER2, TIMER2, TIMER2); |
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index c2b23fc5b..ce19a18e8 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -146,6 +146,9 @@ embassy_hal_common::peripherals! { | |||
| 146 | 146 | ||
| 147 | // I2S | 147 | // I2S |
| 148 | I2S, | 148 | I2S, |
| 149 | |||
| 150 | // PDM | ||
| 151 | PDM, | ||
| 149 | } | 152 | } |
| 150 | 153 | ||
| 151 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 154 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
| @@ -168,6 +171,8 @@ impl_pwm!(PWM0, PWM0, PWM0); | |||
| 168 | impl_pwm!(PWM1, PWM1, PWM1); | 171 | impl_pwm!(PWM1, PWM1, PWM1); |
| 169 | impl_pwm!(PWM2, PWM2, PWM2); | 172 | impl_pwm!(PWM2, PWM2, PWM2); |
| 170 | 173 | ||
| 174 | impl_pdm!(PDM, PDM, PDM); | ||
| 175 | |||
| 171 | impl_timer!(TIMER0, TIMER0, TIMER0); | 176 | impl_timer!(TIMER0, TIMER0, TIMER0); |
| 172 | impl_timer!(TIMER1, TIMER1, TIMER1); | 177 | impl_timer!(TIMER1, TIMER1, TIMER1); |
| 173 | impl_timer!(TIMER2, TIMER2, TIMER2); | 178 | impl_timer!(TIMER2, TIMER2, TIMER2); |
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 95f71ade7..08b82021d 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -197,6 +197,8 @@ impl_pwm!(PWM1, PWM1, PWM1); | |||
| 197 | impl_pwm!(PWM2, PWM2, PWM2); | 197 | impl_pwm!(PWM2, PWM2, PWM2); |
| 198 | impl_pwm!(PWM3, PWM3, PWM3); | 198 | impl_pwm!(PWM3, PWM3, PWM3); |
| 199 | 199 | ||
| 200 | impl_pdm!(PDM, PDM, PDM); | ||
| 201 | |||
| 200 | impl_timer!(TIMER0, TIMER0, TIMER0); | 202 | impl_timer!(TIMER0, TIMER0, TIMER0); |
| 201 | impl_timer!(TIMER1, TIMER1, TIMER1); | 203 | impl_timer!(TIMER1, TIMER1, TIMER1); |
| 202 | impl_timer!(TIMER2, TIMER2, TIMER2); | 204 | impl_timer!(TIMER2, TIMER2, TIMER2); |
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 5e7479e88..4e8b6d9ee 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -208,6 +208,8 @@ impl_timer!(TIMER4, TIMER4, TIMER4, extended); | |||
| 208 | 208 | ||
| 209 | impl_qspi!(QSPI, QSPI, QSPI); | 209 | impl_qspi!(QSPI, QSPI, QSPI); |
| 210 | 210 | ||
| 211 | impl_pdm!(PDM, PDM, PDM); | ||
| 212 | |||
| 211 | impl_pin!(P0_00, 0, 0); | 213 | impl_pin!(P0_00, 0, 0); |
| 212 | impl_pin!(P0_01, 0, 1); | 214 | impl_pin!(P0_01, 0, 1); |
| 213 | impl_pin!(P0_02, 0, 2); | 215 | impl_pin!(P0_02, 0, 2); |
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index 9c7b738e6..050612b1c 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs | |||
| @@ -34,7 +34,7 @@ pub mod pac { | |||
| 34 | nvmc_ns as nvmc, | 34 | nvmc_ns as nvmc, |
| 35 | oscillators_ns as oscillators, | 35 | oscillators_ns as oscillators, |
| 36 | p0_ns as p0, | 36 | p0_ns as p0, |
| 37 | pdm0_ns as pdm0, | 37 | pdm0_ns as pdm, |
| 38 | power_ns as power, | 38 | power_ns as power, |
| 39 | pwm0_ns as pwm0, | 39 | pwm0_ns as pwm0, |
| 40 | qdec0_ns as qdec0, | 40 | qdec0_ns as qdec0, |
| @@ -253,6 +253,9 @@ embassy_hal_common::peripherals! { | |||
| 253 | // QSPI | 253 | // QSPI |
| 254 | QSPI, | 254 | QSPI, |
| 255 | 255 | ||
| 256 | // PDM | ||
| 257 | PDM0, | ||
| 258 | |||
| 256 | // GPIOTE | 259 | // GPIOTE |
| 257 | GPIOTE_CH0, | 260 | GPIOTE_CH0, |
| 258 | GPIOTE_CH1, | 261 | GPIOTE_CH1, |
| @@ -398,6 +401,8 @@ impl_timer!(TIMER2, TIMER2, TIMER2); | |||
| 398 | 401 | ||
| 399 | impl_qspi!(QSPI, QSPI, QSPI); | 402 | impl_qspi!(QSPI, QSPI, QSPI); |
| 400 | 403 | ||
| 404 | impl_pdm!(PDM0, PDM0, PDM0); | ||
| 405 | |||
| 401 | impl_pin!(P0_00, 0, 0); | 406 | impl_pin!(P0_00, 0, 0); |
| 402 | impl_pin!(P0_01, 0, 1); | 407 | impl_pin!(P0_01, 0, 1); |
| 403 | #[cfg(feature = "nfc-pins-as-gpio")] | 408 | #[cfg(feature = "nfc-pins-as-gpio")] |
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 385bd133d..d2b45114f 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs | |||
| @@ -301,6 +301,8 @@ impl_pwm!(PWM1, PWM1, PWM1); | |||
| 301 | impl_pwm!(PWM2, PWM2, PWM2); | 301 | impl_pwm!(PWM2, PWM2, PWM2); |
| 302 | impl_pwm!(PWM3, PWM3, PWM3); | 302 | impl_pwm!(PWM3, PWM3, PWM3); |
| 303 | 303 | ||
| 304 | impl_pdm!(PDM, PDM, PDM); | ||
| 305 | |||
| 304 | impl_timer!(TIMER0, TIMER0, TIMER0); | 306 | impl_timer!(TIMER0, TIMER0, TIMER0); |
| 305 | impl_timer!(TIMER1, TIMER1, TIMER1); | 307 | impl_timer!(TIMER1, TIMER1, TIMER1); |
| 306 | impl_timer!(TIMER2, TIMER2, TIMER2); | 308 | impl_timer!(TIMER2, TIMER2, TIMER2); |
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 446b1f41a..17aa5ad15 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -47,8 +47,10 @@ pub mod nvmc; | |||
| 47 | #[cfg(any( | 47 | #[cfg(any( |
| 48 | feature = "nrf52810", | 48 | feature = "nrf52810", |
| 49 | feature = "nrf52811", | 49 | feature = "nrf52811", |
| 50 | feature = "nrf52832", | ||
| 50 | feature = "nrf52833", | 51 | feature = "nrf52833", |
| 51 | feature = "nrf52840", | 52 | feature = "nrf52840", |
| 53 | feature = "_nrf5340-app", | ||
| 52 | feature = "_nrf9160" | 54 | feature = "_nrf9160" |
| 53 | ))] | 55 | ))] |
| 54 | pub mod pdm; | 56 | pub mod pdm; |
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index 54feca4c1..8815bb316 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs | |||
| @@ -1,25 +1,37 @@ | |||
| 1 | //! Pulse Density Modulation (PDM) mirophone driver. | 1 | //! Pulse Density Modulation (PDM) mirophone driver. |
| 2 | 2 | ||
| 3 | #![macro_use] | ||
| 4 | |||
| 3 | use core::marker::PhantomData; | 5 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 5 | use core::task::Poll; | 7 | use core::task::Poll; |
| 6 | 8 | ||
| 9 | use embassy_cortex_m::interrupt::Interrupt; | ||
| 7 | use embassy_hal_common::drop::OnDrop; | 10 | use embassy_hal_common::drop::OnDrop; |
| 8 | use embassy_hal_common::{into_ref, PeripheralRef}; | 11 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 10 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 11 | 13 | ||
| 12 | use crate::chip::EASY_DMA_SIZE; | 14 | use crate::chip::EASY_DMA_SIZE; |
| 13 | use crate::gpio::sealed::Pin; | 15 | use crate::gpio::sealed::Pin; |
| 14 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 16 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 15 | use crate::interrupt::{self, InterruptExt}; | 17 | use crate::interrupt::{self, InterruptExt}; |
| 16 | use crate::peripherals::PDM; | 18 | use crate::Peripheral; |
| 17 | use crate::{pac, Peripheral}; | 19 | |
| 20 | /// Interrupt handler. | ||
| 21 | pub struct InterruptHandler<T: Instance> { | ||
| 22 | _phantom: PhantomData<T>, | ||
| 23 | } | ||
| 24 | |||
| 25 | impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { | ||
| 26 | unsafe fn on_interrupt() { | ||
| 27 | T::regs().intenclr.write(|w| w.end().clear()); | ||
| 28 | T::state().waker.wake(); | ||
| 29 | } | ||
| 30 | } | ||
| 18 | 31 | ||
| 19 | /// PDM microphone interface | 32 | /// PDM microphone interface |
| 20 | pub struct Pdm<'d> { | 33 | pub struct Pdm<'d, T: Instance> { |
| 21 | irq: PeripheralRef<'d, interrupt::PDM>, | 34 | _peri: PeripheralRef<'d, T>, |
| 22 | phantom: PhantomData<&'d PDM>, | ||
| 23 | } | 35 | } |
| 24 | 36 | ||
| 25 | /// PDM error. | 37 | /// PDM error. |
| @@ -35,32 +47,30 @@ pub enum Error { | |||
| 35 | NotRunning, | 47 | NotRunning, |
| 36 | } | 48 | } |
| 37 | 49 | ||
| 38 | static WAKER: AtomicWaker = AtomicWaker::new(); | ||
| 39 | static DUMMY_BUFFER: [i16; 1] = [0; 1]; | 50 | static DUMMY_BUFFER: [i16; 1] = [0; 1]; |
| 40 | 51 | ||
| 41 | impl<'d> Pdm<'d> { | 52 | impl<'d, T: Instance> Pdm<'d, T> { |
| 42 | /// Create PDM driver | 53 | /// Create PDM driver |
| 43 | pub fn new( | 54 | pub fn new( |
| 44 | pdm: impl Peripheral<P = PDM> + 'd, | 55 | pdm: impl Peripheral<P = T> + 'd, |
| 45 | irq: impl Peripheral<P = interrupt::PDM> + 'd, | 56 | _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 46 | clk: impl Peripheral<P = impl GpioPin> + 'd, | 57 | clk: impl Peripheral<P = impl GpioPin> + 'd, |
| 47 | din: impl Peripheral<P = impl GpioPin> + 'd, | 58 | din: impl Peripheral<P = impl GpioPin> + 'd, |
| 48 | config: Config, | 59 | config: Config, |
| 49 | ) -> Self { | 60 | ) -> Self { |
| 50 | into_ref!(clk, din); | 61 | into_ref!(pdm, clk, din); |
| 51 | Self::new_inner(pdm, irq, clk.map_into(), din.map_into(), config) | 62 | Self::new_inner(pdm, clk.map_into(), din.map_into(), config) |
| 52 | } | 63 | } |
| 53 | 64 | ||
| 54 | fn new_inner( | 65 | fn new_inner( |
| 55 | _pdm: impl Peripheral<P = PDM> + 'd, | 66 | pdm: PeripheralRef<'d, T>, |
| 56 | irq: impl Peripheral<P = interrupt::PDM> + 'd, | ||
| 57 | clk: PeripheralRef<'d, AnyPin>, | 67 | clk: PeripheralRef<'d, AnyPin>, |
| 58 | din: PeripheralRef<'d, AnyPin>, | 68 | din: PeripheralRef<'d, AnyPin>, |
| 59 | config: Config, | 69 | config: Config, |
| 60 | ) -> Self { | 70 | ) -> Self { |
| 61 | into_ref!(irq); | 71 | into_ref!(pdm); |
| 62 | 72 | ||
| 63 | let r = Self::regs(); | 73 | let r = T::regs(); |
| 64 | 74 | ||
| 65 | // setup gpio pins | 75 | // setup gpio pins |
| 66 | din.conf().write(|w| w.input().set_bit()); | 76 | din.conf().write(|w| w.input().set_bit()); |
| @@ -84,26 +94,18 @@ impl<'d> Pdm<'d> { | |||
| 84 | r.gainr.write(|w| w.gainr().default_gain()); | 94 | r.gainr.write(|w| w.gainr().default_gain()); |
| 85 | 95 | ||
| 86 | // IRQ | 96 | // IRQ |
| 87 | irq.disable(); | 97 | unsafe { T::Interrupt::steal() }.unpend(); |
| 88 | irq.set_handler(|_| { | 98 | unsafe { T::Interrupt::steal() }.enable(); |
| 89 | let r = Self::regs(); | ||
| 90 | r.intenclr.write(|w| w.end().clear()); | ||
| 91 | WAKER.wake(); | ||
| 92 | }); | ||
| 93 | irq.enable(); | ||
| 94 | 99 | ||
| 95 | r.enable.write(|w| w.enable().set_bit()); | 100 | r.enable.write(|w| w.enable().set_bit()); |
| 96 | 101 | ||
| 97 | Self { | 102 | Self { _peri: pdm } |
| 98 | phantom: PhantomData, | ||
| 99 | irq, | ||
| 100 | } | ||
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | /// Start sampling microphon data into a dummy buffer | 105 | /// Start sampling microphon data into a dummy buffer |
| 104 | /// Usefull to start the microphon and keep it active between recording samples | 106 | /// Usefull to start the microphon and keep it active between recording samples |
| 105 | pub async fn start(&mut self) { | 107 | pub async fn start(&mut self) { |
| 106 | let r = Self::regs(); | 108 | let r = T::regs(); |
| 107 | 109 | ||
| 108 | // start dummy sampling because microphon needs some setup time | 110 | // start dummy sampling because microphon needs some setup time |
| 109 | r.sample | 111 | r.sample |
| @@ -113,13 +115,13 @@ impl<'d> Pdm<'d> { | |||
| 113 | .maxcnt | 115 | .maxcnt |
| 114 | .write(|w| unsafe { w.buffsize().bits(DUMMY_BUFFER.len() as _) }); | 116 | .write(|w| unsafe { w.buffsize().bits(DUMMY_BUFFER.len() as _) }); |
| 115 | 117 | ||
| 116 | r.tasks_start.write(|w| w.tasks_start().set_bit()); | 118 | r.tasks_start.write(|w| unsafe { w.bits(1) }); |
| 117 | } | 119 | } |
| 118 | 120 | ||
| 119 | /// Stop sampling microphon data inta a dummy buffer | 121 | /// Stop sampling microphon data inta a dummy buffer |
| 120 | pub async fn stop(&mut self) { | 122 | pub async fn stop(&mut self) { |
| 121 | let r = Self::regs(); | 123 | let r = T::regs(); |
| 122 | r.tasks_stop.write(|w| w.tasks_stop().set_bit()); | 124 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); |
| 123 | r.events_started.reset(); | 125 | r.events_started.reset(); |
| 124 | } | 126 | } |
| 125 | 127 | ||
| @@ -132,9 +134,9 @@ impl<'d> Pdm<'d> { | |||
| 132 | return Err(Error::BufferTooLong); | 134 | return Err(Error::BufferTooLong); |
| 133 | } | 135 | } |
| 134 | 136 | ||
| 135 | let r = Self::regs(); | 137 | let r = T::regs(); |
| 136 | 138 | ||
| 137 | if r.events_started.read().events_started().bit_is_clear() { | 139 | if r.events_started.read().bits() == 0 { |
| 138 | return Err(Error::NotRunning); | 140 | return Err(Error::NotRunning); |
| 139 | } | 141 | } |
| 140 | 142 | ||
| @@ -179,7 +181,7 @@ impl<'d> Pdm<'d> { | |||
| 179 | } | 181 | } |
| 180 | 182 | ||
| 181 | async fn wait_for_sample() { | 183 | async fn wait_for_sample() { |
| 182 | let r = Self::regs(); | 184 | let r = T::regs(); |
| 183 | 185 | ||
| 184 | r.events_end.reset(); | 186 | r.events_end.reset(); |
| 185 | r.intenset.write(|w| w.end().set()); | 187 | r.intenset.write(|w| w.end().set()); |
| @@ -187,8 +189,8 @@ impl<'d> Pdm<'d> { | |||
| 187 | compiler_fence(Ordering::SeqCst); | 189 | compiler_fence(Ordering::SeqCst); |
| 188 | 190 | ||
| 189 | poll_fn(|cx| { | 191 | poll_fn(|cx| { |
| 190 | WAKER.register(cx.waker()); | 192 | T::state().waker.register(cx.waker()); |
| 191 | if r.events_end.read().events_end().bit_is_set() { | 193 | if r.events_end.read().bits() != 0 { |
| 192 | return Poll::Ready(()); | 194 | return Poll::Ready(()); |
| 193 | } | 195 | } |
| 194 | Poll::Pending | 196 | Poll::Pending |
| @@ -197,10 +199,6 @@ impl<'d> Pdm<'d> { | |||
| 197 | 199 | ||
| 198 | compiler_fence(Ordering::SeqCst); | 200 | compiler_fence(Ordering::SeqCst); |
| 199 | } | 201 | } |
| 200 | |||
| 201 | fn regs() -> &'static pac::pdm::RegisterBlock { | ||
| 202 | unsafe { &*pac::PDM::ptr() } | ||
| 203 | } | ||
| 204 | } | 202 | } |
| 205 | 203 | ||
| 206 | /// PDM microphone driver Config | 204 | /// PDM microphone driver Config |
| @@ -238,13 +236,11 @@ pub enum Edge { | |||
| 238 | LeftFalling, | 236 | LeftFalling, |
| 239 | } | 237 | } |
| 240 | 238 | ||
| 241 | impl<'d> Drop for Pdm<'d> { | 239 | impl<'d, T: Instance> Drop for Pdm<'d, T> { |
| 242 | fn drop(&mut self) { | 240 | fn drop(&mut self) { |
| 243 | let r = Self::regs(); | 241 | let r = T::regs(); |
| 244 | 242 | ||
| 245 | r.tasks_stop.write(|w| w.tasks_stop().set_bit()); | 243 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); |
| 246 | |||
| 247 | self.irq.disable(); | ||
| 248 | 244 | ||
| 249 | r.enable.write(|w| w.enable().disabled()); | 245 | r.enable.write(|w| w.enable().disabled()); |
| 250 | 246 | ||
| @@ -252,3 +248,48 @@ impl<'d> Drop for Pdm<'d> { | |||
| 252 | r.psel.clk.reset(); | 248 | r.psel.clk.reset(); |
| 253 | } | 249 | } |
| 254 | } | 250 | } |
| 251 | |||
| 252 | pub(crate) mod sealed { | ||
| 253 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 254 | |||
| 255 | /// Peripheral static state | ||
| 256 | pub struct State { | ||
| 257 | pub waker: AtomicWaker, | ||
| 258 | } | ||
| 259 | |||
| 260 | impl State { | ||
| 261 | pub const fn new() -> Self { | ||
| 262 | Self { | ||
| 263 | waker: AtomicWaker::new(), | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 268 | pub trait Instance { | ||
| 269 | fn regs() -> &'static crate::pac::pdm::RegisterBlock; | ||
| 270 | fn state() -> &'static State; | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | /// PDM peripheral instance. | ||
| 275 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { | ||
| 276 | /// Interrupt for this peripheral. | ||
| 277 | type Interrupt: Interrupt; | ||
| 278 | } | ||
| 279 | |||
| 280 | macro_rules! impl_pdm { | ||
| 281 | ($type:ident, $pac_type:ident, $irq:ident) => { | ||
| 282 | impl crate::pdm::sealed::Instance for peripherals::$type { | ||
| 283 | fn regs() -> &'static crate::pac::pdm::RegisterBlock { | ||
| 284 | unsafe { &*pac::$pac_type::ptr() } | ||
| 285 | } | ||
| 286 | fn state() -> &'static crate::pdm::sealed::State { | ||
| 287 | static STATE: crate::pdm::sealed::State = crate::pdm::sealed::State::new(); | ||
| 288 | &STATE | ||
| 289 | } | ||
| 290 | } | ||
| 291 | impl crate::pdm::Instance for peripherals::$type { | ||
| 292 | type Interrupt = crate::interrupt::$irq; | ||
| 293 | } | ||
| 294 | }; | ||
| 295 | } | ||
diff --git a/examples/nrf52840/src/bin/pdm.rs b/examples/nrf52840/src/bin/pdm.rs index 7388580fb..6b41320ca 100644 --- a/examples/nrf52840/src/bin/pdm.rs +++ b/examples/nrf52840/src/bin/pdm.rs | |||
| @@ -4,16 +4,20 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::info; | 5 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::interrupt; | 7 | use embassy_nrf::pdm::{self, Config, Pdm}; |
| 8 | use embassy_nrf::pdm::{Config, Pdm}; | 8 | use embassy_nrf::{bind_interrupts, peripherals}; |
| 9 | use embassy_time::{Duration, Timer}; | 9 | use embassy_time::{Duration, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | PDM => pdm::InterruptHandler<peripherals::PDM>; | ||
| 14 | }); | ||
| 15 | |||
| 12 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 13 | async fn main(_p: Spawner) { | 17 | async fn main(_p: Spawner) { |
| 14 | let p = embassy_nrf::init(Default::default()); | 18 | let p = embassy_nrf::init(Default::default()); |
| 15 | let config = Config::default(); | 19 | let config = Config::default(); |
| 16 | let mut pdm = Pdm::new(p.PDM, interrupt::take!(PDM), p.P0_01, p.P0_00, config); | 20 | let mut pdm = Pdm::new(p.PDM, Irqs, p.P0_01, p.P0_00, config); |
| 17 | 21 | ||
| 18 | loop { | 22 | loop { |
| 19 | pdm.start().await; | 23 | pdm.start().await; |
