minimal startup running
This commit is contained in:
		@@ -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() {
 | 
			
		||||
            Ok(config) => config.network.ap_ssid.clone(),
 | 
			
		||||
            Err(_) => heapless::String::from_str("PlantCtrl Emergency Mode").unwrap(),
 | 
			
		||||
@@ -207,7 +207,7 @@ impl Esp<'_> {
 | 
			
		||||
        let controller = self.controller.take().unwrap();
 | 
			
		||||
        spawner.spawn(connection(controller)).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 {
 | 
			
		||||
            if stack.is_link_up() {
 | 
			
		||||
@@ -699,7 +699,7 @@ impl Esp<'_> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[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 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 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
 | 
			
		||||
        .bind(core::net::SocketAddr::V4(SocketAddrV4::new(
 | 
			
		||||
            Ipv4Addr::UNSPECIFIED,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,12 @@ use crate::{
 | 
			
		||||
use anyhow::{bail, Result};
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use chrono::{DateTime, Utc};
 | 
			
		||||
use esp_hal::gpio::{Level, Output, OutputConfig};
 | 
			
		||||
use log::info;
 | 
			
		||||
use measurements::{Current, Voltage};
 | 
			
		||||
 | 
			
		||||
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) config: PlantControllerConfig,
 | 
			
		||||
    pub(crate) battery: Box<dyn BatteryInteraction + Send>,
 | 
			
		||||
@@ -47,21 +49,14 @@ impl RTCModuleInteraction for NoRTC {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) fn create_initial_board(
 | 
			
		||||
    //free_pins: FreePeripherals,
 | 
			
		||||
    _fs_mount_error: bool,
 | 
			
		||||
    free_pins: FreePeripherals<'static>,
 | 
			
		||||
    config: PlantControllerConfig,
 | 
			
		||||
    esp: Esp<'static>,
 | 
			
		||||
) -> Result<Box<dyn BoardInteraction<'static> + Send>> {
 | 
			
		||||
    log::info!("Start initial");
 | 
			
		||||
    // let mut general_fault = PinDriver::input_output(free_pins.gpio6.downgrade())?;
 | 
			
		||||
    // general_fault.set_pull(Pull::Floating)?;
 | 
			
		||||
    // general_fault.set_low()?;
 | 
			
		||||
    //
 | 
			
		||||
    // if fs_mount_error {
 | 
			
		||||
    //     general_fault.set_high()?
 | 
			
		||||
    // }
 | 
			
		||||
    let general_fault = Output::new(free_pins.gpio23, Level::Low, OutputConfig::default());
 | 
			
		||||
    let v = Initial {
 | 
			
		||||
        //general_fault,
 | 
			
		||||
        general_fault,
 | 
			
		||||
        config,
 | 
			
		||||
        esp,
 | 
			
		||||
        battery: Box::new(NoBatteryMonitor {}),
 | 
			
		||||
@@ -122,8 +117,8 @@ impl<'a> BoardInteraction<'a> for Initial<'a> {
 | 
			
		||||
        bail!("Please configure board revision")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn general_fault(&mut self, _enable: bool) {
 | 
			
		||||
        //let _ = self.general_fault.set_state(enable.into());
 | 
			
		||||
    async fn general_fault(&mut self, enable: bool) {
 | 
			
		||||
        self.general_fault.set_level(enable.into());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn test(&mut self) -> Result<()> {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,10 @@ mod rtc;
 | 
			
		||||
 | 
			
		||||
use crate::alloc::string::ToString;
 | 
			
		||||
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::{
 | 
			
		||||
    config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig},
 | 
			
		||||
@@ -33,7 +37,7 @@ use embassy_sync::once_lock::OnceLock;
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_bootloader_esp_idf::partitions::DataPartitionSubType;
 | 
			
		||||
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_println::{print, println};
 | 
			
		||||
use measurements::{Current, Voltage};
 | 
			
		||||
@@ -41,6 +45,7 @@ use measurements::{Current, Voltage};
 | 
			
		||||
use embassy_sync::mutex::{Mutex, MutexGuard};
 | 
			
		||||
use esp_alloc as _;
 | 
			
		||||
use esp_backtrace as _;
 | 
			
		||||
use esp_hal::analog::adc::Adc;
 | 
			
		||||
use esp_hal::rng::Rng;
 | 
			
		||||
use esp_hal::timer::timg::TimerGroup;
 | 
			
		||||
use esp_wifi::wifi::{
 | 
			
		||||
@@ -125,14 +130,14 @@ impl dyn BoardInteraction<'_> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(dead_code)]
 | 
			
		||||
pub struct FreePeripherals {
 | 
			
		||||
pub struct FreePeripherals<'a> {
 | 
			
		||||
    // pub gpio0: Gpio0,
 | 
			
		||||
    // pub gpio1: Gpio1,
 | 
			
		||||
    // pub gpio2: Gpio2,
 | 
			
		||||
    // pub gpio3: Gpio3,
 | 
			
		||||
    // pub gpio4: Gpio4,
 | 
			
		||||
    // pub gpio5: Gpio5,
 | 
			
		||||
    // pub gpio6: Gpio6,
 | 
			
		||||
    pub gpio6: GPIO6<'a>,
 | 
			
		||||
    // pub gpio7: Gpio7,
 | 
			
		||||
    // pub gpio8: Gpio8,
 | 
			
		||||
    // //config button here
 | 
			
		||||
@@ -148,7 +153,7 @@ pub struct FreePeripherals {
 | 
			
		||||
    // //i2c here
 | 
			
		||||
    // pub gpio21: Gpio21,
 | 
			
		||||
    // pub gpio22: Gpio22,
 | 
			
		||||
    // pub gpio23: Gpio23,
 | 
			
		||||
    pub gpio23: GPIO23<'a>,
 | 
			
		||||
    // pub gpio24: Gpio24,
 | 
			
		||||
    // pub gpio25: Gpio25,
 | 
			
		||||
    // pub gpio26: Gpio26,
 | 
			
		||||
@@ -192,7 +197,7 @@ impl PlantHal {
 | 
			
		||||
 | 
			
		||||
    pub async fn create(spawner: Spawner) -> Result<Mutex<CriticalSectionRawMutex, HAL<'static>>> {
 | 
			
		||||
        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);
 | 
			
		||||
        let systimer = SystemTimer::new(peripherals.SYSTIMER);
 | 
			
		||||
@@ -215,41 +220,42 @@ impl PlantHal {
 | 
			
		||||
        use esp_hal::timer::systimer::SystemTimer;
 | 
			
		||||
        esp_hal_embassy::init(systimer.alarm0);
 | 
			
		||||
 | 
			
		||||
        //let mut adc1 = Adc::new(peripherals.ADC1, adc1_config);
 | 
			
		||||
        //
 | 
			
		||||
        // let free_pins = FreePeripherals {
 | 
			
		||||
        //     can: peripherals.can,
 | 
			
		||||
        //     adc1: peripherals.adc1,
 | 
			
		||||
        //     pcnt0: peripherals.pcnt0,
 | 
			
		||||
        //     pcnt1: peripherals.pcnt1,
 | 
			
		||||
        //     gpio0: peripherals.pins.gpio0,
 | 
			
		||||
        //     gpio1: peripherals.pins.gpio1,
 | 
			
		||||
        //     gpio2: peripherals.pins.gpio2,
 | 
			
		||||
        //     gpio3: peripherals.pins.gpio3,
 | 
			
		||||
        //     gpio4: peripherals.pins.gpio4,
 | 
			
		||||
        //     gpio5: peripherals.pins.gpio5,
 | 
			
		||||
        //     gpio6: peripherals.pins.gpio6,
 | 
			
		||||
        //     gpio7: peripherals.pins.gpio7,
 | 
			
		||||
        //     gpio8: peripherals.pins.gpio8,
 | 
			
		||||
        //     gpio10: peripherals.pins.gpio10,
 | 
			
		||||
        //     gpio11: peripherals.pins.gpio11,
 | 
			
		||||
        //     gpio12: peripherals.pins.gpio12,
 | 
			
		||||
        //     gpio13: peripherals.pins.gpio13,
 | 
			
		||||
        //     gpio14: peripherals.pins.gpio14,
 | 
			
		||||
        //     gpio15: peripherals.pins.gpio15,
 | 
			
		||||
        //     gpio16: peripherals.pins.gpio16,
 | 
			
		||||
        //     gpio17: peripherals.pins.gpio17,
 | 
			
		||||
        //     gpio18: peripherals.pins.gpio18,
 | 
			
		||||
        //     gpio21: peripherals.pins.gpio21,
 | 
			
		||||
        //     gpio22: peripherals.pins.gpio22,
 | 
			
		||||
        //     gpio23: peripherals.pins.gpio23,
 | 
			
		||||
        //     gpio24: peripherals.pins.gpio24,
 | 
			
		||||
        //     gpio25: peripherals.pins.gpio25,
 | 
			
		||||
        //     gpio26: peripherals.pins.gpio26,
 | 
			
		||||
        //     gpio27: peripherals.pins.gpio27,
 | 
			
		||||
        //     gpio28: peripherals.pins.gpio28,
 | 
			
		||||
        //     gpio29: peripherals.pins.gpio29,
 | 
			
		||||
        //     gpio30: peripherals.pins.gpio30,
 | 
			
		||||
        // };
 | 
			
		||||
        let free_pins = FreePeripherals {
 | 
			
		||||
            //     can: peripherals.can,
 | 
			
		||||
            //     adc1: peripherals.adc1,
 | 
			
		||||
            //     pcnt0: peripherals.pcnt0,
 | 
			
		||||
            //     pcnt1: peripherals.pcnt1,
 | 
			
		||||
            //     gpio0: peripherals.pins.gpio0,
 | 
			
		||||
            //     gpio1: peripherals.pins.gpio1,
 | 
			
		||||
            //     gpio2: peripherals.pins.gpio2,
 | 
			
		||||
            //     gpio3: peripherals.pins.gpio3,
 | 
			
		||||
            //     gpio4: peripherals.pins.gpio4,
 | 
			
		||||
            //     gpio5: peripherals.pins.gpio5,
 | 
			
		||||
            gpio6: peripherals.GPIO6,
 | 
			
		||||
            //     gpio7: peripherals.pins.gpio7,
 | 
			
		||||
            //     gpio8: peripherals.pins.gpio8,
 | 
			
		||||
            //     gpio10: peripherals.pins.gpio10,
 | 
			
		||||
            //     gpio11: peripherals.pins.gpio11,
 | 
			
		||||
            //     gpio12: peripherals.pins.gpio12,
 | 
			
		||||
            //     gpio13: peripherals.pins.gpio13,
 | 
			
		||||
            //     gpio14: peripherals.pins.gpio14,
 | 
			
		||||
            //     gpio15: peripherals.pins.gpio15,
 | 
			
		||||
            //     gpio16: peripherals.pins.gpio16,
 | 
			
		||||
            //     gpio17: peripherals.pins.gpio17,
 | 
			
		||||
            //     gpio18: peripherals.pins.gpio18,
 | 
			
		||||
            //     gpio21: peripherals.pins.gpio21,
 | 
			
		||||
            //     gpio22: peripherals.pins.gpio22,
 | 
			
		||||
            gpio23: peripherals.GPIO23,
 | 
			
		||||
            //     gpio24: peripherals.pins.gpio24,
 | 
			
		||||
            //     gpio25: peripherals.pins.gpio25,
 | 
			
		||||
            //     gpio26: peripherals.pins.gpio26,
 | 
			
		||||
            //     gpio27: peripherals.pins.gpio27,
 | 
			
		||||
            //     gpio28: peripherals.pins.gpio28,
 | 
			
		||||
            //     gpio29: peripherals.pins.gpio29,
 | 
			
		||||
            //     gpio30: peripherals.pins.gpio30,
 | 
			
		||||
        };
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
        let mut storage = esp_storage::FlashStorage::new();
 | 
			
		||||
@@ -392,7 +398,7 @@ impl PlantHal {
 | 
			
		||||
 | 
			
		||||
                let board_hal: Box<dyn BoardInteraction + Send> = match config.hardware.board {
 | 
			
		||||
                    BoardVersion::INITIAL => {
 | 
			
		||||
                        initial_hal::create_initial_board(fs_mount_error, config, esp)?
 | 
			
		||||
                        initial_hal::create_initial_board(free_pins, config, esp)?
 | 
			
		||||
                    }
 | 
			
		||||
                    // BoardVersion::V3 => {
 | 
			
		||||
                    //     v3_hal::create_v3(free_pins, esp, config, battery_interaction, rtc_module)?
 | 
			
		||||
@@ -417,7 +423,7 @@ impl PlantHal {
 | 
			
		||||
                );
 | 
			
		||||
                HAL {
 | 
			
		||||
                    board_hal: initial_hal::create_initial_board(
 | 
			
		||||
                        fs_mount_error,
 | 
			
		||||
                        free_pins,
 | 
			
		||||
                        PlantControllerConfig::default(),
 | 
			
		||||
                        esp,
 | 
			
		||||
                    )?,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
 | 
			
		||||
use embassy_sync::lazy_lock::LazyLock;
 | 
			
		||||
use embassy_sync::mutex::Mutex;
 | 
			
		||||
use embassy_time::Instant;
 | 
			
		||||
use esp_println::println;
 | 
			
		||||
use log::info;
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use strum_macros::IntoStaticStr;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										141
									
								
								rust/src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								rust/src/main.rs
									
									
									
									
									
								
							@@ -64,7 +64,7 @@ mod webserver;
 | 
			
		||||
extern crate alloc;
 | 
			
		||||
//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);
 | 
			
		||||
 | 
			
		||||
@@ -143,7 +143,7 @@ enum NetworkMode {
 | 
			
		||||
    OFFLINE,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
async fn safe_main(spawner: Spawner) -> anyhow::Result<()> {
 | 
			
		||||
    info!("Startup Rust");
 | 
			
		||||
 | 
			
		||||
    let mut to_config = false;
 | 
			
		||||
@@ -179,10 +179,8 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
    //};
 | 
			
		||||
    //log(LogMessage::PartitionState, 0, 0, "", ota_state_string);
 | 
			
		||||
    let _ota_state_string = "unknown";
 | 
			
		||||
    println!("faul led");
 | 
			
		||||
    let mut board = BOARD_ACCESS.get().await.lock().await;
 | 
			
		||||
    board.board_hal.general_fault(false).await;
 | 
			
		||||
    println!("faul led2");
 | 
			
		||||
    let cur = board
 | 
			
		||||
        .board_hal
 | 
			
		||||
        .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)
 | 
			
		||||
    if cur.year() < 2020 {
 | 
			
		||||
        to_config = true;
 | 
			
		||||
        log(LogMessage::YearInplausibleForceConfig, 0, 0, "", "");
 | 
			
		||||
        log(LogMessage::YearInplausibleForceConfig, 0, 0, "", "").await;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    info!("cur is {}", cur);
 | 
			
		||||
@@ -237,12 +235,15 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
        && board.board_hal.get_config().network.ssid.is_none()
 | 
			
		||||
    {
 | 
			
		||||
        info!("No wifi configured, starting initial config mode");
 | 
			
		||||
 | 
			
		||||
        let stack = board.board_hal.get_esp().wifi_ap().await?;
 | 
			
		||||
 | 
			
		||||
        let reboot_now = Arc::new(AtomicBool::new(false));
 | 
			
		||||
        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");
 | 
			
		||||
@@ -257,7 +258,12 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
 | 
			
		||||
    if matches!(network_mode, NetworkMode::OFFLINE) && to_config {
 | 
			
		||||
        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(_) => {
 | 
			
		||||
                info!("Started ap, continuing")
 | 
			
		||||
            }
 | 
			
		||||
@@ -274,8 +280,6 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
    // };
 | 
			
		||||
    let _timezone = Tz::UTC;
 | 
			
		||||
 | 
			
		||||
    drop(board);
 | 
			
		||||
 | 
			
		||||
    let timezone_time = cur; //TODO.with_timezone(&timezone);
 | 
			
		||||
    info!(
 | 
			
		||||
        "Running logic at utc {} and {} {}",
 | 
			
		||||
@@ -283,9 +287,9 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if let NetworkMode::WIFI { ref ip_address, .. } = network_mode {
 | 
			
		||||
        publish_firmware_info(version, ip_address, &timezone_time.to_rfc3339()).await;
 | 
			
		||||
        publish_battery_state().await;
 | 
			
		||||
        let _ = publish_mppt_state().await;
 | 
			
		||||
        publish_firmware_info(&mut board, version, ip_address, &timezone_time.to_rfc3339()).await;
 | 
			
		||||
        publish_battery_state(&mut board).await;
 | 
			
		||||
        let _ = publish_mppt_state(&mut board).await;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    log(
 | 
			
		||||
@@ -312,7 +316,8 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
        let reboot_now = Arc::new(AtomicBool::new(false));
 | 
			
		||||
        //TODO
 | 
			
		||||
        //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 {
 | 
			
		||||
        log(LogMessage::NormalRun, 0, 0, "", "").await;
 | 
			
		||||
    }
 | 
			
		||||
@@ -589,11 +594,10 @@ async fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
 | 
			
		||||
    if stay_alive {
 | 
			
		||||
        info!("Go to stay alive move");
 | 
			
		||||
        drop(board);
 | 
			
		||||
        let reboot_now = Arc::new(AtomicBool::new(false));
 | 
			
		||||
        //TODO
 | 
			
		||||
        //let _webserver = httpd(reboot_now.clone());
 | 
			
		||||
        wait_infinity(WaitType::MqttConfig, reboot_now.clone()).await;
 | 
			
		||||
        wait_infinity(board, WaitType::MqttConfig, reboot_now.clone()).await;
 | 
			
		||||
    } else {
 | 
			
		||||
        board.board_hal.get_esp().set_restart_to_conf(false);
 | 
			
		||||
        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) {
 | 
			
		||||
    let board = &mut BOARD_ACCESS.get().await.lock().await;
 | 
			
		||||
async fn publish_firmware_info(
 | 
			
		||||
    mut board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
 | 
			
		||||
    version: VersionInfo,
 | 
			
		||||
    ip_address: &String,
 | 
			
		||||
    timezone_time: &String,
 | 
			
		||||
) {
 | 
			
		||||
    let esp = board.board_hal.get_esp();
 | 
			
		||||
    let _ = esp
 | 
			
		||||
        .mqtt_publish("/firmware/address", ip_address.as_bytes())
 | 
			
		||||
@@ -952,10 +960,11 @@ async fn pump_info(
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn publish_mppt_state() -> anyhow::Result<()> {
 | 
			
		||||
    let board_hal = &mut BOARD_ACCESS.get().await.lock().await.board_hal;
 | 
			
		||||
    let current = board_hal.get_mptt_current().await?;
 | 
			
		||||
    let voltage = board_hal.get_mptt_voltage().await?;
 | 
			
		||||
async fn publish_mppt_state(
 | 
			
		||||
    board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
 | 
			
		||||
) -> anyhow::Result<()> {
 | 
			
		||||
    let current = board.board_hal.get_mptt_current().await?;
 | 
			
		||||
    let voltage = board.board_hal.get_mptt_voltage().await?;
 | 
			
		||||
    let solar_state = Solar {
 | 
			
		||||
        current_ma: current.as_milliamperes() 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) =
 | 
			
		||||
        serde_json::to_string(&solar_state).map(|s| s.into_bytes())
 | 
			
		||||
    {
 | 
			
		||||
        let _ = board_hal
 | 
			
		||||
        let _ = board
 | 
			
		||||
            .board_hal
 | 
			
		||||
            .get_esp()
 | 
			
		||||
            .mqtt_publish("/mppt", &serialized_solar_state_bytes);
 | 
			
		||||
    }
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn publish_battery_state() -> () {
 | 
			
		||||
    let board = &mut BOARD_ACCESS.get().await.lock().await;
 | 
			
		||||
async fn publish_battery_state(
 | 
			
		||||
    board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
 | 
			
		||||
) -> () {
 | 
			
		||||
    let state = board
 | 
			
		||||
        .board_hal
 | 
			
		||||
        .get_battery_monitor()
 | 
			
		||||
@@ -983,55 +994,65 @@ async fn publish_battery_state() -> () {
 | 
			
		||||
        board
 | 
			
		||||
            .board_hal
 | 
			
		||||
            .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 mut led_count = 8;
 | 
			
		||||
    let mut pattern_step = 0;
 | 
			
		||||
    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 {
 | 
			
		||||
            WaitType::MissingConfig => {
 | 
			
		||||
                // Keep existing behavior: circular filling pattern
 | 
			
		||||
                led_count %= 8;
 | 
			
		||||
                led_count += 1;
 | 
			
		||||
                for i in 0..8 {
 | 
			
		||||
                    let _ = board.board_hal.fault(i, i < led_count);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            WaitType::ConfigButton => {
 | 
			
		||||
                // Alternating pattern: 1010 1010 -> 0101 0101
 | 
			
		||||
                pattern_step = (pattern_step + 1) % 2;
 | 
			
		||||
                for i in 0..8 {
 | 
			
		||||
                    let _ = board.board_hal.fault(i, (i + pattern_step) % 2 == 0);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            WaitType::MqttConfig => {
 | 
			
		||||
                // Moving dot pattern
 | 
			
		||||
                pattern_step = (pattern_step + 1) % 8;
 | 
			
		||||
                for i in 0..8 {
 | 
			
		||||
                    let _ = board.board_hal.fault(i, i == pattern_step);
 | 
			
		||||
            match wait_type {
 | 
			
		||||
                WaitType::MissingConfig => {
 | 
			
		||||
                    // Keep existing behavior: circular filling pattern
 | 
			
		||||
                    led_count %= 8;
 | 
			
		||||
                    led_count += 1;
 | 
			
		||||
                    for i in 0..8 {
 | 
			
		||||
                        let _ = board.board_hal.fault(i, i < led_count);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                WaitType::ConfigButton => {
 | 
			
		||||
                    // Alternating pattern: 1010 1010 -> 0101 0101
 | 
			
		||||
                    pattern_step = (pattern_step + 1) % 2;
 | 
			
		||||
                    for i in 0..8 {
 | 
			
		||||
                        let _ = board.board_hal.fault(i, (i + pattern_step) % 2 == 0);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                WaitType::MqttConfig => {
 | 
			
		||||
                    // Moving dot pattern
 | 
			
		||||
                    pattern_step = (pattern_step + 1) % 8;
 | 
			
		||||
                    for i in 0..8 {
 | 
			
		||||
                        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;
 | 
			
		||||
        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
 | 
			
		||||
        for i in 0..8 {
 | 
			
		||||
            let _ = board.board_hal.fault(i, false);
 | 
			
		||||
            // Clear all LEDs
 | 
			
		||||
            for i in 0..8 {
 | 
			
		||||
                let _ = board.board_hal.fault(i, false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        drop(board);
 | 
			
		||||
 | 
			
		||||
        Timer::after_millis(delay).await;
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
        // timeout, this is just a fallback
 | 
			
		||||
        Ok(_) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,12 @@ use anyhow::{bail, Context};
 | 
			
		||||
use chrono::DateTime;
 | 
			
		||||
use core::result::Result::Ok;
 | 
			
		||||
use core::sync::atomic::AtomicBool;
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::tcp::TcpSocket;
 | 
			
		||||
use embassy_net::{IpListenEndpoint, Stack};
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_println::{print, println};
 | 
			
		||||
use esp_wifi::wifi::WifiController;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
#[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 tx_buffer = [0; 1536];
 | 
			
		||||
    println!("Stack {}", stack.is_config_up());
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user