sensor and esp and canable call all communicate with each other.

This commit is contained in:
2025-10-18 00:58:12 +02:00
parent ea608dfa6a
commit a446f3ace2
232 changed files with 9387 additions and 3067870 deletions

View File

@@ -4,13 +4,14 @@ extern crate alloc;
use crate::hal::peripherals::CAN1;
use core::fmt::Write as _;
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET, MOISTURE_DATA_OFFSET};
use canapi::SensorSlot;
use ch32_hal::gpio::{Level, Output, Speed};
use ch32_hal::adc::{Adc, SampleTime, ADC_MAX};
use ch32_hal::can;
use ch32_hal::can::{Can, CanFifo, CanFilter, CanFrame, CanMode};
use ch32_hal::mode::{Blocking};
use ch32_hal::mode::{NonBlocking};
use ch32_hal::peripherals::USBD;
// use ch32_hal::delay::Delay;
use embassy_executor::{Spawner, task};
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
use embassy_usb::{Builder, UsbDevice};
@@ -19,9 +20,8 @@ use hal::usbd::{Driver};
use hal::{bind_interrupts};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::{Channel};
use embassy_time::{Instant, Duration};
use embedded_can::blocking::Can as bcan;
use embedded_can::StandardId;
use embassy_time::{Instant, Duration, Delay, Timer};
use embedded_can::{Id, StandardId};
use {ch32_hal as hal, panic_halt as _};
macro_rules! mk_static {
@@ -33,12 +33,15 @@ macro_rules! mk_static {
}};
}
bind_interrupts!(struct Irqs {
USB_LP_CAN1_RX0 => hal::usbd::InterruptHandler<hal::peripherals::USBD>;
});
bind_interrupts!(struct Irqs {
USB_LP_CAN1_RX0 => hal::usbd::InterruptHandler<hal::peripherals::USBD>;
});
use embedded_alloc::LlffHeap as Heap;
use embedded_alloc::LlffHeap as Heap;
use embedded_can::nb::Can as nb_can;
use qingke::riscv::asm::delay;
use log::log;
#[global_allocator]
static HEAP: Heap = Heap::empty();
@@ -49,7 +52,7 @@ static LOG_CH: Channel<CriticalSectionRawMutex, heapless::String<128>, 8> = Chan
#[embassy_executor::main(entry = "qingke_rt::entry")]
async fn main(spawner: Spawner) {
ch32_hal::pac::AFIO.pcfr1().write(|w| w.set_can1_rm(2));
//
unsafe {
static mut HEAP_SPACE: [u8; 4096] = [0; 4096]; // 4 KiB heap, adjust as needed
HEAP.init(HEAP_SPACE.as_ptr() as usize, HEAP_SPACE.len());
@@ -103,20 +106,14 @@ async fn main(spawner: Spawner) {
// Built-in LED on PB2 mirrors Q state
let led = Output::new(p.PB2, Level::Low, Speed::Low);
let info = Output::new(p.PA3, Level::Low, Speed::Low);
// Create ADC on ADC1 and use PA1 as analog input (Threshold/Trigger)
let adc = Adc::new(p.ADC1, Default::default());
let ain = p.PA1;
let config = can::can::Config::default();
let can: Can<'static, CAN1 , Blocking> = Can::new_blocking(p.CAN1, p.PB8, p.PB9, CanFifo::Fifo1, CanMode::Normal, 125_000, config).expect("Valid");
let mut filter = CanFilter::new_id_list();
filter
.get(0)
.unwrap()
.set(StandardId::new(0x580 | 0x42).unwrap().into(), Default::default());
can.add_filter(CanFilter::accept_all());
let can: Can<CAN1, NonBlocking> = Can::new_nb(p.CAN1, p.PB8, p.PB9, CanFifo::Fifo0, CanMode::Normal, 125_000, config).expect("Valid");
ch32_hal::pac::AFIO.pcfr1().write(|w| w.set_can1_rm(2));
spawner.spawn(usb_task(usb)).unwrap();
spawner.spawn(usb_writer(class)).unwrap();
@@ -135,13 +132,28 @@ async fn worker(
mut led: Output<'static>,
mut adc: Adc<'static, hal::peripherals::ADC1>,
mut ain: hal::peripherals::PA1,
mut can: Can<'static, CAN1, Blocking>,
mut can: Can<'static, CAN1, NonBlocking>,
) {
// 555 emulation state: Q initially Low
let mut q_high = false;
let low_th: u16 = (ADC_MAX as u16) / 3; // ~1/3 Vref
let high_th: u16 = ((ADC_MAX as u32 * 2) / 3) as u16; // ~2/3 Vref
let moisture_address = StandardId::new(plant_id(MOISTURE_DATA_OFFSET, SensorSlot::A, 0)).unwrap();
let identity_address = StandardId::new(plant_id(IDENTIFY_CMD_OFFSET, SensorSlot::A, 0)).unwrap();
let mut filter = CanFilter::new_id_list();
filter
.get(0)
.unwrap()
.set(identity_address.into(), Default::default());
can.add_filter(filter);
//can.add_filter(CanFilter::accept_all());
loop {
// Count rising edges of Q in a 100 ms window
let start = Instant::now();
@@ -167,10 +179,8 @@ async fn worker(
// Drive output pin accordingly
if q_high {
q.set_high();
led.set_high();
} else {
q.set_low();
led.set_low();
}
// Count rising edges
@@ -194,9 +204,9 @@ async fn worker(
);
log(msg);
let address = StandardId::new(0x580 | 0x42).unwrap();
let moisture = CanFrame::new(address, &[freq_hz as u8]).unwrap();
match bcan::transmit(&mut can, &moisture) {
let mut moisture = CanFrame::new(moisture_address, &[freq_hz as u8]).unwrap();
match can.transmit(&mut moisture){
Ok(..) => {
let mut msg: heapless::String<128> = heapless::String::new();
let _ = write!(
@@ -206,18 +216,48 @@ async fn worker(
log(msg);
}
Err(err) => {
let mut msg: heapless::String<128> = heapless::String::new();
let _ = write!(
&mut msg,
"err {}"
"err {:?}"
,err
);
log(msg);
}
}
loop {
yield_now().await;
match can.receive() {
Ok(frame) => {
match frame.id() {
Id::Standard(s_frame) => {
let mut msg: heapless::String<128> = heapless::String::new();
let _ = write!(
&mut msg,
"Received from canbus: {:?} ident is {:?} \r\n",
s_frame.as_raw(),
identity_address.as_raw()
);
log(msg);
if s_frame.as_raw() == identity_address.as_raw() {
for _ in 0..10 {
Timer::after_millis(250).await;
led.toggle();
}
led.set_low();
}
}
Id::Extended(_) => {}
}
}
_ => {
break;
}
}
}
}
}