added RTR example
This commit is contained in:
@ -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]
|
||||
|
Reference in New Issue
Block a user