Files
k-frame/crates/client-esp32/src/main.rs
Gabriel Kaszewski a51d22649a internal data sources (clock, static text), connection indicator, rendering fixes
DataSourceConfig refactored to enum: External/Clock/StaticText. Clock
generates formatted time via chrono, static text emits configured string.

ESP32: connection status indicator (green/red dot bottom-right), per-widget
clear before redraw, RenderEvent enum for local + server messages.

Polling uses DataUpdate instead of ScreenUpdate to avoid wiping widget state.
Empty mappings passthrough raw source data for internal sources.
2026-06-19 11:26:49 +02:00

77 lines
2.4 KiB
Rust

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::RenderEvent>();
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);
}