keep ota around for alter queries to it
This commit is contained in:
@@ -7,7 +7,7 @@ use chrono::{DateTime, Utc};
|
||||
use serde::Serialize;
|
||||
|
||||
use alloc::string::ToString;
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use alloc::{format, string::String, vec::Vec};
|
||||
use core::marker::PhantomData;
|
||||
use core::net::{IpAddr, Ipv4Addr};
|
||||
use core::str::FromStr;
|
||||
@@ -15,15 +15,18 @@ use embassy_executor::{SendSpawner, Spawner};
|
||||
use embassy_net::tcp::TcpSocket;
|
||||
use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use esp_bootloader_esp_idf::ota::OtaImageState;
|
||||
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState, Slot};
|
||||
use esp_bootloader_esp_idf::partitions::{Error, FlashRegion, PartitionEntry, PartitionTable};
|
||||
use esp_hal::gpio::Input;
|
||||
use esp_hal::rng::Rng;
|
||||
use esp_hal::rtc_cntl::sleep::RtcSleepConfig;
|
||||
use esp_println::{print, println};
|
||||
use esp_storage::FlashStorage;
|
||||
use esp_wifi::wifi::{
|
||||
AccessPointConfiguration, Configuration, Interfaces, WifiController, WifiDevice, WifiEvent,
|
||||
WifiState,
|
||||
};
|
||||
use log::{info, warn};
|
||||
|
||||
#[link_section = ".rtc.data"]
|
||||
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
|
||||
@@ -72,11 +75,8 @@ pub struct Esp<'a> {
|
||||
pub boot_button: Input<'a>,
|
||||
pub(crate) wall_clock_offset: u64,
|
||||
|
||||
pub storage: FlashStorage,
|
||||
pub slot: usize,
|
||||
pub next_slot: usize,
|
||||
pub ota_state: OtaImageState,
|
||||
pub slot_addres: u32,
|
||||
pub ota: Ota<'static, FlashStorage>,
|
||||
pub ota_next: &'static PartitionEntry<'static>,
|
||||
}
|
||||
|
||||
pub struct IpInfo {
|
||||
@@ -103,6 +103,36 @@ impl Esp<'_> {
|
||||
const CONFIG_FILE: &'static str = "/spiffs/config.cfg";
|
||||
const BASE_PATH: &'static str = "/spiffs";
|
||||
|
||||
pub(crate) fn get_ota_slot(&mut self) -> String {
|
||||
match self.ota.current_slot() {
|
||||
Ok(slot) => {
|
||||
format!("{:?}", slot)
|
||||
}
|
||||
Err(err) => {
|
||||
format!("{:?}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_ota_state(&mut self) -> String {
|
||||
match self.ota.current_ota_state() {
|
||||
Ok(state) => {
|
||||
format!("{:?}", state)
|
||||
}
|
||||
Err(err) => {
|
||||
format!("{:?}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let current = ota.current_slot()?;
|
||||
// println!(
|
||||
// "current image state {:?} (only relevant if the bootloader was built with auto-rollback support)",
|
||||
// ota.current_ota_state()
|
||||
// );
|
||||
// println!("current {:?} - next {:?}", current, current.next());
|
||||
// let ota_state = ota.current_ota_state()?;
|
||||
|
||||
pub(crate) fn mode_override_pressed(&mut self) -> bool {
|
||||
self.boot_button.is_low()
|
||||
}
|
||||
@@ -119,6 +149,14 @@ impl Esp<'_> {
|
||||
//self.time()
|
||||
todo!();
|
||||
}
|
||||
|
||||
pub async fn flash_ota(&mut self) -> anyhow::Result<()> {
|
||||
let mut storage_ota_next = FlashStorage::new();
|
||||
let ota_next = self.ota_next.as_embedded_storage(&mut storage_ota_next);
|
||||
|
||||
bail!("not implemented")
|
||||
}
|
||||
|
||||
pub(crate) fn time(&mut self) -> DateTime<Utc> {
|
||||
let wall_clock = Instant::now().as_millis() + self.wall_clock_offset;
|
||||
DateTime::from_timestamp_millis(wall_clock as i64).unwrap()
|
||||
@@ -231,6 +269,36 @@ impl Esp<'_> {
|
||||
anyhow::Ok(stack.clone())
|
||||
}
|
||||
|
||||
pub async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
||||
let mut cfg = RtcSleepConfig::deep();
|
||||
|
||||
let cur = self.ota.current_ota_state().unwrap();
|
||||
//we made it till here, so fine
|
||||
if cur == OtaImageState::PendingVerify {
|
||||
self.ota
|
||||
.set_current_ota_state(OtaImageState::Valid)
|
||||
.expect("Could not set image to valid");
|
||||
}
|
||||
//unsafe {
|
||||
// //allow early wakeup by pressing the boot button
|
||||
if duration_in_ms == 0 {
|
||||
loop {
|
||||
info!("todo reboot")
|
||||
}
|
||||
} else {
|
||||
loop {
|
||||
info!("todo deepsleep")
|
||||
}
|
||||
// //configure gpio 1 to wakeup on low, reused boot button for this
|
||||
// esp_sleep_enable_ext1_wakeup(
|
||||
// 0b10u64,
|
||||
// esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW,
|
||||
// );
|
||||
// esp_deep_sleep(duration_in_ms);
|
||||
}
|
||||
//};
|
||||
}
|
||||
|
||||
pub(crate) async fn wifi(&mut self, network_config: &NetworkConfig) -> anyhow::Result<IpInfo> {
|
||||
let _ssid = network_config
|
||||
.ssid
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::hal::rtc::{BackupHeader, RTCModuleInteraction};
|
||||
use alloc::vec::Vec;
|
||||
//use crate::hal::water::TankSensor;
|
||||
use crate::alloc::boxed::Box;
|
||||
use crate::hal::{deep_sleep, BoardInteraction, FreePeripherals, Sensor};
|
||||
use crate::hal::{BoardInteraction, FreePeripherals, Sensor};
|
||||
use crate::{
|
||||
config::PlantControllerConfig,
|
||||
hal::battery::{BatteryInteraction, NoBatteryMonitor},
|
||||
@@ -91,8 +91,8 @@ impl<'a> BoardInteraction<'a> for Initial<'a> {
|
||||
bail!("Please configure board revision")
|
||||
}
|
||||
|
||||
fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
||||
deep_sleep(duration_in_ms)
|
||||
async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
||||
self.esp.deep_sleep(duration_in_ms).await;
|
||||
}
|
||||
fn is_day(&self) -> bool {
|
||||
false
|
||||
|
||||
@@ -23,36 +23,25 @@ use alloc::boxed::Box;
|
||||
use alloc::format;
|
||||
use anyhow::{Ok, Result};
|
||||
use async_trait::async_trait;
|
||||
use core::cell::OnceCell;
|
||||
use core::marker::PhantomData;
|
||||
use core::net::Ipv4Addr;
|
||||
use core::str::FromStr;
|
||||
use embassy_executor::{SendSpawner, Spawner};
|
||||
use embassy_net::tcp::{Error, TcpSocket};
|
||||
use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||
use embassy_executor::Spawner;
|
||||
//use battery::BQ34Z100G1;
|
||||
//use bq34z100::Bq34z100g1Driver;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::once_lock::OnceLock;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_bootloader_esp_idf::partitions::{
|
||||
AppPartitionSubType, DataPartitionSubType, PartitionEntry,
|
||||
AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry,
|
||||
};
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::gpio::{Input, InputConfig, Io, Pull};
|
||||
use esp_hal::timer::systimer::SystemTimer;
|
||||
use esp_println::{print, println};
|
||||
use esp_println::println;
|
||||
use measurements::{Current, Voltage};
|
||||
|
||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::analog::adc::Adc;
|
||||
use esp_bootloader_esp_idf::ota::Slot;
|
||||
use esp_hal::rng::Rng;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_wifi::wifi::{
|
||||
AccessPointConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiState,
|
||||
};
|
||||
use esp_storage::FlashStorage;
|
||||
use esp_wifi::{init, EspWifiController};
|
||||
|
||||
//Only support for 8 right now!
|
||||
@@ -62,27 +51,6 @@ const TANK_MULTI_SAMPLE: usize = 11;
|
||||
|
||||
//pub static I2C_DRIVER: LazyLock<Mutex<CriticalSectionRawMutex,I2cDriver<'static>>> = LazyLock::new(PlantHal::create_i2c);
|
||||
|
||||
fn deep_sleep(_duration_in_ms: u64) -> ! {
|
||||
//unsafe {
|
||||
// //if we don't do this here, we might just revert newly flashed firmware
|
||||
// mark_app_valid();
|
||||
// //allow early wakeup by pressing the boot button
|
||||
// if duration_in_ms == 0 {
|
||||
// esp_restart();
|
||||
// } else {
|
||||
// //configure gpio 1 to wakeup on low, reused boot button for this
|
||||
// esp_sleep_enable_ext1_wakeup(
|
||||
// 0b10u64,
|
||||
// esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW,
|
||||
// );
|
||||
// esp_deep_sleep(duration_in_ms);
|
||||
// }
|
||||
loop {
|
||||
todo!()
|
||||
}
|
||||
//};
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Sensor {
|
||||
A,
|
||||
@@ -103,7 +71,7 @@ pub trait BoardInteraction<'a> {
|
||||
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
|
||||
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
|
||||
fn set_charge_indicator(&mut self, charging: bool) -> Result<()>;
|
||||
fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
|
||||
async fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
|
||||
|
||||
fn is_day(&self) -> bool;
|
||||
//should be multsampled
|
||||
@@ -209,14 +177,14 @@ impl PlantHal {
|
||||
InputConfig::default().with_pull(Pull::None),
|
||||
);
|
||||
|
||||
let mut rng = Rng::new(peripherals.RNG);
|
||||
let rng = Rng::new(peripherals.RNG);
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let esp_wifi_ctrl = &*mk_static!(
|
||||
EspWifiController<'static>,
|
||||
init(timg0.timer0, rng.clone()).unwrap()
|
||||
);
|
||||
|
||||
let (mut controller, interfaces) =
|
||||
let (controller, interfaces) =
|
||||
esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap();
|
||||
|
||||
use esp_hal::timer::systimer::SystemTimer;
|
||||
@@ -260,62 +228,60 @@ impl PlantHal {
|
||||
};
|
||||
//
|
||||
|
||||
let mut storage = esp_storage::FlashStorage::new();
|
||||
let mut buffer = [0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN];
|
||||
let tablebuffer: [u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN] =
|
||||
[0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN];
|
||||
let tablebuffer = mk_static!(
|
||||
[u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN],
|
||||
tablebuffer
|
||||
);
|
||||
let storage_ota = mk_static!(FlashStorage, FlashStorage::new());
|
||||
let pt =
|
||||
esp_bootloader_esp_idf::partitions::read_partition_table(&mut storage, &mut buffer)?;
|
||||
esp_bootloader_esp_idf::partitions::read_partition_table(storage_ota, tablebuffer)?;
|
||||
|
||||
// List all partitions - this is just FYI
|
||||
for i in 0..pt.len() {
|
||||
println!("{:?}", pt.get_partition(i));
|
||||
}
|
||||
|
||||
// Find the OTA-data partition and show the currently active partition
|
||||
let ota_part = pt
|
||||
let ota_data = pt
|
||||
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::Data(
|
||||
DataPartitionSubType::Ota,
|
||||
))?
|
||||
.unwrap();
|
||||
let mut ota_part = ota_part.as_embedded_storage(&mut storage);
|
||||
println!("Found ota data");
|
||||
|
||||
let mut ota = esp_bootloader_esp_idf::ota::Ota::new(&mut ota_part)?;
|
||||
let current = ota.current_slot()?;
|
||||
println!(
|
||||
"current image state {:?} (only relevant if the bootloader was built with auto-rollback support)",
|
||||
ota.current_ota_state()
|
||||
);
|
||||
println!("current {:?} - next {:?}", current, current.next());
|
||||
let ota_state = ota.current_ota_state()?;
|
||||
let ota_data = mk_static!(PartitionEntry, ota_data);
|
||||
|
||||
let current_app = if current.number() == 0 {
|
||||
pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||
AppPartitionSubType::Ota0,
|
||||
))
|
||||
} else {
|
||||
pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||
AppPartitionSubType::Ota1,
|
||||
))
|
||||
};
|
||||
let app_address = match current_app {
|
||||
Result::Ok(part) => match part {
|
||||
None => 0,
|
||||
Some(entry) => entry.offset(),
|
||||
},
|
||||
Err(_) => 0,
|
||||
let ota_data = ota_data.as_embedded_storage(storage_ota);
|
||||
let ota_data = mk_static!(FlashRegion<FlashStorage>, ota_data);
|
||||
|
||||
let mut ota = esp_bootloader_esp_idf::ota::Ota::new(ota_data)?;
|
||||
|
||||
let ota_partition = match ota.current_slot()? {
|
||||
Slot::None => {
|
||||
panic!("No OTA slot found");
|
||||
}
|
||||
Slot::Slot0 => pt
|
||||
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||
AppPartitionSubType::Ota0,
|
||||
))?
|
||||
.unwrap(),
|
||||
Slot::Slot1 => pt
|
||||
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||
AppPartitionSubType::Ota1,
|
||||
))?
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
let ota_next = mk_static!(PartitionEntry, ota_partition);
|
||||
|
||||
let mut esp = Esp {
|
||||
rng,
|
||||
controller: Some(controller),
|
||||
interfaces: Some(interfaces),
|
||||
boot_button,
|
||||
mqtt_client: None,
|
||||
storage,
|
||||
slot: current.number(),
|
||||
slot_addres: app_address,
|
||||
next_slot: current.next().number(),
|
||||
ota_state,
|
||||
ota,
|
||||
ota_next,
|
||||
wall_clock_offset: 0,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user