aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Smith <[email protected]>2023-07-18 17:17:04 -0400
committerQuentin Smith <[email protected]>2023-07-18 17:17:04 -0400
commit2c01f277c27bc6ca4f3d41ac57aa1ea24868cfc1 (patch)
treeb5a407f457472fc70dafc3ced5e0744f25443f35
parentc333d855fca0743de1d58ef14e3c2f6389f73145 (diff)
cargo fmt
-rw-r--r--embassy-nrf/src/pdm.rs26
-rw-r--r--examples/nrf52840/src/bin/pdm.rs8
-rw-r--r--examples/nrf52840/src/bin/pdm_continuous.rs65
3 files changed, 56 insertions, 43 deletions
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs
index f2675bb7a..48668c7f4 100644
--- a/embassy-nrf/src/pdm.rs
+++ b/embassy-nrf/src/pdm.rs
@@ -8,17 +8,17 @@ use core::task::Poll;
8 8
9use embassy_hal_common::drop::OnDrop; 9use embassy_hal_common::drop::OnDrop;
10use embassy_hal_common::{into_ref, PeripheralRef}; 10use embassy_hal_common::{into_ref, PeripheralRef};
11use futures::future::poll_fn;
12use fixed::types::I7F1; 11use fixed::types::I7F1;
12use futures::future::poll_fn;
13 13
14use crate::chip::EASY_DMA_SIZE; 14use crate::chip::EASY_DMA_SIZE;
15use crate::gpio::sealed::Pin; 15use crate::gpio::sealed::Pin;
16use crate::gpio::{AnyPin, Pin as GpioPin}; 16use crate::gpio::{AnyPin, Pin as GpioPin};
17use crate::interrupt::typelevel::Interrupt; 17use crate::interrupt::typelevel::Interrupt;
18use crate::{interrupt, Peripheral};
19use crate::pac::pdm::mode::{EDGE_A, OPERATION_A}; 18use crate::pac::pdm::mode::{EDGE_A, OPERATION_A};
20pub use crate::pac::pdm::pdmclkctrl::FREQ_A as Frequency; 19pub use crate::pac::pdm::pdmclkctrl::FREQ_A as Frequency;
21pub use crate::pac::pdm::ratio::RATIO_A as Ratio; 20pub use crate::pac::pdm::ratio::RATIO_A as Ratio;
21use crate::{interrupt, Peripheral};
22 22
23/// Interrupt handler. 23/// Interrupt handler.
24pub struct InterruptHandler<T: Instance> { 24pub struct InterruptHandler<T: Instance> {
@@ -133,8 +133,14 @@ impl<'d, T: Instance> Pdm<'d, T> {
133 } 133 }
134 134
135 fn _set_gain(r: &crate::pac::pdm::RegisterBlock, gain_left: I7F1, gain_right: I7F1) { 135 fn _set_gain(r: &crate::pac::pdm::RegisterBlock, gain_left: I7F1, gain_right: I7F1) {
136 let gain_left = gain_left.saturating_add(I7F1::from_bits(40)).saturating_to_num::<u8>().clamp(0, 0x50); 136 let gain_left = gain_left
137 let gain_right = gain_right.saturating_add(I7F1::from_bits(40)).saturating_to_num::<u8>().clamp(0, 0x50); 137 .saturating_add(I7F1::from_bits(40))
138 .saturating_to_num::<u8>()
139 .clamp(0, 0x50);
140 let gain_right = gain_right
141 .saturating_add(I7F1::from_bits(40))
142 .saturating_to_num::<u8>()
143 .clamp(0, 0x50);
138 144
139 r.gainl.write(|w| unsafe { w.gainl().bits(gain_left) }); 145 r.gainl.write(|w| unsafe { w.gainl().bits(gain_left) });
140 r.gainr.write(|w| unsafe { w.gainr().bits(gain_right) }); 146 r.gainr.write(|w| unsafe { w.gainr().bits(gain_right) });
@@ -258,7 +264,8 @@ impl<'d, T: Instance> Pdm<'d, T> {
258 &mut self, 264 &mut self,
259 bufs: &mut [[i16; N]; 2], 265 bufs: &mut [[i16; N]; 2],
260 mut sampler: S, 266 mut sampler: S,
261 ) -> Result<(), Error> where 267 ) -> Result<(), Error>
268 where
262 S: FnMut(&[i16; N]) -> SamplerState, 269 S: FnMut(&[i16; N]) -> SamplerState,
263 { 270 {
264 let r = T::regs(); 271 let r = T::regs();
@@ -267,7 +274,9 @@ impl<'d, T: Instance> Pdm<'d, T> {
267 return Err(Error::AlreadyRunning); 274 return Err(Error::AlreadyRunning);
268 } 275 }
269 276
270 r.sample.ptr.write(|w| unsafe { w.sampleptr().bits(bufs[0].as_mut_ptr() as u32) }); 277 r.sample
278 .ptr
279 .write(|w| unsafe { w.sampleptr().bits(bufs[0].as_mut_ptr() as u32) });
271 r.sample.maxcnt.write(|w| unsafe { w.buffsize().bits(N as _) }); 280 r.sample.maxcnt.write(|w| unsafe { w.buffsize().bits(N as _) });
272 281
273 // Reset and enable the events 282 // Reset and enable the events
@@ -285,7 +294,7 @@ impl<'d, T: Instance> Pdm<'d, T> {
285 // wouldn't happen anyway. 294 // wouldn't happen anyway.
286 compiler_fence(Ordering::SeqCst); 295 compiler_fence(Ordering::SeqCst);
287 296
288 r.tasks_start.write(|w| { w.tasks_start().set_bit() }); 297 r.tasks_start.write(|w| w.tasks_start().set_bit());
289 298
290 let mut current_buffer = 0; 299 let mut current_buffer = 0;
291 300
@@ -309,7 +318,8 @@ impl<'d, T: Instance> Pdm<'d, T> {
309 r.events_end.reset(); 318 r.events_end.reset();
310 r.intenset.write(|w| w.end().set()); 319 r.intenset.write(|w| w.end().set());
311 320
312 if !done { // Discard the last buffer after the user requested a stop. 321 if !done {
322 // Discard the last buffer after the user requested a stop.
313 if sampler(&bufs[current_buffer]) == SamplerState::Sampled { 323 if sampler(&bufs[current_buffer]) == SamplerState::Sampled {
314 let next_buffer = 1 - current_buffer; 324 let next_buffer = 1 - current_buffer;
315 current_buffer = next_buffer; 325 current_buffer = next_buffer;
diff --git a/examples/nrf52840/src/bin/pdm.rs b/examples/nrf52840/src/bin/pdm.rs
index 47fe67733..444b9137f 100644
--- a/examples/nrf52840/src/bin/pdm.rs
+++ b/examples/nrf52840/src/bin/pdm.rs
@@ -41,9 +41,11 @@ async fn main(_p: Spawner) {
41 buf.iter().min().unwrap(), 41 buf.iter().min().unwrap(),
42 buf.iter().max().unwrap(), 42 buf.iter().max().unwrap(),
43 mean, 43 mean,
44 ( 44 (buf.iter()
45 buf.iter().map(|v| i32::from(*v - mean).pow(2)).fold(0i32, |a,b| a.saturating_add(b)) 45 .map(|v| i32::from(*v - mean).pow(2))
46 / buf.len() as i32).sqrt() as i16, 46 .fold(0i32, |a, b| a.saturating_add(b))
47 / buf.len() as i32)
48 .sqrt() as i16,
47 ); 49 );
48 50
49 info!("samples: {:?}", &buf); 51 info!("samples: {:?}", &buf);
diff --git a/examples/nrf52840/src/bin/pdm_continuous.rs b/examples/nrf52840/src/bin/pdm_continuous.rs
index 9eaf30717..7d8531475 100644
--- a/examples/nrf52840/src/bin/pdm_continuous.rs
+++ b/examples/nrf52840/src/bin/pdm_continuous.rs
@@ -2,14 +2,15 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use defmt::info;
6use core::cmp::Ordering; 5use core::cmp::Ordering;
6
7use defmt::info;
7use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_nrf::pdm::{self, Config, Frequency, OperationMode, Pdm, Ratio, SamplerState};
8use embassy_nrf::{bind_interrupts, peripherals}; 10use embassy_nrf::{bind_interrupts, peripherals};
9use embassy_nrf::pdm::{self, Config, OperationMode, Pdm, SamplerState, Frequency, Ratio};
10use fixed::types::I7F1; 11use fixed::types::I7F1;
11use num_integer::Roots;
12use microfft::real::rfft_1024; 12use microfft::real::rfft_1024;
13use num_integer::Roots;
13use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
14 15
15// Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer 16// Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer
@@ -31,34 +32,34 @@ async fn main(_p: Spawner) {
31 32
32 let mut bufs = [[0; 1024]; 2]; 33 let mut bufs = [[0; 1024]; 2];
33 34
34 pdm 35 pdm.run_task_sampler(&mut bufs, move |buf| {
35 .run_task_sampler( 36 // NOTE: It is important that the time spent within this callback
36 &mut bufs, 37 // does not exceed the time taken to acquire the 1500 samples we
37 move |buf| { 38 // have in this example, which would be 10us + 2us per
38 // NOTE: It is important that the time spent within this callback 39 // sample * 1500 = 18ms. You need to measure the time taken here
39 // does not exceed the time taken to acquire the 1500 samples we 40 // and set the sample buffer size accordingly. Exceeding this
40 // have in this example, which would be 10us + 2us per 41 // time can lead to the peripheral re-writing the other buffer.
41 // sample * 1500 = 18ms. You need to measure the time taken here 42 let mean = (buf.iter().map(|v| i32::from(*v)).sum::<i32>() / buf.len() as i32) as i16;
42 // and set the sample buffer size accordingly. Exceeding this 43 let (peak_freq_index, peak_mag) = fft_peak_freq(&buf);
43 // time can lead to the peripheral re-writing the other buffer. 44 let peak_freq = peak_freq_index * 16000 / buf.len();
44 let mean = (buf.iter().map(|v| i32::from(*v)).sum::<i32>() / buf.len() as i32) as i16; 45 info!(
45 let (peak_freq_index, peak_mag) = fft_peak_freq(&buf); 46 "{} samples, min {=i16}, max {=i16}, mean {=i16}, AC RMS {=i16}, peak {} @ {} Hz",
46 let peak_freq = peak_freq_index * 16000 / buf.len(); 47 buf.len(),
47 info!( 48 buf.iter().min().unwrap(),
48 "{} samples, min {=i16}, max {=i16}, mean {=i16}, AC RMS {=i16}, peak {} @ {} Hz", 49 buf.iter().max().unwrap(),
49 buf.len(), 50 mean,
50 buf.iter().min().unwrap(), 51 (buf.iter()
51 buf.iter().max().unwrap(), 52 .map(|v| i32::from(*v - mean).pow(2))
52 mean, 53 .fold(0i32, |a, b| a.saturating_add(b))
53 ( 54 / buf.len() as i32)
54 buf.iter().map(|v| i32::from(*v - mean).pow(2)).fold(0i32, |a,b| a.saturating_add(b)) 55 .sqrt() as i16,
55 / buf.len() as i32).sqrt() as i16, 56 peak_mag,
56 peak_mag, peak_freq, 57 peak_freq,
57 ); 58 );
58 SamplerState::Sampled 59 SamplerState::Sampled
59 }, 60 })
60 ) 61 .await
61 .await.unwrap(); 62 .unwrap();
62} 63}
63 64
64fn fft_peak_freq(input: &[i16; 1024]) -> (usize, u32) { 65fn fft_peak_freq(input: &[i16; 1024]) -> (usize, u32) {
@@ -75,6 +76,6 @@ fn fft_peak_freq(input: &[i16; 1024]) -> (usize, u32) {
75 .map(|c| c.norm_sqr()) 76 .map(|c| c.norm_sqr())
76 .enumerate() 77 .enumerate()
77 .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap_or(Ordering::Equal)) 78 .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap_or(Ordering::Equal))
78 .map(|(i, v)| (i, ((v*32768.0) as u32).sqrt())) 79 .map(|(i, v)| (i, ((v * 32768.0) as u32).sqrt()))
79 .unwrap() 80 .unwrap()
80} 81}