A RPi Pico powered Lightning Detector
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}