minimal startup running

This commit is contained in:
Empire Phoenix 2025-09-14 13:19:30 +02:00
parent b3cc313139
commit 4aa25c687b
7 changed files with 146 additions and 119 deletions

View File

@ -57,6 +57,7 @@ esp-hal = { version = "=1.0.0-rc.0", features = [
"esp32c6", "esp32c6",
"log-04", "log-04",
"unstable", "unstable",
"rt"
] } ] }
log = "0.4.27" log = "0.4.27"

View File

@ -175,7 +175,7 @@ impl Esp<'_> {
} }
} }
pub(crate) async fn wifi_ap(&mut self) -> anyhow::Result<Stack> { pub(crate) async fn wifi_ap(&mut self) -> anyhow::Result<Stack<'static>> {
let _ssid = match self.load_config() { let _ssid = match self.load_config() {
Ok(config) => config.network.ap_ssid.clone(), Ok(config) => config.network.ap_ssid.clone(),
Err(_) => heapless::String::from_str("PlantCtrl Emergency Mode").unwrap(), Err(_) => heapless::String::from_str("PlantCtrl Emergency Mode").unwrap(),
@ -207,7 +207,7 @@ impl Esp<'_> {
let controller = self.controller.take().unwrap(); let controller = self.controller.take().unwrap();
spawner.spawn(connection(controller)).ok(); spawner.spawn(connection(controller)).ok();
spawner.spawn(net_task(runner)).ok(); spawner.spawn(net_task(runner)).ok();
spawner.spawn(run_dhcp(stack, gw_ip_addr_str)).ok(); spawner.spawn(run_dhcp(stack.clone(), gw_ip_addr_str)).ok();
loop { loop {
if stack.is_link_up() { if stack.is_link_up() {
@ -699,7 +699,7 @@ impl Esp<'_> {
} }
#[embassy_executor::task] #[embassy_executor::task]
async fn run_dhcp(stack: &'static Stack<'static>, gw_ip_addr: &'static str) { async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) {
use core::net::{Ipv4Addr, SocketAddrV4}; use core::net::{Ipv4Addr, SocketAddrV4};
use edge_dhcp::{ use edge_dhcp::{
@ -716,7 +716,7 @@ async fn run_dhcp(stack: &'static Stack<'static>, gw_ip_addr: &'static str) {
let mut gw_buf = [Ipv4Addr::UNSPECIFIED]; let mut gw_buf = [Ipv4Addr::UNSPECIFIED];
let buffers = UdpBuffers::<3, 1024, 1024, 10>::new(); let buffers = UdpBuffers::<3, 1024, 1024, 10>::new();
let unbound_socket = Udp::new(*stack, &buffers); let unbound_socket = Udp::new(stack, &buffers);
let mut bound_socket = unbound_socket let mut bound_socket = unbound_socket
.bind(core::net::SocketAddr::V4(SocketAddrV4::new( .bind(core::net::SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::UNSPECIFIED, Ipv4Addr::UNSPECIFIED,

View File

@ -11,10 +11,12 @@ use crate::{
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use esp_hal::gpio::{Level, Output, OutputConfig};
use log::info;
use measurements::{Current, Voltage}; use measurements::{Current, Voltage};
pub struct Initial<'a> { pub struct Initial<'a> {
//pub(crate) general_fault: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, pub(crate) general_fault: Output<'a>,
pub(crate) esp: Esp<'a>, pub(crate) esp: Esp<'a>,
pub(crate) config: PlantControllerConfig, pub(crate) config: PlantControllerConfig,
pub(crate) battery: Box<dyn BatteryInteraction + Send>, pub(crate) battery: Box<dyn BatteryInteraction + Send>,
@ -47,21 +49,14 @@ impl RTCModuleInteraction for NoRTC {
} }
pub(crate) fn create_initial_board( pub(crate) fn create_initial_board(
//free_pins: FreePeripherals, free_pins: FreePeripherals<'static>,
_fs_mount_error: bool,
config: PlantControllerConfig, config: PlantControllerConfig,
esp: Esp<'static>, esp: Esp<'static>,
) -> Result<Box<dyn BoardInteraction<'static> + Send>> { ) -> Result<Box<dyn BoardInteraction<'static> + Send>> {
log::info!("Start initial"); log::info!("Start initial");
// let mut general_fault = PinDriver::input_output(free_pins.gpio6.downgrade())?; let general_fault = Output::new(free_pins.gpio23, Level::Low, OutputConfig::default());
// general_fault.set_pull(Pull::Floating)?;
// general_fault.set_low()?;
//
// if fs_mount_error {
// general_fault.set_high()?
// }
let v = Initial { let v = Initial {
//general_fault, general_fault,
config, config,
esp, esp,
battery: Box::new(NoBatteryMonitor {}), battery: Box::new(NoBatteryMonitor {}),
@ -122,8 +117,8 @@ impl<'a> BoardInteraction<'a> for Initial<'a> {
bail!("Please configure board revision") bail!("Please configure board revision")
} }
async fn general_fault(&mut self, _enable: bool) { async fn general_fault(&mut self, enable: bool) {
//let _ = self.general_fault.set_state(enable.into()); self.general_fault.set_level(enable.into());
} }
async fn test(&mut self) -> Result<()> { async fn test(&mut self) -> Result<()> {

View File

@ -6,6 +6,10 @@ mod rtc;
use crate::alloc::string::ToString; use crate::alloc::string::ToString;
use crate::hal::rtc::RTCModuleInteraction; use crate::hal::rtc::RTCModuleInteraction;
use esp_hal::peripherals::Peripherals;
use esp_hal::peripherals::GPIO23;
use esp_hal::peripherals::GPIO6;
//use crate::hal::water::TankSensor; //use crate::hal::water::TankSensor;
use crate::{ use crate::{
config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig}, config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig},
@ -33,7 +37,7 @@ use embassy_sync::once_lock::OnceLock;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use esp_bootloader_esp_idf::partitions::DataPartitionSubType; use esp_bootloader_esp_idf::partitions::DataPartitionSubType;
use esp_hal::clock::CpuClock; use esp_hal::clock::CpuClock;
use esp_hal::gpio::{Input, InputConfig, Pull}; use esp_hal::gpio::{Input, InputConfig, Io, Pull};
use esp_hal::timer::systimer::SystemTimer; use esp_hal::timer::systimer::SystemTimer;
use esp_println::{print, println}; use esp_println::{print, println};
use measurements::{Current, Voltage}; use measurements::{Current, Voltage};
@ -41,6 +45,7 @@ use measurements::{Current, Voltage};
use embassy_sync::mutex::{Mutex, MutexGuard}; use embassy_sync::mutex::{Mutex, MutexGuard};
use esp_alloc as _; use esp_alloc as _;
use esp_backtrace as _; use esp_backtrace as _;
use esp_hal::analog::adc::Adc;
use esp_hal::rng::Rng; use esp_hal::rng::Rng;
use esp_hal::timer::timg::TimerGroup; use esp_hal::timer::timg::TimerGroup;
use esp_wifi::wifi::{ use esp_wifi::wifi::{
@ -125,14 +130,14 @@ impl dyn BoardInteraction<'_> {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub struct FreePeripherals { pub struct FreePeripherals<'a> {
// pub gpio0: Gpio0, // pub gpio0: Gpio0,
// pub gpio1: Gpio1, // pub gpio1: Gpio1,
// pub gpio2: Gpio2, // pub gpio2: Gpio2,
// pub gpio3: Gpio3, // pub gpio3: Gpio3,
// pub gpio4: Gpio4, // pub gpio4: Gpio4,
// pub gpio5: Gpio5, // pub gpio5: Gpio5,
// pub gpio6: Gpio6, pub gpio6: GPIO6<'a>,
// pub gpio7: Gpio7, // pub gpio7: Gpio7,
// pub gpio8: Gpio8, // pub gpio8: Gpio8,
// //config button here // //config button here
@ -148,7 +153,7 @@ pub struct FreePeripherals {
// //i2c here // //i2c here
// pub gpio21: Gpio21, // pub gpio21: Gpio21,
// pub gpio22: Gpio22, // pub gpio22: Gpio22,
// pub gpio23: Gpio23, pub gpio23: GPIO23<'a>,
// pub gpio24: Gpio24, // pub gpio24: Gpio24,
// pub gpio25: Gpio25, // pub gpio25: Gpio25,
// pub gpio26: Gpio26, // pub gpio26: Gpio26,
@ -192,7 +197,7 @@ impl PlantHal {
pub async fn create(spawner: Spawner) -> Result<Mutex<CriticalSectionRawMutex, HAL<'static>>> { pub async fn create(spawner: Spawner) -> Result<Mutex<CriticalSectionRawMutex, HAL<'static>>> {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config); let peripherals: Peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 64 * 1024); esp_alloc::heap_allocator!(size: 64 * 1024);
let systimer = SystemTimer::new(peripherals.SYSTIMER); let systimer = SystemTimer::new(peripherals.SYSTIMER);
@ -215,41 +220,42 @@ impl PlantHal {
use esp_hal::timer::systimer::SystemTimer; use esp_hal::timer::systimer::SystemTimer;
esp_hal_embassy::init(systimer.alarm0); esp_hal_embassy::init(systimer.alarm0);
//let mut adc1 = Adc::new(peripherals.ADC1, adc1_config);
// //
// let free_pins = FreePeripherals { let free_pins = FreePeripherals {
// can: peripherals.can, // can: peripherals.can,
// adc1: peripherals.adc1, // adc1: peripherals.adc1,
// pcnt0: peripherals.pcnt0, // pcnt0: peripherals.pcnt0,
// pcnt1: peripherals.pcnt1, // pcnt1: peripherals.pcnt1,
// gpio0: peripherals.pins.gpio0, // gpio0: peripherals.pins.gpio0,
// gpio1: peripherals.pins.gpio1, // gpio1: peripherals.pins.gpio1,
// gpio2: peripherals.pins.gpio2, // gpio2: peripherals.pins.gpio2,
// gpio3: peripherals.pins.gpio3, // gpio3: peripherals.pins.gpio3,
// gpio4: peripherals.pins.gpio4, // gpio4: peripherals.pins.gpio4,
// gpio5: peripherals.pins.gpio5, // gpio5: peripherals.pins.gpio5,
// gpio6: peripherals.pins.gpio6, gpio6: peripherals.GPIO6,
// gpio7: peripherals.pins.gpio7, // gpio7: peripherals.pins.gpio7,
// gpio8: peripherals.pins.gpio8, // gpio8: peripherals.pins.gpio8,
// gpio10: peripherals.pins.gpio10, // gpio10: peripherals.pins.gpio10,
// gpio11: peripherals.pins.gpio11, // gpio11: peripherals.pins.gpio11,
// gpio12: peripherals.pins.gpio12, // gpio12: peripherals.pins.gpio12,
// gpio13: peripherals.pins.gpio13, // gpio13: peripherals.pins.gpio13,
// gpio14: peripherals.pins.gpio14, // gpio14: peripherals.pins.gpio14,
// gpio15: peripherals.pins.gpio15, // gpio15: peripherals.pins.gpio15,
// gpio16: peripherals.pins.gpio16, // gpio16: peripherals.pins.gpio16,
// gpio17: peripherals.pins.gpio17, // gpio17: peripherals.pins.gpio17,
// gpio18: peripherals.pins.gpio18, // gpio18: peripherals.pins.gpio18,
// gpio21: peripherals.pins.gpio21, // gpio21: peripherals.pins.gpio21,
// gpio22: peripherals.pins.gpio22, // gpio22: peripherals.pins.gpio22,
// gpio23: peripherals.pins.gpio23, gpio23: peripherals.GPIO23,
// gpio24: peripherals.pins.gpio24, // gpio24: peripherals.pins.gpio24,
// gpio25: peripherals.pins.gpio25, // gpio25: peripherals.pins.gpio25,
// gpio26: peripherals.pins.gpio26, // gpio26: peripherals.pins.gpio26,
// gpio27: peripherals.pins.gpio27, // gpio27: peripherals.pins.gpio27,
// gpio28: peripherals.pins.gpio28, // gpio28: peripherals.pins.gpio28,
// gpio29: peripherals.pins.gpio29, // gpio29: peripherals.pins.gpio29,
// gpio30: peripherals.pins.gpio30, // gpio30: peripherals.pins.gpio30,
// }; };
// //
let mut storage = esp_storage::FlashStorage::new(); let mut storage = esp_storage::FlashStorage::new();
@ -392,7 +398,7 @@ impl PlantHal {
let board_hal: Box<dyn BoardInteraction + Send> = match config.hardware.board { let board_hal: Box<dyn BoardInteraction + Send> = match config.hardware.board {
BoardVersion::INITIAL => { BoardVersion::INITIAL => {
initial_hal::create_initial_board(fs_mount_error, config, esp)? initial_hal::create_initial_board(free_pins, config, esp)?
} }
// BoardVersion::V3 => { // BoardVersion::V3 => {
// v3_hal::create_v3(free_pins, esp, config, battery_interaction, rtc_module)? // v3_hal::create_v3(free_pins, esp, config, battery_interaction, rtc_module)?
@ -417,7 +423,7 @@ impl PlantHal {
); );
HAL { HAL {
board_hal: initial_hal::create_initial_board( board_hal: initial_hal::create_initial_board(
fs_mount_error, free_pins,
PlantControllerConfig::default(), PlantControllerConfig::default(),
esp, esp,
)?, )?,

View File

@ -5,6 +5,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::lazy_lock::LazyLock; use embassy_sync::lazy_lock::LazyLock;
use embassy_sync::mutex::Mutex; use embassy_sync::mutex::Mutex;
use embassy_time::Instant; use embassy_time::Instant;
use esp_println::println;
use log::info; use log::info;
use serde::Serialize; use serde::Serialize;
use strum_macros::IntoStaticStr; use strum_macros::IntoStaticStr;

View File

@ -64,7 +64,7 @@ mod webserver;
extern crate alloc; extern crate alloc;
//mod webserver; //mod webserver;
pub static BOARD_ACCESS: OnceLock<Mutex<CriticalSectionRawMutex, HAL>> = OnceLock::new(); pub static BOARD_ACCESS: OnceLock<Mutex<CriticalSectionRawMutex, HAL<'static>>> = OnceLock::new();
pub static STAY_ALIVE: AtomicBool = AtomicBool::new(false); pub static STAY_ALIVE: AtomicBool = AtomicBool::new(false);
@ -143,7 +143,7 @@ enum NetworkMode {
OFFLINE, OFFLINE,
} }
async fn safe_main() -> anyhow::Result<()> { async fn safe_main(spawner: Spawner) -> anyhow::Result<()> {
info!("Startup Rust"); info!("Startup Rust");
let mut to_config = false; let mut to_config = false;
@ -179,10 +179,8 @@ async fn safe_main() -> anyhow::Result<()> {
//}; //};
//log(LogMessage::PartitionState, 0, 0, "", ota_state_string); //log(LogMessage::PartitionState, 0, 0, "", ota_state_string);
let _ota_state_string = "unknown"; let _ota_state_string = "unknown";
println!("faul led");
let mut board = BOARD_ACCESS.get().await.lock().await; let mut board = BOARD_ACCESS.get().await.lock().await;
board.board_hal.general_fault(false).await; board.board_hal.general_fault(false).await;
println!("faul led2");
let cur = board let cur = board
.board_hal .board_hal
.get_rtc_module() .get_rtc_module()
@ -196,7 +194,7 @@ async fn safe_main() -> anyhow::Result<()> {
//check if we know the time current > 2020 (plausibility checks, this code is newer than 2020) //check if we know the time current > 2020 (plausibility checks, this code is newer than 2020)
if cur.year() < 2020 { if cur.year() < 2020 {
to_config = true; to_config = true;
log(LogMessage::YearInplausibleForceConfig, 0, 0, "", ""); log(LogMessage::YearInplausibleForceConfig, 0, 0, "", "").await;
} }
info!("cur is {}", cur); info!("cur is {}", cur);
@ -237,12 +235,15 @@ async fn safe_main() -> anyhow::Result<()> {
&& board.board_hal.get_config().network.ssid.is_none() && board.board_hal.get_config().network.ssid.is_none()
{ {
info!("No wifi configured, starting initial config mode"); info!("No wifi configured, starting initial config mode");
let stack = board.board_hal.get_esp().wifi_ap().await?; let stack = board.board_hal.get_esp().wifi_ap().await?;
let reboot_now = Arc::new(AtomicBool::new(false)); let reboot_now = Arc::new(AtomicBool::new(false));
println!("starting webserver"); println!("starting webserver");
let _webserver = httpd(reboot_now.clone(), stack).await;
wait_infinity(WaitType::MissingConfig, reboot_now.clone()).await; spawner.spawn(httpd(reboot_now.clone(), stack))?;
wait_infinity(board, WaitType::MissingConfig, reboot_now.clone()).await;
} }
info!("attempting to connect wifi"); info!("attempting to connect wifi");
@ -257,7 +258,12 @@ async fn safe_main() -> anyhow::Result<()> {
if matches!(network_mode, NetworkMode::OFFLINE) && to_config { if matches!(network_mode, NetworkMode::OFFLINE) && to_config {
info!("Could not connect to station and config mode forced, switching to ap mode!"); info!("Could not connect to station and config mode forced, switching to ap mode!");
match board.board_hal.get_esp().wifi_ap().await {
let res = {
let esp = board.board_hal.get_esp();
esp.wifi_ap().await
};
match res {
Ok(_) => { Ok(_) => {
info!("Started ap, continuing") info!("Started ap, continuing")
} }
@ -274,8 +280,6 @@ async fn safe_main() -> anyhow::Result<()> {
// }; // };
let _timezone = Tz::UTC; let _timezone = Tz::UTC;
drop(board);
let timezone_time = cur; //TODO.with_timezone(&timezone); let timezone_time = cur; //TODO.with_timezone(&timezone);
info!( info!(
"Running logic at utc {} and {} {}", "Running logic at utc {} and {} {}",
@ -283,9 +287,9 @@ async fn safe_main() -> anyhow::Result<()> {
); );
if let NetworkMode::WIFI { ref ip_address, .. } = network_mode { if let NetworkMode::WIFI { ref ip_address, .. } = network_mode {
publish_firmware_info(version, ip_address, &timezone_time.to_rfc3339()).await; publish_firmware_info(&mut board, version, ip_address, &timezone_time.to_rfc3339()).await;
publish_battery_state().await; publish_battery_state(&mut board).await;
let _ = publish_mppt_state().await; let _ = publish_mppt_state(&mut board).await;
} }
log( log(
@ -312,7 +316,8 @@ async fn safe_main() -> anyhow::Result<()> {
let reboot_now = Arc::new(AtomicBool::new(false)); let reboot_now = Arc::new(AtomicBool::new(false));
//TODO //TODO
//let _webserver = httpd(reboot_now.clone()); //let _webserver = httpd(reboot_now.clone());
wait_infinity(WaitType::ConfigButton, reboot_now.clone()).await; let board = BOARD_ACCESS.get().await.lock().await;
wait_infinity(board, WaitType::ConfigButton, reboot_now.clone()).await;
} else { } else {
log(LogMessage::NormalRun, 0, 0, "", "").await; log(LogMessage::NormalRun, 0, 0, "", "").await;
} }
@ -589,11 +594,10 @@ async fn safe_main() -> anyhow::Result<()> {
if stay_alive { if stay_alive {
info!("Go to stay alive move"); info!("Go to stay alive move");
drop(board);
let reboot_now = Arc::new(AtomicBool::new(false)); let reboot_now = Arc::new(AtomicBool::new(false));
//TODO //TODO
//let _webserver = httpd(reboot_now.clone()); //let _webserver = httpd(reboot_now.clone());
wait_infinity(WaitType::MqttConfig, reboot_now.clone()).await; wait_infinity(board, WaitType::MqttConfig, reboot_now.clone()).await;
} else { } else {
board.board_hal.get_esp().set_restart_to_conf(false); board.board_hal.get_esp().set_restart_to_conf(false);
board board
@ -831,8 +835,12 @@ async fn update_charge_indicator(board: &mut MutexGuard<'_, CriticalSectionRawMu
// } // }
// } // }
async fn publish_firmware_info(version: VersionInfo, ip_address: &String, timezone_time: &String) { async fn publish_firmware_info(
let board = &mut BOARD_ACCESS.get().await.lock().await; mut board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
version: VersionInfo,
ip_address: &String,
timezone_time: &String,
) {
let esp = board.board_hal.get_esp(); let esp = board.board_hal.get_esp();
let _ = esp let _ = esp
.mqtt_publish("/firmware/address", ip_address.as_bytes()) .mqtt_publish("/firmware/address", ip_address.as_bytes())
@ -952,10 +960,11 @@ async fn pump_info(
}; };
} }
async fn publish_mppt_state() -> anyhow::Result<()> { async fn publish_mppt_state(
let board_hal = &mut BOARD_ACCESS.get().await.lock().await.board_hal; board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
let current = board_hal.get_mptt_current().await?; ) -> anyhow::Result<()> {
let voltage = board_hal.get_mptt_voltage().await?; let current = board.board_hal.get_mptt_current().await?;
let voltage = board.board_hal.get_mptt_voltage().await?;
let solar_state = Solar { let solar_state = Solar {
current_ma: current.as_milliamperes() as u32, current_ma: current.as_milliamperes() as u32,
voltage_ma: voltage.as_millivolts() as u32, voltage_ma: voltage.as_millivolts() as u32,
@ -963,15 +972,17 @@ async fn publish_mppt_state() -> anyhow::Result<()> {
if let Ok(serialized_solar_state_bytes) = if let Ok(serialized_solar_state_bytes) =
serde_json::to_string(&solar_state).map(|s| s.into_bytes()) serde_json::to_string(&solar_state).map(|s| s.into_bytes())
{ {
let _ = board_hal let _ = board
.board_hal
.get_esp() .get_esp()
.mqtt_publish("/mppt", &serialized_solar_state_bytes); .mqtt_publish("/mppt", &serialized_solar_state_bytes);
} }
Ok(()) Ok(())
} }
async fn publish_battery_state() -> () { async fn publish_battery_state(
let board = &mut BOARD_ACCESS.get().await.lock().await; board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
) -> () {
let state = board let state = board
.board_hal .board_hal
.get_battery_monitor() .get_battery_monitor()
@ -983,55 +994,65 @@ async fn publish_battery_state() -> () {
board board
.board_hal .board_hal
.get_esp() .get_esp()
.mqtt_publish("/battery", &serialized_battery_state_bytes); .mqtt_publish("/battery", &serialized_battery_state_bytes)
.await;
} }
} }
async fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { async fn wait_infinity(
board: MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
wait_type: WaitType,
reboot_now: Arc<AtomicBool>,
) -> ! {
//since we force to have the lock when entering, we can release it to ensure the caller does not forget to dispose of it
drop(board);
let delay = wait_type.blink_pattern(); let delay = wait_type.blink_pattern();
let mut led_count = 8; let mut led_count = 8;
let mut pattern_step = 0; let mut pattern_step = 0;
loop { loop {
let mut board = BOARD_ACCESS.get().await.lock().await; {
update_charge_indicator(&mut board).await; let mut board = BOARD_ACCESS.get().await.lock().await;
update_charge_indicator(&mut board).await;
match wait_type { match wait_type {
WaitType::MissingConfig => { WaitType::MissingConfig => {
// Keep existing behavior: circular filling pattern // Keep existing behavior: circular filling pattern
led_count %= 8; led_count %= 8;
led_count += 1; led_count += 1;
for i in 0..8 { for i in 0..8 {
let _ = board.board_hal.fault(i, i < led_count); let _ = board.board_hal.fault(i, i < led_count);
} }
} }
WaitType::ConfigButton => { WaitType::ConfigButton => {
// Alternating pattern: 1010 1010 -> 0101 0101 // Alternating pattern: 1010 1010 -> 0101 0101
pattern_step = (pattern_step + 1) % 2; pattern_step = (pattern_step + 1) % 2;
for i in 0..8 { for i in 0..8 {
let _ = board.board_hal.fault(i, (i + pattern_step) % 2 == 0); let _ = board.board_hal.fault(i, (i + pattern_step) % 2 == 0);
} }
} }
WaitType::MqttConfig => { WaitType::MqttConfig => {
// Moving dot pattern // Moving dot pattern
pattern_step = (pattern_step + 1) % 8; pattern_step = (pattern_step + 1) % 8;
for i in 0..8 { for i in 0..8 {
let _ = board.board_hal.fault(i, i == pattern_step); let _ = board.board_hal.fault(i, i == pattern_step);
}
} }
} }
board.board_hal.general_fault(true).await;
} }
board.board_hal.general_fault(true);
drop(board);
Timer::after_millis(delay).await; Timer::after_millis(delay).await;
let mut board = BOARD_ACCESS.get().await.lock().await; {
board.board_hal.general_fault(false); let mut board = BOARD_ACCESS.get().await.lock().await;
board.board_hal.general_fault(false).await;
// Clear all LEDs // Clear all LEDs
for i in 0..8 { for i in 0..8 {
let _ = board.board_hal.fault(i, false); let _ = board.board_hal.fault(i, false);
}
} }
drop(board);
Timer::after_millis(delay).await; Timer::after_millis(delay).await;
if wait_type == WaitType::MqttConfig && !STAY_ALIVE.load(Ordering::Relaxed) { if wait_type == WaitType::MqttConfig && !STAY_ALIVE.load(Ordering::Relaxed) {
@ -1065,7 +1086,7 @@ async fn main(spawner: Spawner) {
} }
println!("Hal init done, starting logic"); println!("Hal init done, starting logic");
match safe_main().await { match safe_main(spawner).await {
// this should not get triggered, safe_main should not return but go into deep sleep with sensible // this should not get triggered, safe_main should not return but go into deep sleep with sensible
// timeout, this is just a fallback // timeout, this is just a fallback
Ok(_) => { Ok(_) => {

View File

@ -16,10 +16,12 @@ use anyhow::{bail, Context};
use chrono::DateTime; use chrono::DateTime;
use core::result::Result::Ok; use core::result::Result::Ok;
use core::sync::atomic::AtomicBool; use core::sync::atomic::AtomicBool;
use embassy_executor::Spawner;
use embassy_net::tcp::TcpSocket; use embassy_net::tcp::TcpSocket;
use embassy_net::{IpListenEndpoint, Stack}; use embassy_net::{IpListenEndpoint, Stack};
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use esp_println::{print, println}; use esp_println::{print, println};
use esp_wifi::wifi::WifiController;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
@ -388,7 +390,8 @@ pub struct NightLampCommand {
// } // }
// } // }
pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'_>) { #[embassy_executor::task]
pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
let mut rx_buffer = [0; 1536]; let mut rx_buffer = [0; 1536];
let mut tx_buffer = [0; 1536]; let mut tx_buffer = [0; 1536];
println!("Stack {}", stack.is_config_up()); println!("Stack {}", stack.is_config_up());