A RPi Pico powered Lightning Detector
at main 83 lines 2.4 kB view raw
1use alloc::vec::Vec; 2use sachy_fmt::{info, unwrap}; 3 4use embassy_futures::select::select4; 5use embassy_rp::peripherals::DMA_CH1; 6use embassy_strike_driver::{ 7 DetectorDriver, ZeroCopyChannel, 8 drivers::rp::{AdcDriver, PwmDriver}, 9 traits::{AdcSource, PwmSource, TimeSource}, 10}; 11use embassy_sync::{blocking_mutex::raw::NoopRawMutex, zerocopy_channel::Channel as ZChannel}; 12use embassy_time::Timer; 13 14use crate::{ 15 constants::BLOCK_SIZE, 16 rtc::GlobalRtc, 17 updates::{DetectorConfigurationHandle, UpdateConnection}, 18 utils::{static_alloc, try_buffer, try_static_timestamped_block_vecs}, 19}; 20 21#[embassy_executor::task] 22pub async fn detector_task( 23 adc: AdcDriver<'static, NoopRawMutex, DMA_CH1>, 24 pwm: PwmDriver<'static>, 25 rtc: GlobalRtc<'static>, 26) { 27 info!("Waiting for RTC to start running"); 28 while !rtc.is_ready().await { 29 Timer::after_secs(2).await; 30 } 31 32 info!("Allocating detector resources"); 33 34 let blocks = unwrap!( 35 try_static_timestamped_block_vecs::<BLOCK_SIZE, u16>(2), 36 "Couldn't allocate block buffers" 37 ); 38 39 let buf_channel: &mut ZeroCopyChannel = static_alloc(ZChannel::new(blocks)); 40 41 let (mut sender, mut receiver) = buf_channel.split(); 42 43 let config = DetectorConfigurationHandle::get_config(); 44 let mut detector = DetectorDriver::new(config, rtc.track_time().await, pwm, adc); 45 let mut samples = unwrap!(try_buffer(64), "Failed to allocate sample buffer"); 46 let mut peaks = Vec::new(); 47 48 unwrap!( 49 peaks.try_reserve_exact(BLOCK_SIZE), 50 "Failed to allocate peaks buffer" 51 ); 52 53 loop { 54 detector.tune(samples.as_mut_slice()).await; 55 56 select4( 57 update_detector_config(&detector), 58 detector.sample_with_zerocopy(&mut sender), 59 detector.detect_with_zerocopy( 60 &mut receiver, 61 &mut peaks, 62 UpdateConnection::transmit_update, 63 ), 64 detector.tick(UpdateConnection::transmit_update), 65 ) 66 .await; 67 68 detector.reset_timer_source(rtc).await; 69 } 70} 71 72async fn update_detector_config<T, P, A>(detector: &DetectorDriver<T, P, A>) 73where 74 T: TimeSource, 75 P: PwmSource, 76 A: AdcSource, 77{ 78 loop { 79 let update = DetectorConfigurationHandle::get_updated_config().await; 80 81 detector.set_config(update); 82 } 83}