mod adapters; mod boot; mod config; mod hal; mod provisioning; mod tasks; use std::sync::mpsc; use esp_idf_hal::peripherals::Peripherals; use esp_idf_svc::eventloop::EspSystemEventLoop; use esp_idf_svc::nvs::EspDefaultNvsPartition; use log::info; fn main() { esp_idf_svc::sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); info!("=== K-Frame ESP32 ==="); let peripherals = Peripherals::take().unwrap(); let sysloop = EspSystemEventLoop::take().unwrap(); let nvs = EspDefaultNvsPartition::take().unwrap(); let mut display = hal::display::init(hal::display::DisplayHardware { spi: peripherals.spi2, sclk: peripherals.pins.gpio18.into(), mosi: peripherals.pins.gpio23.into(), cs: peripherals.pins.gpio26.into(), dc: peripherals.pins.gpio21.into(), rst: peripherals.pins.gpio22.into(), }); info!("Display ready"); match provisioning::read_config(nvs.clone()) { Some(cfg) => run_station(peripherals.modem, sysloop, nvs, cfg, display), None => { info!("No config found, entering setup mode"); run_setup(peripherals.modem, sysloop, nvs, &mut display); } } } fn run_station( modem: esp_idf_hal::modem::Modem<'static>, sysloop: EspSystemEventLoop, nvs: EspDefaultNvsPartition, cfg: provisioning::DeviceConfig, display: adapters::display::Esp32DisplayAdapter, ) { info!("Connecting WiFi..."); match hal::wifi::init(modem, sysloop.clone(), nvs.clone(), &cfg.wifi_ssid, &cfg.wifi_pass) { Ok(_wifi) => { let (tx, rx) = mpsc::channel::(); tasks::network::spawn(cfg.server_addr, tx); tasks::render::run(config::SCREEN, display, rx); } Err(e) => { info!("WiFi failed ({e}), clearing config and rebooting to setup mode"); provisioning::clear_config(nvs); std::thread::sleep(std::time::Duration::from_secs(1)); unsafe { esp_idf_svc::sys::esp_restart(); } } } } fn run_setup( modem: esp_idf_hal::modem::Modem<'static>, sysloop: EspSystemEventLoop, nvs: EspDefaultNvsPartition, display: &mut adapters::display::Esp32DisplayAdapter, ) { let _wifi = hal::wifi::init_ap(modem, sysloop, nvs.clone()) .expect("AP mode failed"); provisioning::portal::run_captive_portal(nvs, display); }