refactor: consolidate logging and time handling, remove TIME_ACCESS and LOG_ACCESS
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::bail;
|
||||
use crate::config::{NetworkConfig, PlantControllerConfig};
|
||||
use crate::hal::savegame_manager::SavegameManager;
|
||||
use crate::hal::{PLANT_COUNT, TIME_ACCESS};
|
||||
use crate::log::{LogMessage, LOG_ACCESS};
|
||||
use crate::hal::PLANT_COUNT;
|
||||
use crate::log::{log, LogMessage};
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
use crate::fat_error::{ContextExt, FatError, FatResult};
|
||||
@@ -16,7 +16,7 @@ use embassy_executor::Spawner;
|
||||
use embassy_net::udp::UdpSocket;
|
||||
use embassy_net::{DhcpConfig, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_sync::once_lock::OnceLock;
|
||||
use embassy_time::{Duration, Timer, WithTimeout};
|
||||
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash, RmwNorFlashStorage};
|
||||
@@ -112,6 +112,8 @@ pub struct Esp<'a> {
|
||||
pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>,
|
||||
pub uart0: Uart<'a, Blocking>,
|
||||
|
||||
pub rtc: Rtc<'a>,
|
||||
|
||||
pub ota: Ota<'static, RmwNorFlashStorage<'static, &'static mut MutexFlashStorage>>,
|
||||
pub ota_target: &'static mut FlashRegion<'static, MutexFlashStorage>,
|
||||
pub current: AppPartitionSubType,
|
||||
@@ -137,6 +139,14 @@ macro_rules! mk_static {
|
||||
}
|
||||
|
||||
impl Esp<'_> {
|
||||
pub fn get_time(&self) -> DateTime<Utc> {
|
||||
DateTime::from_timestamp_micros(self.rtc.current_time_us() as i64).unwrap_or(DateTime::UNIX_EPOCH)
|
||||
}
|
||||
|
||||
pub fn set_time(&mut self, time: DateTime<Utc>) {
|
||||
self.rtc.set_current_time_us(time.timestamp_micros() as u64);
|
||||
}
|
||||
|
||||
pub(crate) async fn read_serial_line(&mut self) -> FatResult<Option<alloc::string::String>> {
|
||||
let mut buf = [0u8; 1];
|
||||
let mut line = String::new();
|
||||
@@ -442,70 +452,65 @@ impl Esp<'_> {
|
||||
spawner.spawn(net_task(runner)).ok();
|
||||
self.controller.lock().await.start_async().await?;
|
||||
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + max_wait as u64 * 1000;
|
||||
loop {
|
||||
let state = esp_radio::wifi::sta_state();
|
||||
if state == WifiStaState::Started {
|
||||
self.controller.lock().await.connect()?;
|
||||
break;
|
||||
let res = async {
|
||||
loop {
|
||||
let state = esp_radio::wifi::sta_state();
|
||||
if state == WifiStaState::Started {
|
||||
self.controller.lock().await.connect()?;
|
||||
break;
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
if {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} > timeout
|
||||
{
|
||||
bail!("Timeout waiting for wifi sta ready")
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
Ok::<(), FatError>(())
|
||||
}
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + max_wait as u64 * 1000;
|
||||
loop {
|
||||
let state = esp_radio::wifi::sta_state();
|
||||
if state == WifiStaState::Connected {
|
||||
break;
|
||||
}
|
||||
if {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} > timeout
|
||||
{
|
||||
bail!("Timeout waiting for wifi sta connected")
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
bail!("Timeout waiting for wifi sta ready")
|
||||
}
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + max_wait as u64 * 1000;
|
||||
while !stack.is_link_up() {
|
||||
if {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} > timeout
|
||||
{
|
||||
bail!("Timeout waiting for wifi link up")
|
||||
|
||||
let res = async {
|
||||
loop {
|
||||
let state = esp_radio::wifi::sta_state();
|
||||
if state == WifiStaState::Connected {
|
||||
break;
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
Ok::<(), FatError>(())
|
||||
}
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + max_wait as u64 * 1000;
|
||||
while !stack.is_config_up() {
|
||||
if {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} > timeout
|
||||
{
|
||||
bail!("Timeout waiting for wifi config up")
|
||||
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
bail!("Timeout waiting for wifi sta connected")
|
||||
}
|
||||
|
||||
let res = async {
|
||||
while !stack.is_link_up() {
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
Timer::after(Duration::from_millis(100)).await
|
||||
Ok::<(), FatError>(())
|
||||
}
|
||||
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
bail!("Timeout waiting for wifi link up")
|
||||
}
|
||||
|
||||
let res = async {
|
||||
while !stack.is_config_up() {
|
||||
Timer::after(Duration::from_millis(100)).await
|
||||
}
|
||||
Ok::<(), FatError>(())
|
||||
}
|
||||
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
bail!("Timeout waiting for wifi config up")
|
||||
}
|
||||
|
||||
info!("Connected WIFI, dhcp: {:?}", stack.config_v4());
|
||||
@@ -515,7 +520,6 @@ impl Esp<'_> {
|
||||
pub fn deep_sleep(
|
||||
&mut self,
|
||||
duration_in_ms: u64,
|
||||
mut rtc: MutexGuard<CriticalSectionRawMutex, Rtc>,
|
||||
) -> ! {
|
||||
// Mark the current OTA image as valid if we reached here while in pending verify.
|
||||
if let Ok(cur) = self.ota.current_ota_state() {
|
||||
@@ -536,7 +540,7 @@ impl Esp<'_> {
|
||||
let mut wake_pins: [(&mut dyn RtcPinWithResistors, WakeupLevel); 1] =
|
||||
[(&mut self.wake_gpio1, WakeupLevel::Low)];
|
||||
let ext1 = esp_hal::rtc_cntl::sleep::Ext1WakeupSource::new(&mut wake_pins);
|
||||
rtc.sleep_deep(&[&timer, &ext1]);
|
||||
self.rtc.sleep_deep(&[&timer, &ext1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,28 +607,15 @@ impl Esp<'_> {
|
||||
if to_config_mode {
|
||||
RESTART_TO_CONF = 1;
|
||||
}
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(
|
||||
LogMessage::RestartToConfig,
|
||||
RESTART_TO_CONF as u32,
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
)
|
||||
.await;
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(
|
||||
LogMessage::LowVoltage,
|
||||
LOW_VOLTAGE_DETECTED as u32,
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
)
|
||||
.await;
|
||||
log(LogMessage::RestartToConfig, RESTART_TO_CONF as u32, 0, "", "").await;
|
||||
log(
|
||||
LogMessage::LowVoltage,
|
||||
LOW_VOLTAGE_DETECTED as u32,
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
)
|
||||
.await;
|
||||
// is executed before main, no other code will alter these values during printing
|
||||
#[allow(static_mut_refs)]
|
||||
for (i, time) in LAST_WATERING_TIMESTAMP.iter().enumerate() {
|
||||
@@ -703,29 +694,22 @@ impl Esp<'_> {
|
||||
))?;
|
||||
spawner.spawn(mqtt_runner(task))?;
|
||||
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(LogMessage::StayAlive, 0, 0, "", &stay_alive_topic)
|
||||
.await;
|
||||
log(LogMessage::StayAlive, 0, 0, "", &stay_alive_topic).await;
|
||||
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(LogMessage::MqttInfo, 0, 0, "", mqtt_url)
|
||||
.await;
|
||||
log(LogMessage::MqttInfo, 0, 0, "", mqtt_url).await;
|
||||
|
||||
let mqtt_timeout = 15000;
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + mqtt_timeout as u64 * 1000;
|
||||
while !MQTT_CONNECTED_EVENT_RECEIVED.load(Ordering::Relaxed) {
|
||||
let cur = TIME_ACCESS.get().await.lock().await.current_time_us();
|
||||
if cur > timeout {
|
||||
bail!("Timeout waiting MQTT connect event")
|
||||
let res = async {
|
||||
while !MQTT_CONNECTED_EVENT_RECEIVED.load(Ordering::Relaxed) {
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
}
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
Ok::<(), FatError>(())
|
||||
}
|
||||
.with_timeout(Duration::from_millis(mqtt_timeout as u64))
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
bail!("Timeout waiting MQTT connect event")
|
||||
}
|
||||
|
||||
let _ = Topic::General(round_trip_topic.clone())
|
||||
@@ -733,18 +717,19 @@ impl Esp<'_> {
|
||||
.publish()
|
||||
.await;
|
||||
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + mqtt_timeout as u64 * 1000;
|
||||
while !MQTT_ROUND_TRIP_RECEIVED.load(Ordering::Relaxed) {
|
||||
let cur = TIME_ACCESS.get().await.lock().await.current_time_us();
|
||||
if cur > timeout {
|
||||
//ensure we do not further try to publish
|
||||
MQTT_CONNECTED_EVENT_RECEIVED.store(false, Ordering::Relaxed);
|
||||
bail!("Timeout waiting MQTT roundtrip")
|
||||
let res = async {
|
||||
while !MQTT_ROUND_TRIP_RECEIVED.load(Ordering::Relaxed) {
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
}
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
Ok::<(), FatError>(())
|
||||
}
|
||||
.with_timeout(Duration::from_millis(mqtt_timeout as u64))
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
//ensure we do not further try to publish
|
||||
MQTT_CONNECTED_EVENT_RECEIVED.store(false, Ordering::Relaxed);
|
||||
bail!("Timeout waiting MQTT roundtrip")
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -851,18 +836,10 @@ async fn mqtt_incoming_task(
|
||||
true => 1,
|
||||
false => 0,
|
||||
};
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(LogMessage::MqttStayAliveRec, a, 0, "", "")
|
||||
.await;
|
||||
log(LogMessage::MqttStayAliveRec, a, 0, "", "").await;
|
||||
MQTT_STAY_ALIVE.store(value, Ordering::Relaxed);
|
||||
} else {
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(LogMessage::UnknownTopic, 0, 0, "", &topic)
|
||||
.await;
|
||||
log(LogMessage::UnknownTopic, 0, 0, "", &topic).await;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -44,8 +44,8 @@ use crate::{
|
||||
battery::{BatteryInteraction, NoBatteryMonitor},
|
||||
esp::Esp,
|
||||
},
|
||||
log::log,
|
||||
log::LogMessage,
|
||||
BOARD_ACCESS,
|
||||
};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::format;
|
||||
@@ -77,7 +77,6 @@ use crate::fat_error::{ContextExt, FatError, FatResult};
|
||||
use crate::hal::battery::WCHI2CSlave;
|
||||
use crate::hal::savegame_manager::SavegameManager;
|
||||
use crate::hal::water::TankSensor;
|
||||
use crate::log::LOG_ACCESS;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_sync::once_lock::OnceLock;
|
||||
use embedded_storage::nor_flash::RmwNorFlashStorage;
|
||||
@@ -104,8 +103,6 @@ use portable_atomic::AtomicBool;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use shared_flash::MutexFlashStorage;
|
||||
|
||||
pub static TIME_ACCESS: OnceLock<Mutex<CriticalSectionRawMutex, Rtc>> = OnceLock::new();
|
||||
|
||||
//Only support for 8 right now!
|
||||
pub const PLANT_COUNT: usize = 8;
|
||||
|
||||
@@ -145,6 +142,8 @@ pub trait BoardInteraction<'a> {
|
||||
fn get_config(&mut self) -> &PlantControllerConfig;
|
||||
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
|
||||
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
|
||||
async fn get_time(&mut self) -> DateTime<Utc>;
|
||||
async fn set_time(&mut self, time: &DateTime<FixedOffset>) -> FatResult<()>;
|
||||
async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError>;
|
||||
async fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
|
||||
|
||||
@@ -246,12 +245,7 @@ impl PlantHal {
|
||||
esp_alloc::heap_allocator!(size: 64 * 1024);
|
||||
esp_alloc::heap_allocator!(#[link_section = ".dram2_uninit"] size: 64000);
|
||||
|
||||
let rtc: Rtc = Rtc::new(peripherals.LPWR);
|
||||
TIME_ACCESS
|
||||
.init(Mutex::new(rtc))
|
||||
.map_err(|_| FatError::String {
|
||||
error: "Init error rct".to_string(),
|
||||
})?;
|
||||
let rtc_peripheral: Rtc = Rtc::new(peripherals.LPWR);
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
||||
@@ -409,6 +403,7 @@ impl PlantHal {
|
||||
slot0_state: state_0,
|
||||
slot1_state: state_1,
|
||||
uart0,
|
||||
rtc: rtc_peripheral,
|
||||
};
|
||||
|
||||
//init,reset rtc memory depending on cause
|
||||
@@ -444,17 +439,14 @@ impl PlantHal {
|
||||
SocResetReason::Cpu0JtagCpu => "cpu0 jtag cpu",
|
||||
},
|
||||
};
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(
|
||||
LogMessage::ResetReason,
|
||||
init_rtc_store as u32,
|
||||
to_config_mode as u32,
|
||||
"",
|
||||
&format!("{reasons:?}"),
|
||||
)
|
||||
.await;
|
||||
log(
|
||||
LogMessage::ResetReason,
|
||||
init_rtc_store as u32,
|
||||
to_config_mode as u32,
|
||||
"",
|
||||
&format!("{reasons:?}"),
|
||||
)
|
||||
.await;
|
||||
|
||||
esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode)
|
||||
.await;
|
||||
@@ -548,17 +540,14 @@ impl PlantHal {
|
||||
HAL { board_hal }
|
||||
}
|
||||
Err(err) => {
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(
|
||||
LogMessage::ConfigModeMissingConfig,
|
||||
0,
|
||||
0,
|
||||
"",
|
||||
&err.to_string(),
|
||||
)
|
||||
.await;
|
||||
log(
|
||||
LogMessage::ConfigModeMissingConfig,
|
||||
0,
|
||||
0,
|
||||
"",
|
||||
&err.to_string(),
|
||||
)
|
||||
.await;
|
||||
HAL {
|
||||
board_hal: v4_hal::create_v4(
|
||||
free_pins,
|
||||
@@ -641,27 +630,6 @@ pub fn next_partition(current: AppPartitionSubType) -> FatResult<AppPartitionSub
|
||||
Ok(next)
|
||||
}
|
||||
|
||||
pub async fn esp_time() -> DateTime<Utc> {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
DateTime::from_timestamp_micros(guard.current_time_us() as i64).unwrap_or(DateTime::UNIX_EPOCH)
|
||||
}
|
||||
|
||||
pub async fn esp_set_time(time: DateTime<FixedOffset>) -> FatResult<()> {
|
||||
{
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.set_current_time_us(time.timestamp_micros() as u64);
|
||||
}
|
||||
BOARD_ACCESS
|
||||
.get()
|
||||
.await
|
||||
.lock()
|
||||
.await
|
||||
.board_hal
|
||||
.get_rtc_module()
|
||||
.set_rtc_time(&time.to_utc())
|
||||
.await
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize)]
|
||||
pub struct Moistures {
|
||||
pub sensor_a_hz: [Option<f32>; PLANT_COUNT],
|
||||
|
||||
@@ -7,15 +7,15 @@ use crate::hal::rtc::{BackupHeader, RTCModuleInteraction, EEPROM_PAGE, X25};
|
||||
use crate::hal::water::TankSensor;
|
||||
use crate::hal::{
|
||||
BoardInteraction, Detection, FreePeripherals, Moistures, Sensor, I2C_DRIVER, PLANT_COUNT,
|
||||
TIME_ACCESS,
|
||||
};
|
||||
use crate::log::{LogMessage, LOG_ACCESS};
|
||||
use crate::log::{log, LogMessage};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::ToString;
|
||||
use async_trait::async_trait;
|
||||
use bincode::config;
|
||||
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
|
||||
use canapi::SensorSlot;
|
||||
use chrono::{DateTime, FixedOffset, Utc};
|
||||
use core::cmp::min;
|
||||
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
@@ -300,6 +300,16 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
&mut self.rtc_module
|
||||
}
|
||||
|
||||
async fn get_time(&mut self) -> DateTime<Utc> {
|
||||
self.esp.get_time()
|
||||
}
|
||||
|
||||
async fn set_time(&mut self, time: &DateTime<FixedOffset>) -> FatResult<()> {
|
||||
self.rtc_module.set_rtc_time(&time.to_utc()).await?;
|
||||
self.esp.set_time(time.to_utc());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError> {
|
||||
self.charger.set_charge_indicator(charging)
|
||||
}
|
||||
@@ -307,8 +317,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
||||
self.awake.set_low();
|
||||
self.charger.power_save();
|
||||
let rtc = TIME_ACCESS.get().await.lock().await;
|
||||
self.esp.deep_sleep(duration_in_ms, rtc);
|
||||
self.esp.deep_sleep(duration_in_ms);
|
||||
}
|
||||
|
||||
fn is_day(&self) -> bool {
|
||||
@@ -507,10 +516,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
for plant in 0..PLANT_COUNT {
|
||||
let a = moisture.sensor_a_hz[plant].unwrap_or(0.0) as u32;
|
||||
let b = moisture.sensor_b_hz[plant].unwrap_or(0.0) as u32;
|
||||
LOG_ACCESS
|
||||
.lock()
|
||||
.await
|
||||
.log(LogMessage::TestSensor, a, b, &(plant + 1).to_string(), "")
|
||||
log(LogMessage::TestSensor, a, b, &(plant + 1).to_string(), "")
|
||||
.await;
|
||||
}
|
||||
Timer::after_millis(10).await;
|
||||
|
||||
Reference in New Issue
Block a user