added RTR example

This commit is contained in:
2025-05-13 14:45:49 +02:00
parent 37ec9114b3
commit d661c940fe
4 changed files with 110 additions and 56 deletions

View File

@ -9,12 +9,17 @@ use defmt_rtt as _;
use embassy_example::EXTCLK_FREQ;
use embassy_executor::Spawner;
use va416xx_hal::can::asynch::on_interrupt_can;
use va416xx_hal::can::{Can, CanFrame, CanFrameNormal, CanId, CanRx, CanTx, ClockConfig};
use va416xx_hal::can::{
Can, CanFrame, CanFrameNormal, CanFrameRtr, CanId, CanRx, CanTx, ClockConfig,
};
use va416xx_hal::clock::ClockConfigurator;
use va416xx_hal::pac::{self, interrupt};
use va416xx_hal::time::Hertz;
use va416xx_hal::{can, prelude::*};
const STANDARD_ID_0: can::StandardId = can::StandardId::new(0x42).unwrap();
const STANDARD_ID_1: can::StandardId = can::StandardId::new(0x5).unwrap();
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
defmt::println!("-- VA416xx CAN Demo --");
@ -42,6 +47,7 @@ async fn main(_spawner: Spawner) {
val.set_diag_enable(true);
val
});
can.set_global_mask_for_exact_id_match_with_rtr_masked();
can.set_base_mask_for_all_match();
can.enable();
let err_counter = can.read_error_counters();
@ -57,17 +63,72 @@ async fn main(_spawner: Spawner) {
let mut rx_dedicated = CanRx::new(channels.take(1).unwrap());
// Base channel which has dedicated mask.
let mut rx_base = CanRx::new(channels.take(14).unwrap());
let standard_id = can::StandardId::new(0x42).unwrap();
let send_data = &[1, 2, 3, 4];
let send_frame =
CanFrame::Normal(CanFrameNormal::new(can::Id::Standard(standard_id), send_data).unwrap());
rx_dedicated
.configure_for_reception_with_standard_id(standard_id, false)
.unwrap();
rx_base.configure_for_reception();
defmt::info!("sending CAN frame with ID 0x42 and data {}", send_data);
send_and_receive_on_dedicated_channel(&mut can, &mut tx, &mut rx_dedicated);
send_and_receive_rtr_on_dedicated_channel(&mut can, &mut tx, &mut rx_dedicated);
loop {
cortex_m::asm::nop();
}
}
fn send_and_receive_on_dedicated_channel(can: &mut Can, tx: &mut CanTx, rx_dedicated: &mut CanRx) {
let send_data = &[1, 2, 3, 4];
defmt::info!(
"sending CAN frame with ID {:#X} and data {}",
STANDARD_ID_0.as_raw(),
send_data
);
rx_dedicated.configure_for_reception_with_standard_id(STANDARD_ID_0, false);
let send_frame =
CanFrame::Normal(CanFrameNormal::new(can::Id::Standard(STANDARD_ID_0), send_data).unwrap());
tx.transmit_frame(send_frame).unwrap();
// Await frame transmission completion.
nb::block!(tx.transfer_done()).unwrap();
check_and_handle_errors(can);
let frame = nb::block!(rx_dedicated.receive(true)).expect("invalid CAN rx state");
check_and_handle_errors(can);
if let CanFrame::Normal(can_frame_normal) = frame {
if let can::Id::Standard(standard_id) = can_frame_normal.id() {
defmt::info!(
"received CAN frame with ID {:#X} and data {}",
standard_id.as_raw(),
can_frame_normal.data()
);
} else {
panic!("unexpected CAN extended frame ID");
}
} else {
defmt::error!("received unexpected CAN remote frame");
}
}
fn send_and_receive_rtr_on_dedicated_channel(
can: &mut Can,
tx: &mut CanTx,
rx_dedicated: &mut CanRx,
) {
let rtr_frame = CanFrame::Rtr(CanFrameRtr::new(can::Id::Standard(STANDARD_ID_1), 0));
// RTR bit is masked, so the setting should not matter.
rx_dedicated.configure_for_reception_with_standard_id(STANDARD_ID_1, false);
tx.transmit_frame(rtr_frame).unwrap();
// Await frame transmission completion.
nb::block!(tx.remote_transfer_done()).unwrap();
check_and_handle_errors(can);
let frame = nb::block!(rx_dedicated.receive(true)).expect("invalid CAN rx state");
check_and_handle_errors(can);
if let CanFrame::Rtr(can_frame_rtr) = frame {
if let can::Id::Standard(standard_id) = can_frame_rtr.id() {
defmt::info!("received CAN RTR frame with ID {:#X}", standard_id.as_raw(),);
} else {
panic!("unexpected CAN extended frame ID");
}
} else {
defmt::error!("received unexpected CAN data frame");
}
}
fn check_and_handle_errors(can: &mut Can) {
let err_counter = can.read_error_counters();
if err_counter.transmit() > 0 || err_counter.receive() > 0 {
defmt::warn!(
@ -78,24 +139,6 @@ async fn main(_spawner: Spawner) {
let diag = can.read_error_diagnostics();
defmt::warn!("EFID: {}, EBID: {}", diag.efid(), diag.ebid());
}
match frame {
CanFrame::Normal(can_frame_normal) => match can_frame_normal.id() {
can::Id::Standard(standard_id) => {
defmt::info!(
"received CAN frame with ID {:#X} and data {}",
standard_id.as_raw(),
can_frame_normal.data()
);
}
can::Id::Extended(_) => (),
},
_ => {
defmt::error!("received unexpected CAN remote frame");
}
}
loop {
cortex_m::asm::nop();
}
}
#[interrupt]