A RPi Pico powered Lightning Detector
1#![allow(clippy::too_many_arguments)]
2use core::str::FromStr;
3
4use cyw43::JoinOptions;
5use cyw43_pio::PioSpi;
6use embassy_executor::Spawner;
7use embassy_net::{Config, DhcpConfig, StackResources};
8use embassy_rp::clocks::RoscRng;
9use embassy_rp::gpio::Output;
10use embassy_rp::peripherals::{DMA_CH0, PIO0};
11use embassy_time::{Duration, WithTimeout};
12use sachy_fmt::{info, unwrap};
13use static_cell::StaticCell;
14
15use crate::net;
16use crate::rtc::GlobalRtc;
17
18#[embassy_executor::task]
19async fn cyw43_task(
20 runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>,
21) -> ! {
22 runner.run().await
23}
24
25#[embassy_executor::task]
26async fn net_runner(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
27 runner.run().await
28}
29
30#[embassy_executor::task]
31pub async fn main_loop(
32 spawner: Spawner,
33 rtc: GlobalRtc<'static>,
34 spi: PioSpi<'static, PIO0, 0, embassy_rp::peripherals::DMA_CH0>,
35 pwr: Output<'static>,
36) {
37 let fw = include_bytes!("../firmware/43439A0.bin");
38 let clm = include_bytes!("../firmware/43439A0_clm.bin");
39
40 info!("Initialising WIFI chip");
41
42 static STATE: StaticCell<cyw43::State> = StaticCell::new();
43 static RESOURCES: StaticCell<StackResources<6>> = StaticCell::new();
44 let state = STATE.init_with(cyw43::State::new);
45 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
46 spawner.must_spawn(cyw43_task(runner));
47
48 control.init(clm).await;
49 control
50 .set_power_management(cyw43::PowerManagementMode::PowerSave)
51 .await;
52
53 unwrap!(
54 control
55 .add_multicast_address([0x01, 0, 0x5E, 0, 0, 0xFB])
56 .await,
57 "Failed to join ipv4 multicast hardware address"
58 );
59
60 let seed = RoscRng.next_u64();
61
62 let mut dhcp: DhcpConfig = Default::default();
63
64 dhcp.hostname = heapless::String::from_str("pico-strike").ok();
65
66 info!("Init Net stack");
67
68 let (stack, runner) = embassy_net::new(
69 net_device,
70 Config::dhcpv4(dhcp),
71 RESOURCES.init_with(StackResources::new),
72 seed,
73 );
74
75 info!("WIFI chip enabled successfully");
76
77 spawner.must_spawn(net_runner(runner));
78
79 spawner.must_spawn(net::udp_stack(stack, rtc));
80 spawner.must_spawn(net::tcp_stack(stack));
81
82 loop {
83 info!("Joining WIFI!");
84 control.gpio_set(0, true).await;
85
86 if control
87 .join(
88 crate::constants::SSID,
89 JoinOptions::new(crate::constants::PASSWORD.as_bytes()),
90 )
91 .await
92 .is_err()
93 {
94 continue;
95 }
96
97 if stack
98 .wait_config_up()
99 .with_timeout(Duration::from_secs(60))
100 .await
101 .is_err()
102 {
103 control.leave().await;
104 continue;
105 }
106
107 info!("WIFI connection ready!");
108 control.gpio_set(0, false).await;
109
110 stack.wait_link_down().await;
111
112 control.leave().await;
113 }
114}