Connect to wireless network

This commit is contained in:
Invariantspace 2024-10-13 21:01:33 -07:00
parent fc1105fdc3
commit 95ad37bcaa
No known key found for this signature in database
GPG key ID: EBC4A20067373921
3 changed files with 239 additions and 171 deletions

View file

@ -1,11 +1,16 @@
#![feature(impl_trait_in_assoc_type)]
#![no_std]
#![no_main]
extern crate panic_halt;
use cyw43::JoinOptions;
use cyw43_pio::PioSpi;
use embassy_executor::Spawner;
use embassy_net::{Config, DhcpConfig, StackResources};
use embassy_rp::{
bind_interrupts,
clocks::RoscRng,
gpio::{Level, Output},
peripherals::{DMA_CH0, PIO0, USB},
pio::{self, Pio},
@ -13,41 +18,51 @@ use embassy_rp::{
};
use embassy_time::Timer;
use log::info;
use rand::RngCore;
use static_cell::StaticCell;
const WIFI_CREDENTIALS: &[(&str, &str)] =
const HOSTNAME: &str = "picow";
const WIRELESS_CREDENTIALS: &[(&str, &str)] =
&include!(concat!(env!("OUT_DIR"), "/wireless-credentials.rs"));
// bind interrupt request to handler
const WIRELESS_SCAN_PERIOD_SECOND: u64 = 7;
bind_interrupts!(struct Irqs {
PIO0_IRQ_0 => pio::InterruptHandler<PIO0>;
USBCTRL_IRQ => usb::InterruptHandler<USB>;
});
// logger task
#[embassy_executor::task]
async fn logger_task(driver: Driver<'static, USB>) {
embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver);
async fn logger_task(usb_driver: Driver<'static, USB>) -> ! {
embassy_usb_logger::run!(1024, log::LevelFilter::Info, usb_driver);
}
// wireless task
#[embassy_executor::task]
async fn cyw43_task(
runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>,
async fn network_task(
mut network_runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>,
) -> ! {
runner.run().await
network_runner.run().await;
}
#[embassy_executor::task]
async fn wireless_task(
wireless_runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>,
) -> ! {
wireless_runner.run().await;
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
async fn main(spawner: Spawner) -> ! {
// hardware abstraction layer
let hal = embassy_rp::init(Default::default());
// usb driver
let driver = Driver::new(hal.USB, Irqs);
let usb_driver = Driver::new(hal.USB, Irqs);
// spawn logger task
spawner.spawn(logger_task(driver)).unwrap();
spawner
.spawn(logger_task(usb_driver))
.expect("Logger task should not fail to spawn");
// wireless firmware binary
let fw = include_bytes!("../firmware/43439A0.bin");
@ -80,23 +95,69 @@ async fn main(spawner: Spawner) {
let state = STATE.init(cyw43::State::new());
// spawn wireless task
let (_, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
spawner.spawn(cyw43_task(runner)).unwrap();
let (network_device, mut wireless_control, wireless_runner) =
cyw43::new(state, pwr, spi, fw).await;
spawner
.spawn(wireless_task(wireless_runner))
.expect("Wireless task should not fail to spawn");
// initialize wireless
control.init(clm).await;
control
// initialize wireless control
wireless_control.init(clm).await;
wireless_control
.set_power_management(cyw43::PowerManagementMode::PowerSave)
.await;
// time to blink
let mut led = false;
loop {
for (k, v) in WIFI_CREDENTIALS {
info!("{k}: {v}");
// set hostname
let mut dhcpv4_config = DhcpConfig::default();
dhcpv4_config.hostname = HOSTNAME.try_into().ok();
// setup network stack
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (network_stack, network_runner) = embassy_net::new(
network_device,
Config::dhcpv4(dhcpv4_config),
RESOURCES.init(StackResources::new()),
RoscRng.next_u64(),
);
// spawn network task
spawner
.spawn(network_task(network_runner))
.expect("Network task should not fail to spawn");
// search and join wireless network
for (ssid, password) in WIRELESS_CREDENTIALS.iter().cycle() {
info!("Searching for wireless network: {ssid}");
if let Ok(_) = wireless_control
.join(ssid, JoinOptions::new(password.as_bytes()))
.await
{
info!("Successfully joined wireless network: {ssid}");
break;
} else if ssid
== &WIRELESS_CREDENTIALS
.last()
.expect("The list of wireless credentials should not be empty")
.0
{
info!("Unable to join any wireless network with provided credentials");
info!("Sleep for {WIRELESS_SCAN_PERIOD_SECOND} seconds before rescan");
Timer::after_secs(WIRELESS_SCAN_PERIOD_SECOND).await;
}
led = !led;
control.gpio_set(0, led).await;
}
// wait for network stack
info!("Wait for network setup");
network_stack.wait_config_up().await;
network_stack.wait_link_up().await;
info!("Successfully setup network stack");
info!("Network configuration: {:?}", network_stack.config_v4());
// turn on led to indicate network connection
wireless_control.gpio_set(0, true).await;
loop {
info!("System is idle");
Timer::after_secs(1).await;
}
}