Add firmware build timestamp support for sensors; update detection workflows and UI accordingly.
This commit is contained in:
@@ -8,4 +8,15 @@ fn main() {
|
||||
std::fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap();
|
||||
println!("cargo:rustc-link-search={}", out_dir.display());
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
|
||||
// Embed firmware build timestamp as minutes since Unix epoch (4 bytes, big-endian).
|
||||
// Dropping sub-minute precision keeps it in 4 bytes for many years.
|
||||
let build_seconds = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.expect("System time before UNIX_EPOCH")
|
||||
.as_secs();
|
||||
let build_minutes = (build_seconds / 60) as u32;
|
||||
let bytes = build_minutes.to_be_bytes();
|
||||
std::fs::write(out_dir.join("build_minutes.bin"), bytes).unwrap();
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
extern crate alloc;
|
||||
|
||||
use crate::hal::peripherals::CAN1;
|
||||
use canapi::id::{plant_id, IDENTIFY_CMD_OFFSET, MOISTURE_DATA_OFFSET};
|
||||
use canapi::id::{plant_id, FIRMWARE_BUILD_OFFSET, IDENTIFY_CMD_OFFSET, MOISTURE_DATA_OFFSET};
|
||||
use canapi::SensorSlot;
|
||||
use ch32_hal::adc::{Adc, SampleTime, ADC_MAX};
|
||||
use ch32_hal::{pac};
|
||||
@@ -47,6 +47,10 @@ static CAN_TX_CH: Channel<CriticalSectionRawMutex, CanFrame, 4> = Channel::new()
|
||||
|
||||
static BEACON: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// Firmware build timestamp in minutes since Unix epoch, embedded at compile time.
|
||||
const FIRMWARE_BUILD_MINUTES: u32 =
|
||||
u32::from_be_bytes(*include_bytes!(concat!(env!("OUT_DIR"), "/build_minutes.bin")));
|
||||
|
||||
#[embassy_executor::main(entry = "qingke_rt::entry")]
|
||||
async fn main(spawner: Spawner) {
|
||||
ch32_hal::pac::AFIO.pcfr1().write(|w| w.set_can1_rm(2));
|
||||
@@ -111,6 +115,7 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
let moisture_id = plant_id(MOISTURE_DATA_OFFSET, slot, addr as u16);
|
||||
let identify_id = plant_id(IDENTIFY_CMD_OFFSET, slot, addr as u16);
|
||||
let firmware_build_id = plant_id(FIRMWARE_BUILD_OFFSET, slot, addr as u16);
|
||||
let standard_identify_id = StandardId::new(identify_id).unwrap();
|
||||
|
||||
//is any floating, or invalid addr (only 1-8 are valid)
|
||||
@@ -269,8 +274,9 @@ async fn main(spawner: Spawner) {
|
||||
// filter.get(0).unwrap().set(Id::Standard(standard_identify_id), Default::default());
|
||||
// can.add_filter(filter);
|
||||
let standard_moisture_id = StandardId::new(moisture_id).unwrap();
|
||||
let standard_firmware_build_id = StandardId::new(firmware_build_id).unwrap();
|
||||
spawner
|
||||
.spawn(can_task(can,info, warn, standard_identify_id, standard_moisture_id))
|
||||
.spawn(can_task(can, info, warn, standard_identify_id, standard_moisture_id, standard_firmware_build_id))
|
||||
.unwrap();
|
||||
|
||||
// move Q output, LED, ADC and analog input into worker task
|
||||
@@ -282,6 +288,7 @@ async fn main(spawner: Spawner) {
|
||||
ain,
|
||||
standard_moisture_id,
|
||||
standard_identify_id,
|
||||
standard_firmware_build_id,
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
@@ -362,6 +369,7 @@ async fn can_task(
|
||||
warn: &'static mut Output<'static>,
|
||||
identify_id: StandardId,
|
||||
moisture_id: StandardId,
|
||||
firmware_build_id: StandardId,
|
||||
) {
|
||||
// Non-blocking beacon blink timing.
|
||||
// We keep this inside the CAN task so it can't stall other tasks (like `worker`) with `await`s.
|
||||
@@ -460,6 +468,7 @@ async fn worker(
|
||||
mut ain: hal::peripherals::PA1,
|
||||
moisture_id: StandardId,
|
||||
identify_id: StandardId,
|
||||
firmware_build_id: StandardId,
|
||||
) {
|
||||
// 555 emulation state: Q initially Low
|
||||
let mut q_high = false;
|
||||
@@ -540,6 +549,12 @@ async fn worker(
|
||||
|
||||
let moisture = CanFrame::new(moisture_id, &(freq_hz as u32).to_be_bytes()).unwrap();
|
||||
CAN_TX_CH.send(moisture).await;
|
||||
|
||||
// Send firmware build timestamp after each measurement so the controller
|
||||
// always has up-to-date build info without requiring an identify request.
|
||||
if let Some(build_frame) = CanFrame::new(firmware_build_id, &FIRMWARE_BUILD_MINUTES.to_be_bytes()) {
|
||||
CAN_TX_CH.send(build_frame).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user