make async can useable

This commit is contained in:
2025-10-08 19:48:13 +02:00
parent 7f3910bcd0
commit e5c5f31112
8 changed files with 35 additions and 35 deletions

View File

@@ -11,7 +11,7 @@ use esp_hal::Blocking;
use measurements::Temperature;
use serde::Serialize;
#[async_trait]
#[async_trait(?Send)]
pub trait BatteryInteraction {
async fn state_charge_percent(&mut self) -> FatResult<f32>;
async fn remaining_milli_ampere_hour(&mut self) -> FatResult<u16>;
@@ -51,7 +51,7 @@ pub enum BatteryState {
/// If no battery monitor is installed this implementation will be used
pub struct NoBatteryMonitor {}
#[async_trait]
#[async_trait(?Send)]
impl BatteryInteraction for NoBatteryMonitor {
async fn state_charge_percent(&mut self) -> FatResult<f32> {
// No monitor configured: assume full battery for lightstate logic
@@ -105,7 +105,7 @@ pub struct BQ34Z100G1 {
pub battery_driver: Bq34z100g1Driver<I2cDev, Delay>,
}
#[async_trait]
#[async_trait(?Send)]
impl BatteryInteraction for BQ34Z100G1 {
async fn state_charge_percent(&mut self) -> FatResult<f32> {
self.battery_driver

View File

@@ -1,6 +1,6 @@
use crate::bail;
use crate::config::{NetworkConfig, PlantControllerConfig};
use crate::hal::{get_current_slot_and_fix_ota_data, PLANT_COUNT, TIME_ACCESS};
use crate::hal::{PLANT_COUNT, TIME_ACCESS};
use crate::log::{LogMessage, LOG_ACCESS};
use chrono::{DateTime, Utc};
use serde::Serialize;

View File

@@ -24,7 +24,7 @@ pub struct Initial<'a> {
pub(crate) struct NoRTC {}
#[async_trait]
#[async_trait(?Send)]
impl RTCModuleInteraction for NoRTC {
async fn get_backup_info(&mut self) -> Result<BackupHeader, FatError> {
bail!("Please configure board revision")
@@ -68,7 +68,7 @@ pub(crate) fn create_initial_board(
Ok(Box::new(v))
}
#[async_trait]
#[async_trait(?Send)]
impl<'a> BoardInteraction<'a> for Initial<'a> {
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
bail!("Please configure board revision")

View File

@@ -130,7 +130,7 @@ pub struct HAL<'a> {
pub board_hal: Box<dyn BoardInteraction<'a> + Send>,
}
#[async_trait]
#[async_trait(?Send)]
pub trait BoardInteraction<'a> {
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError>;
fn get_esp(&mut self) -> &mut Esp<'a>;

View File

@@ -21,7 +21,7 @@ use serde::{Deserialize, Serialize};
pub const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
const CONFIG: Configuration = config::standard();
//
#[async_trait]
#[async_trait(?Send)]
pub trait RTCModuleInteraction {
async fn get_backup_info(&mut self) -> FatResult<BackupHeader>;
async fn get_backup_config(&mut self, chunk: usize) -> FatResult<([u8; 32], usize, u16)>;
@@ -55,7 +55,7 @@ pub struct DS3231Module {
>,
}
#[async_trait]
#[async_trait(?Send)]
impl RTCModuleInteraction for DS3231Module {
async fn get_backup_info(&mut self) -> FatResult<BackupHeader> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];

View File

@@ -170,7 +170,7 @@ pub(crate) fn create_v3(
}))
}
#[async_trait]
#[async_trait(?Send)]
impl<'a> BoardInteraction<'a> for V3<'a> {
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
Ok(&mut self.tank_sensor)

View File

@@ -297,7 +297,7 @@ pub(crate) async fn create_v4(
Ok(Box::new(v))
}
#[async_trait]
#[async_trait(?Send)]
impl<'a> BoardInteraction<'a> for V4<'a> {
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
Ok(&mut self.tank_sensor)
@@ -461,7 +461,6 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
async fn detect_sensors(&mut self) -> Result<alloc::string::String, FatError> {
// Delegate to sensor autodetect and build JSON
use alloc::string::ToString;
let detected = self.sensor.autodetect().await?;
// Build JSON manually to avoid exposing internal types
let mut s = alloc::string::String::from("{\"plants\":[");

View File

@@ -9,24 +9,21 @@ use alloc::string::ToString;
use async_trait::async_trait;
use bincode::config;
use bincode::error::DecodeError;
use core::mem;
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::mutex::Mutex;
use embassy_time::{Instant, Timer, WithTimeout};
use embedded_can::nb::Can;
use embedded_can::Frame;
use esp_hal::gpio::Output;
use esp_hal::i2c::master::I2c;
use esp_hal::pcnt::unit::Unit;
use esp_hal::twai::{EspTwaiError, EspTwaiFrame, StandardId, Twai, TwaiConfiguration};
use esp_hal::Blocking;
use esp_hal::twai::{EspTwaiFrame, StandardId, Twai, TwaiConfiguration};
use esp_hal::{Async, Blocking};
use log::info;
use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface};
const REPEAT_MOIST_MEASURE: usize = 10;
#[async_trait]
#[async_trait(?Send)]
pub trait SensorInteraction {
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> FatResult<f32>;
}
@@ -50,7 +47,7 @@ pub enum SensorImpl {
},
}
#[async_trait]
#[async_trait(?Send)]
impl SensorInteraction for SensorImpl {
async fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> FatResult<f32> {
match self {
@@ -180,8 +177,10 @@ impl SensorImpl {
} => {
// Power on CAN transceiver and start controller
can_power.set_high();
let config = twai_config.take().expect("twai config not set");
let mut twai = config.start();
let mut config = twai_config.take().expect("twai config not set");
let mut as_async = config.into_async().start();
Timer::after_millis(10).await;
// Give CAN some time to stabilize
Timer::after_millis(10).await;
@@ -197,7 +196,7 @@ impl SensorImpl {
{
if let Some(frame) = EspTwaiFrame::new(address, &can_buffer) {
// Try a few times; we intentionally ignore rx here and rely on stub logic
let resu = twai.transmit(&frame);
let resu = as_async.transmit_async(&frame).await;
match resu {
Ok(_) => {
info!(
@@ -217,22 +216,23 @@ impl SensorImpl {
}
}
}
// Poll for messages for ~100 ms
let detect_timeout = Instant::now()
.checked_add(embassy_time::Duration::from_millis(100))
.unwrap();
loop {
let rec = twai
.receive()
.with_timeout(embassy_time::Duration::from_millis(100))
.await;
match rec {
Ok(msg) => match msg {
match as_async.receive() {
Ok(or) => {
info!("Received CAN message: {:?}", or);
}
Err(err) => {
info!("Error receiving CAN message: {:?}", err);
Err(nb::Error::WouldBlock) => {
if Instant::now() > detect_timeout {
break;
}
},
Err(err) => {
Timer::after_millis(10).await;
}
Err(nb::Error::Other(err)) => {
info!("Error receiving CAN message: {:?}", err);
break;
}
@@ -242,6 +242,7 @@ impl SensorImpl {
// Wait for acknowledgements on the bus (stub: just wait 5 seconds)
Timer::after_millis(5_000).await;
// Stop CAN and power down
let config = as_async.stop().into_blocking();
can_power.set_low();
twai_config.replace(config);