remove: delete initial_hal implementation, update moisture sensor logic to handle optional raw values, optimize TWAI management, and improve CAN data handling

This commit is contained in:
2026-02-01 03:57:36 +01:00
parent ce10d084f8
commit e6f8e34f7d
7 changed files with 86 additions and 246 deletions

View File

@@ -11,8 +11,7 @@ use crate::hal::{
};
use crate::log::{LogMessage, LOG_ACCESS};
use alloc::boxed::Box;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::string::{ToString};
use async_trait::async_trait;
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
use canapi::SensorSlot;
@@ -22,7 +21,6 @@ use embassy_time::{Duration, Timer, WithTimeout};
use embedded_can::{Frame, Id};
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
use esp_hal::i2c::master::I2c;
use esp_hal::peripherals;
use esp_hal::twai::{EspTwaiError, EspTwaiFrame, StandardId, Twai, TwaiConfiguration, TwaiMode};
use esp_hal::{twai, Async, Blocking};
use ina219::address::{Address, Pin};
@@ -134,7 +132,7 @@ pub struct V4<'a> {
extra1: Output<'a>,
extra2: Output<'a>,
can_mutex: embassy_sync::mutex::Mutex<CriticalSectionRawMutex, ()>,
twai_config: Option<TwaiConfiguration<'static, Blocking>>
}
@@ -152,11 +150,13 @@ pub(crate) async fn create_v4(
let mut general_fault = Output::new(peripherals.gpio23, Level::Low, OutputConfig::default());
general_fault.set_low();
let twai_peripheral = Some(peripherals.twai);
let twai_rx_pin = Some(peripherals.gpio2);
let twai_tx_pin = Some(peripherals.gpio0);
let twai_config = Some(TwaiConfiguration::new(
peripherals.twai,
peripherals.gpio0,
peripherals.gpio2,
TWAI_BAUDRATE,
TwaiMode::Normal,
));
let extra1 = Output::new(peripherals.gpio6, Level::Low, OutputConfig::default());
let extra2 = Output::new(peripherals.gpio15, Level::Low, OutputConfig::default());
@@ -260,38 +260,11 @@ pub(crate) async fn create_v4(
extra1,
extra2,
can_power,
can_mutex: embassy_sync::mutex::Mutex::new(()),
twai_config
};
Ok(Box::new(v))
}
fn teardown_twai(old: Twai<Async>) {
let config = old.stop();
drop(config);
// Re-acquire the peripheral and pins
let rx_pin = unsafe { peripherals::GPIO2::steal() };
let tx_pin = unsafe { peripherals::GPIO0::steal() };
// Set pins to low to avoid parasitic powering
let _ = Input::new(rx_pin, InputConfig::default().with_pull(Pull::None));
let _ = Input::new(tx_pin, InputConfig::default().with_pull(Pull::None));
}
fn create_twai<'a>() -> Twai<'a, Async> {
// Release the pins from Output back to raw pins and store everything
let twai = unsafe { peripherals::TWAI0::steal() };
let twai_rx_pin = unsafe { peripherals::GPIO2::steal() };
let twai_tx_pin = unsafe { peripherals::GPIO0::steal() };
let twai_config = TwaiConfiguration::new(
twai,
twai_rx_pin,
twai_tx_pin,
TWAI_BAUDRATE,
TwaiMode::Normal,
);
twai_config.into_async().start()
}
#[async_trait(?Send)]
impl<'a> BoardInteraction<'a> for V4<'a> {
@@ -384,10 +357,8 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
}
async fn measure_moisture_hz(&mut self) -> FatResult<Moistures> {
self.can_power.set_high();
let mut twai = create_twai();
let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start();
Timer::after_millis(10).await;
@@ -395,17 +366,20 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
.with_timeout(Duration::from_millis(5000))
.await;
teardown_twai(twai);
let config = twai.stop().into_blocking();
self.twai_config.replace(config);
self.can_power.set_low();
Ok(moistures)
}
async fn detect_sensors(&mut self) -> FatResult<DetectionResult> {
self.can_power.set_high();
let mut twai = create_twai();
// Give CAN some time to stabilize
Timer::after_millis(3000).await;
let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start();
Timer::after_millis(1000).await;
info!("Sending info messages now");
// Send a few test messages per potential sensor node
for plant in 0..PLANT_COUNT {
@@ -418,7 +392,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
// Try a few times; we intentionally ignore rx here and rely on stub logic
let resu = twai
.transmit_async(&frame)
.with_timeout(Duration::from_millis(1000))
.with_timeout(Duration::from_millis(3000))
.await;
match resu {
Ok(_) => {
@@ -438,11 +412,13 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
let mut moistures = Moistures::default();
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
.with_timeout(Duration::from_millis(1000))
.with_timeout(Duration::from_millis(3000))
.await;
teardown_twai(twai);
let config = twai.stop().into_blocking();
self.twai_config.replace(config);
self.can_power.set_low();
@@ -490,8 +466,8 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
}
let moisture = self.measure_moisture_hz().await?;
for plant in 0..PLANT_COUNT {
let a = moisture.sensor_a_hz[plant] as u32;
let b = moisture.sensor_b_hz[plant] as u32;
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
@@ -515,11 +491,9 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
}
async fn can_power(&mut self, state: bool) -> FatResult<()> {
if state && self.can_power.is_set_low(){
self.can_power.set_high();
create_twai();
if state && self.can_power.is_set_low() {
self.can_power.set_high();
} else {
teardown_twai(create_twai());
self.can_power.set_low();
}
Ok(())
@@ -552,10 +526,10 @@ async fn wait_for_can_measurements(
let frequency = u16::from_be_bytes([data[0], data[1]]);
match sensor {
SensorSlot::A => {
moistures.sensor_a_hz[plant] = frequency as f32;
moistures.sensor_a_hz[plant] = Some(frequency as f32);
}
SensorSlot::B => {
moistures.sensor_b_hz[plant] = frequency as f32;
moistures.sensor_b_hz[plant] = Some(frequency as f32);
}
}
}
@@ -585,10 +559,10 @@ impl From<Moistures> for DetectionResult {
fn from(value: Moistures) -> Self {
let mut result = DetectionResult::default();
for (plant, sensor) in value.sensor_a_hz.iter().enumerate() {
result.plant[plant].sensor_a = *sensor > 1.0_f32;
result.plant[plant].sensor_a = sensor.is_some();
}
for (plant, sensor) in value.sensor_b_hz.iter().enumerate() {
result.plant[plant].sensor_b = *sensor > 1.0_f32;
result.plant[plant].sensor_b = sensor.is_some();
}
result
}