update: improve documentation and restructure code for modular hardware integration, add CAN communication to HAL, and update KiCad layouts
This commit is contained in:
@@ -541,15 +541,15 @@ impl PlantHal {
|
||||
}
|
||||
};
|
||||
|
||||
let board_hal: Box<dyn BoardInteraction + Send> = match config.hardware.board {
|
||||
BoardVersion::Initial => {
|
||||
initial_hal::create_initial_board(free_pins, config, esp)?
|
||||
}
|
||||
BoardVersion::V4 => {
|
||||
let board_hal: Box<dyn BoardInteraction + Send> = //match config.hardware.board {
|
||||
//BoardVersion::Initial => {
|
||||
// initial_hal::create_initial_board(free_pins, config, esp)?
|
||||
//}
|
||||
//BoardVersion::V4 => {
|
||||
v4_hal::create_v4(free_pins, esp, config, battery_interaction, rtc_module)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
.await?;
|
||||
//}
|
||||
//};
|
||||
|
||||
HAL { board_hal }
|
||||
}
|
||||
@@ -566,11 +566,9 @@ impl PlantHal {
|
||||
)
|
||||
.await;
|
||||
HAL {
|
||||
board_hal: initial_hal::create_initial_board(
|
||||
free_pins,
|
||||
PlantControllerConfig::default(),
|
||||
esp,
|
||||
)?,
|
||||
board_hal: v4_hal::create_v4(free_pins, esp, PlantControllerConfig::default(),
|
||||
Box::new(NoBatteryMonitor {}), rtc_module)
|
||||
.await?
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ 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};
|
||||
@@ -129,7 +130,9 @@ pub struct V4<'a> {
|
||||
pump_ina: Option<
|
||||
SyncIna219<I2cDevice<'a, CriticalSectionRawMutex, I2c<'static, Blocking>>, UnCalibrated>,
|
||||
>,
|
||||
twai_config: Option<TwaiConfiguration<'static, Blocking>>,
|
||||
twai_peripheral: Option<esp_hal::peripherals::TWAI0<'static>>,
|
||||
twai_rx_pin: Option<esp_hal::peripherals::GPIO2<'static>>,
|
||||
twai_tx_pin: Option<esp_hal::peripherals::GPIO0<'static>>,
|
||||
can_power: Output<'static>,
|
||||
|
||||
extra1: Output<'a>,
|
||||
@@ -150,6 +153,12 @@ 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 extra1 = Output::new(peripherals.gpio6, Level::Low, OutputConfig::default());
|
||||
let extra2 = Output::new(peripherals.gpio15, Level::Low, OutputConfig::default());
|
||||
|
||||
@@ -169,19 +178,13 @@ pub(crate) async fn create_v4(
|
||||
peripherals.pcnt1,
|
||||
)?;
|
||||
|
||||
let twai_config = Some(TwaiConfiguration::new(
|
||||
peripherals.twai,
|
||||
peripherals.gpio2,
|
||||
peripherals.gpio0,
|
||||
TWAI_BAUDRATE,
|
||||
TwaiMode::Normal,
|
||||
));
|
||||
let can_power = Output::new(peripherals.gpio22, Level::Low, OutputConfig::default());
|
||||
|
||||
let solar_is_day = Input::new(peripherals.gpio7, InputConfig::default());
|
||||
let light = Output::new(peripherals.gpio10, Level::Low, Default::default());
|
||||
let charge_indicator = Output::new(peripherals.gpio3, Level::Low, Default::default());
|
||||
|
||||
info!("Start pump expander");
|
||||
let pump_device = I2cDevice::new(I2C_DRIVER.get().await);
|
||||
let mut pump_expander = Pca9535Immediate::new(pump_device, 32);
|
||||
for pin in 0..8 {
|
||||
@@ -191,6 +194,7 @@ pub(crate) async fn create_v4(
|
||||
let _ = pump_expander.pin_set_low(GPIOBank::Bank1, pin);
|
||||
}
|
||||
|
||||
info!("Start mppt");
|
||||
let mppt_current = I2cDevice::new(I2C_DRIVER.get().await);
|
||||
let mppt_ina = match SyncIna219::new(mppt_current, Address::from_pins(Pin::Vcc, Pin::Gnd)) {
|
||||
Ok(mut ina) => {
|
||||
@@ -211,6 +215,7 @@ pub(crate) async fn create_v4(
|
||||
}
|
||||
};
|
||||
|
||||
info!("Start pump current sensor");
|
||||
let pump_current_dev = I2cDevice::new(I2C_DRIVER.get().await);
|
||||
let pump_ina = match SyncIna219::new(pump_current_dev, Address::from_pins(Pin::Gnd, Pin::Sda)) {
|
||||
Ok(ina) => Some(ina),
|
||||
@@ -252,15 +257,37 @@ pub(crate) async fn create_v4(
|
||||
config,
|
||||
battery_monitor,
|
||||
pump_ina,
|
||||
twai_config,
|
||||
twai_peripheral,
|
||||
twai_rx_pin,
|
||||
twai_tx_pin,
|
||||
charger,
|
||||
extra1,
|
||||
extra2,
|
||||
can_power
|
||||
can_power,
|
||||
};
|
||||
Ok(Box::new(v))
|
||||
}
|
||||
|
||||
impl<'a> V4<'a> {
|
||||
fn teardown_twai(&mut self, old: TwaiConfiguration<Blocking>) {
|
||||
drop(old);
|
||||
// Re-acquire the peripheral and pins
|
||||
let twai = unsafe { peripherals::TWAI0::steal() };
|
||||
let rx_pin = unsafe { peripherals::GPIO2::steal() };
|
||||
let tx_pin = unsafe { peripherals::GPIO0::steal() };
|
||||
|
||||
// Set pins to low to avoid parasitic powering
|
||||
let mut rx = Input::new(rx_pin, InputConfig::default().with_pull(Pull::None));
|
||||
let mut tx = Input::new(tx_pin, InputConfig::default().with_pull(Pull::None));
|
||||
|
||||
// Release the pins from Output back to raw pins and store everything
|
||||
self.twai_peripheral = Some(twai);
|
||||
self.twai_rx_pin = Some(unsafe { peripherals::GPIO2::steal() });
|
||||
self.twai_tx_pin = Some(unsafe { peripherals::GPIO0::steal() });
|
||||
self.can_power.set_low();
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
|
||||
@@ -352,8 +379,14 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
}
|
||||
async fn measure_moisture_hz(&mut self) -> FatResult<Moistures> {
|
||||
self.can_power.set_high();
|
||||
let config = self.twai_config.take().expect("twai config not set");
|
||||
let mut twai = config.into_async().start();
|
||||
let twai_config = TwaiConfiguration::new(
|
||||
self.twai_peripheral.take().unwrap(),
|
||||
self.twai_rx_pin.take().unwrap(),
|
||||
self.twai_tx_pin.take().unwrap(),
|
||||
TWAI_BAUDRATE,
|
||||
TwaiMode::Normal,
|
||||
);
|
||||
let mut twai = twai_config.into_async().start();
|
||||
|
||||
loop {
|
||||
let rec = twai.receive();
|
||||
@@ -372,11 +405,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
|
||||
.with_timeout(Duration::from_millis(2000))
|
||||
.await;
|
||||
|
||||
self.can_power.set_low();
|
||||
|
||||
let config = twai.stop().into_blocking();
|
||||
self.twai_config.replace(config);
|
||||
self.teardown_twai(twai.stop().into_blocking());
|
||||
|
||||
Ok(moistures)
|
||||
}
|
||||
@@ -445,9 +474,17 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
async fn detect_sensors(&mut self) -> FatResult<DetectionResult> {
|
||||
// Power on CAN transceiver and start controller
|
||||
self.can_power.set_high();
|
||||
let config = self.twai_config.take().expect("twai config not set");
|
||||
let twai_config = TwaiConfiguration::new(
|
||||
self.twai_peripheral.take().unwrap(),
|
||||
self.twai_rx_pin.take().unwrap(),
|
||||
self.twai_tx_pin.take().unwrap(),
|
||||
TWAI_BAUDRATE,
|
||||
TwaiMode::Normal,
|
||||
);
|
||||
|
||||
|
||||
info!("convert can");
|
||||
let mut as_async = config.into_async().start();
|
||||
let mut as_async = twai_config.into_async().start();
|
||||
// Give CAN some time to stabilize
|
||||
Timer::after_millis(10).await;
|
||||
|
||||
@@ -487,8 +524,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||
.await;
|
||||
|
||||
let config = as_async.stop().into_blocking();
|
||||
self.can_power.set_low();
|
||||
self.twai_config.replace(config);
|
||||
self.teardown_twai(config);
|
||||
|
||||
let result = moistures.into();
|
||||
|
||||
|
||||
@@ -186,7 +186,6 @@ fn limit_length<const LIMIT: usize>(input: &str, target: &mut heapless::String<L
|
||||
)
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user