#![allow(clippy::too_many_arguments)] use core::str::FromStr; use cyw43::JoinOptions; use cyw43_pio::PioSpi; use embassy_executor::Spawner; use embassy_net::{Config, DhcpConfig, StackResources}; use embassy_rp::clocks::RoscRng; use embassy_rp::gpio::Output; use embassy_rp::peripherals::{DMA_CH0, PIO0}; use embassy_time::{Duration, WithTimeout}; use sachy_fmt::{info, unwrap}; use static_cell::StaticCell; use crate::net; use crate::rtc::GlobalRtc; #[embassy_executor::task] async fn cyw43_task( runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>, ) -> ! { runner.run().await } #[embassy_executor::task] async fn net_runner(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! { runner.run().await } #[embassy_executor::task] pub async fn main_loop( spawner: Spawner, rtc: GlobalRtc<'static>, spi: PioSpi<'static, PIO0, 0, embassy_rp::peripherals::DMA_CH0>, pwr: Output<'static>, ) { let fw = include_bytes!("../firmware/43439A0.bin"); let clm = include_bytes!("../firmware/43439A0_clm.bin"); info!("Initialising WIFI chip"); static STATE: StaticCell = StaticCell::new(); static RESOURCES: StaticCell> = StaticCell::new(); let state = STATE.init_with(cyw43::State::new); let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; spawner.must_spawn(cyw43_task(runner)); control.init(clm).await; control .set_power_management(cyw43::PowerManagementMode::PowerSave) .await; unwrap!( control .add_multicast_address([0x01, 0, 0x5E, 0, 0, 0xFB]) .await, "Failed to join ipv4 multicast hardware address" ); let seed = RoscRng.next_u64(); let mut dhcp: DhcpConfig = Default::default(); dhcp.hostname = heapless::String::from_str("pico-strike").ok(); info!("Init Net stack"); let (stack, runner) = embassy_net::new( net_device, Config::dhcpv4(dhcp), RESOURCES.init_with(StackResources::new), seed, ); info!("WIFI chip enabled successfully"); spawner.must_spawn(net_runner(runner)); spawner.must_spawn(net::udp_stack(stack, rtc)); spawner.must_spawn(net::tcp_stack(stack)); loop { info!("Joining WIFI!"); control.gpio_set(0, true).await; if control .join( crate::constants::SSID, JoinOptions::new(crate::constants::PASSWORD.as_bytes()), ) .await .is_err() { continue; } if stack .wait_config_up() .with_timeout(Duration::from_secs(60)) .await .is_err() { control.leave().await; continue; } info!("WIFI connection ready!"); control.gpio_set(0, false).await; stack.wait_link_down().await; control.leave().await; } }