diff options
| author | Michael Kefeder <[email protected]> | 2025-09-28 18:32:40 +0200 |
|---|---|---|
| committer | Michael Kefeder <[email protected]> | 2025-09-29 21:24:34 +0200 |
| commit | 8fae6f5a3f7055dc8250cd8926624010b14db6dc (patch) | |
| tree | 8efee5340798565cf5a0e13293e1766f5156c6d9 /examples/nrf52810/src | |
| parent | b29c7295e406045ec137b78ca5f220bf7909006b (diff) | |
Reset SAADC in Drop impl for nrf52, workaround for anomaly 241.
Diffstat (limited to 'examples/nrf52810/src')
| -rw-r--r-- | examples/nrf52810/src/bin/saadc_lowpower.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/examples/nrf52810/src/bin/saadc_lowpower.rs b/examples/nrf52810/src/bin/saadc_lowpower.rs new file mode 100644 index 000000000..d7e7f09a4 --- /dev/null +++ b/examples/nrf52810/src/bin/saadc_lowpower.rs | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | //! Run SAADC on multiple pins only every 3rd time, to show anomaly 241 workaround. | ||
| 2 | //! | ||
| 3 | //! To correctly measure the MCU current on the NRF52DK follow the instructions | ||
| 4 | //! <https://docs.nordicsemi.com/bundle/ug_nrf52832_dk/page/UG/dk/prepare_board.html> | ||
| 5 | //! otherwise you will measure the whole board, including the segger j-link chip for example | ||
| 6 | |||
| 7 | #![no_std] | ||
| 8 | #![no_main] | ||
| 9 | |||
| 10 | use defmt::info; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 13 | use embassy_nrf::saadc::{Oversample, Saadc}; | ||
| 14 | use embassy_nrf::{bind_interrupts, saadc}; | ||
| 15 | use embassy_time::Timer; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | SAADC => saadc::InterruptHandler; | ||
| 20 | }); | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async fn main(_p: Spawner) { | ||
| 24 | let mut p = embassy_nrf::init(Default::default()); | ||
| 25 | |||
| 26 | // For PPK2 digital channel plot to track when SAADC is on/off. | ||
| 27 | let mut ppk2_d0 = Output::new(p.P0_27, Level::Low, OutputDrive::Standard); | ||
| 28 | let mut num_loops: usize = 0; | ||
| 29 | loop { | ||
| 30 | num_loops += 1; | ||
| 31 | if num_loops.is_multiple_of(3) { | ||
| 32 | ppk2_d0.set_high(); | ||
| 33 | let battery_pin = p.P0_02.reborrow(); | ||
| 34 | let sensor1_pin = p.P0_03.reborrow(); | ||
| 35 | let mut adc_config = saadc::Config::default(); | ||
| 36 | adc_config.oversample = Oversample::OVER4X; | ||
| 37 | let battery = saadc::ChannelConfig::single_ended(battery_pin); | ||
| 38 | let sensor1 = saadc::ChannelConfig::single_ended(sensor1_pin); | ||
| 39 | let mut saadc = Saadc::new(p.SAADC.reborrow(), Irqs, adc_config, [battery, sensor1]); | ||
| 40 | // Indicated: wait for ADC calibration. | ||
| 41 | saadc.calibrate().await; | ||
| 42 | let mut buf = [0; 2]; | ||
| 43 | info!("sampling..."); | ||
| 44 | saadc.sample(&mut buf).await; | ||
| 45 | info!("data: {:x}", buf); | ||
| 46 | |||
| 47 | // Sleep to show the high power usage on the plot, even though sampling is done. | ||
| 48 | Timer::after_millis(100).await; | ||
| 49 | ppk2_d0.set_low(); | ||
| 50 | // disable the following line to show the anomaly on the power profiler plot. | ||
| 51 | core::mem::drop(saadc); | ||
| 52 | // Sleep to show the power usage when drop did not happen. | ||
| 53 | Timer::after_millis(100).await; | ||
| 54 | // worst case drop happens here | ||
| 55 | } else { | ||
| 56 | info!("waiting"); | ||
| 57 | } | ||
| 58 | // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do. | ||
| 59 | // During this sleep, the nRF chip should only use ~3uA | ||
| 60 | Timer::after_secs(1).await; | ||
| 61 | } | ||
| 62 | } | ||
