FDCAN: Fix offset issue preventing CAN2 and CAN3 from working.

Fix for not H7
This commit is contained in:
Corey Schuhen 2024-03-16 19:24:47 +10:00
parent c580d4c490
commit 3f5c8784af
2 changed files with 57 additions and 3 deletions

View File

@ -30,7 +30,12 @@ impl Registers {
&mut self.msg_ram_mut().transmit.tbsa[bufidx] &mut self.msg_ram_mut().transmit.tbsa[bufidx]
} }
pub fn msg_ram_mut(&self) -> &mut RegisterBlock { pub fn msg_ram_mut(&self) -> &mut RegisterBlock {
#[cfg(stm32h7)]
let ptr = self.msgram.ram(self.msg_ram_offset / 4).as_ptr() as *mut RegisterBlock;
#[cfg(not(stm32h7))]
let ptr = self.msgram.as_ptr() as *mut RegisterBlock; let ptr = self.msgram.as_ptr() as *mut RegisterBlock;
unsafe { &mut (*ptr) } unsafe { &mut (*ptr) }
} }
@ -637,7 +642,7 @@ impl Registers {
use crate::can::fd::message_ram::*; use crate::can::fd::message_ram::*;
//use fdcan::message_ram::*; //use fdcan::message_ram::*;
let mut offset_words = self.msg_ram_offset as u16; let mut offset_words = (self.msg_ram_offset / 4) as u16;
// 11-bit filter // 11-bit filter
r.sidfc().modify(|w| w.set_flssa(offset_words)); r.sidfc().modify(|w| w.set_flssa(offset_words));

View File

@ -13,7 +13,11 @@ use embassy_stm32::{bind_interrupts, can, Config};
use embassy_time::{Duration, Instant}; use embassy_time::{Duration, Instant};
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs { bind_interrupts!(struct Irqs2 {
FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;
});
bind_interrupts!(struct Irqs1 {
FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
}); });
@ -75,17 +79,24 @@ async fn main(_spawner: Spawner) {
let options = options(); let options = options();
let peripherals = embassy_stm32::init(options.config); let peripherals = embassy_stm32::init(options.config);
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs); let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1);
let mut can2 = can::FdcanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2);
// 250k bps // 250k bps
can.set_bitrate(250_000); can.set_bitrate(250_000);
can2.set_bitrate(250_000);
can.set_extended_filter( can.set_extended_filter(
can::filter::ExtendedFilterSlot::_0, can::filter::ExtendedFilterSlot::_0,
can::filter::ExtendedFilter::accept_all_into_fifo1(), can::filter::ExtendedFilter::accept_all_into_fifo1(),
); );
can2.set_extended_filter(
can::filter::ExtendedFilterSlot::_0,
can::filter::ExtendedFilter::accept_all_into_fifo1(),
);
let mut can = can.into_internal_loopback_mode(); let mut can = can.into_internal_loopback_mode();
let mut can2 = can2.into_internal_loopback_mode();
info!("CAN Configured"); info!("CAN Configured");
@ -126,6 +137,44 @@ async fn main(_spawner: Spawner) {
} }
} }
let mut i: u8 = 0;
loop {
let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap();
info!("Transmitting frame...");
let tx_ts = Instant::now();
can2.write(&tx_frame).await;
let (frame, timestamp) = can2.read().await.unwrap();
info!("Frame received!");
//print_regs().await;
// Check data.
assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]);
info!("loopback time {}", timestamp);
info!("loopback frame {=u8}", frame.data()[0]);
let latency = timestamp.saturating_duration_since(tx_ts);
info!("loopback latency {} us", latency.as_micros());
// Theoretical minimum latency is 55us, actual is usually ~80us
const MIN_LATENCY: Duration = Duration::from_micros(50);
// Was failing at 150 but we are not getting a real time stamp. I'm not
// sure if there are other delays
assert!(
MIN_LATENCY <= latency && latency <= options.max_latency,
"{} <= {} <= {}",
MIN_LATENCY,
latency,
options.max_latency
);
i += 1;
if i > 10 {
break;
}
}
let max_buffered = if options.second_fifo_working { 6 } else { 3 }; let max_buffered = if options.second_fifo_working { 6 } else { 3 };
// Below here, check that we can receive from both FIFO0 and FIFO0 // Below here, check that we can receive from both FIFO0 and FIFO0