152 lines
4.3 KiB
Rust
152 lines
4.3 KiB
Rust
#![no_std]
|
|
#![no_main]
|
|
#![deny(
|
|
clippy::mem_forget,
|
|
reason = "mem::forget is generally not safe to do with esp_hal types"
|
|
)]
|
|
|
|
use embassy_executor::Spawner;
|
|
use embassy_net::{Runner, StackResources};
|
|
use embassy_time::{Duration, Timer};
|
|
use esp_alloc as _;
|
|
use esp_backtrace as _;
|
|
use esp_hal::{clock::CpuClock, rng::Rng, timer::timg::TimerGroup};
|
|
use esp_wifi::{
|
|
EspWifiController,
|
|
init,
|
|
wifi::{ClientConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiState},
|
|
};
|
|
use log::info;
|
|
use rust_mqtt::packet::v5::publish_packet::QualityOfService;
|
|
use projekt_final::mqtt::client::{mqtt_task, mqtt_publish};
|
|
use defmt_rtt as _;
|
|
|
|
extern crate alloc;
|
|
|
|
esp_bootloader_esp_idf::esp_app_desc!();
|
|
|
|
macro_rules! mk_static {
|
|
($t:ty,$val:expr) => {{
|
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
|
#[deny(unused_attributes)]
|
|
let x = STATIC_CELL.uninit().write(($val));
|
|
x
|
|
}};
|
|
}
|
|
|
|
const SSID: &str = env!("SSID");
|
|
const PASSWORD: &str = env!("PASSWORD");
|
|
|
|
#[esp_hal_embassy::main]
|
|
async fn main(spawner: Spawner) -> ! {
|
|
esp_println::logger::init_logger_from_env();
|
|
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
|
let peripherals = esp_hal::init(config);
|
|
|
|
esp_alloc::heap_allocator!(size: 72 * 1024);
|
|
|
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
|
let mut rng = Rng::new(peripherals.RNG);
|
|
|
|
let esp_wifi_ctrl = &*mk_static!(
|
|
EspWifiController<'static>,
|
|
init(timg0.timer0, rng.clone()).unwrap()
|
|
);
|
|
|
|
let (controller, interfaces) = esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap();
|
|
|
|
let wifi_interface = interfaces.sta;
|
|
|
|
let timg1 = TimerGroup::new(peripherals.TIMG1);
|
|
esp_hal_embassy::init(timg1.timer0);
|
|
|
|
let config = embassy_net::Config::dhcpv4(Default::default());
|
|
|
|
let seed = (rng.random() as u64) << 32 | rng.random() as u64;
|
|
|
|
// Init network stack
|
|
let (stack, runner) = embassy_net::new(
|
|
wifi_interface,
|
|
config,
|
|
mk_static!(StackResources<3>, StackResources::<3>::new()),
|
|
seed,
|
|
);
|
|
|
|
spawner.spawn(connection(controller)).ok();
|
|
spawner.spawn(net_task(runner)).ok();
|
|
|
|
// Wait for link up
|
|
loop {
|
|
if stack.is_link_up() {
|
|
break;
|
|
}
|
|
Timer::after(Duration::from_millis(500)).await;
|
|
}
|
|
|
|
info!("Waiting to get IP address...");
|
|
loop {
|
|
if let Some(config) = stack.config_v4() {
|
|
info!("Got IP: {}", config.address);
|
|
break;
|
|
}
|
|
Timer::after(Duration::from_millis(500)).await;
|
|
}
|
|
|
|
spawner.spawn(mqtt_task(stack)).expect("failed to spawn MQTT task");
|
|
info!("MQTT task started");
|
|
|
|
loop {
|
|
// TODO example
|
|
mqtt_publish(
|
|
"esp32/topic",
|
|
b"hello from main",
|
|
QualityOfService::QoS1,
|
|
false,
|
|
)
|
|
.await;
|
|
|
|
// Avoid spamming, just an example cadence
|
|
Timer::after(Duration::from_secs(5)).await;
|
|
}
|
|
}
|
|
|
|
#[embassy_executor::task]
|
|
async fn connection(mut controller: WifiController<'static>) {
|
|
info!("start connection task");
|
|
info!("Device capabilities: {:?}", controller.capabilities());
|
|
loop {
|
|
match esp_wifi::wifi::wifi_state() {
|
|
WifiState::StaConnected => {
|
|
controller.wait_for_event(WifiEvent::StaDisconnected).await;
|
|
Timer::after(Duration::from_millis(5000)).await
|
|
}
|
|
_ => {}
|
|
}
|
|
if !matches!(controller.is_started(), Ok(true)) {
|
|
let client_config = Configuration::Client(ClientConfiguration {
|
|
ssid: SSID.into(),
|
|
password: PASSWORD.into(),
|
|
..Default::default()
|
|
});
|
|
controller.set_configuration(&client_config).unwrap();
|
|
info!("Starting wifi");
|
|
controller.start_async().await.unwrap();
|
|
info!("Wifi started!");
|
|
}
|
|
info!("About to connect...");
|
|
|
|
match controller.connect_async().await {
|
|
Ok(_) => info!("Wifi connected!"),
|
|
Err(e) => {
|
|
info!("Failed to connect to wifi: {e:?}");
|
|
Timer::after(Duration::from_millis(5000)).await
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[embassy_executor::task]
|
|
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
|
|
runner.run().await
|
|
}
|