Merge pull request #3032 from cschuhen/feature/bxcan_no_generics2

Remove more BXCAN generics.
This commit is contained in:
Dario Nieuwenhuis 2024-06-02 10:33:14 +00:00 committed by GitHub
commit 5f8f867eae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 100 additions and 83 deletions

View File

@ -2,7 +2,7 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use super::{ExtendedId, Fifo, FilterOwner, Id, Instance, MasterInstance, StandardId}; use super::{ExtendedId, Fifo, Id, StandardId};
const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames
const F32_IDE: u32 = 0b100; // set the IDE bit to match extended identifiers const F32_IDE: u32 = 0b100; // set the IDE bit to match extended identifiers
@ -210,24 +210,24 @@ impl From<Mask32> for BankConfig {
} }
/// Interface to the filter banks of a CAN peripheral. /// Interface to the filter banks of a CAN peripheral.
pub struct MasterFilters<'a, I: FilterOwner> { pub struct MasterFilters<'a> {
/// Number of assigned filter banks. /// Number of assigned filter banks.
/// ///
/// On chips with splittable filter banks, this value can be dynamic. /// On chips with splittable filter banks, this value can be dynamic.
bank_count: u8, bank_count: u8,
_can: PhantomData<&'a mut I>, _phantom: PhantomData<&'a ()>,
canregs: crate::pac::can::Can, info: &'static crate::can::Info,
} }
// NOTE: This type mutably borrows the CAN instance and has unique access to the registers while it // NOTE: This type mutably borrows the CAN instance and has unique access to the registers while it
// exists. // exists.
impl<I: FilterOwner> MasterFilters<'_, I> { impl MasterFilters<'_> {
pub(crate) unsafe fn new(canregs: crate::pac::can::Can) -> Self { pub(crate) unsafe fn new(info: &'static crate::can::Info) -> Self {
// Enable initialization mode. // Enable initialization mode.
canregs.fmr().modify(|reg| reg.set_finit(true)); info.regs.0.fmr().modify(|reg| reg.set_finit(true));
// Read the filter split value. // Read the filter split value.
let bank_count = canregs.fmr().read().can2sb(); let bank_count = info.regs.0.fmr().read().can2sb();
// (Reset value of CAN2SB is 0x0E, 14, which, in devices with 14 filter banks, assigns all // (Reset value of CAN2SB is 0x0E, 14, which, in devices with 14 filter banks, assigns all
// of them to the master peripheral, and in devices with 28, assigns them 50/50 to // of them to the master peripheral, and in devices with 28, assigns them 50/50 to
@ -235,8 +235,8 @@ impl<I: FilterOwner> MasterFilters<'_, I> {
Self { Self {
bank_count, bank_count,
_can: PhantomData, _phantom: PhantomData,
canregs, info,
} }
} }
@ -244,7 +244,7 @@ impl<I: FilterOwner> MasterFilters<'_, I> {
FilterBanks { FilterBanks {
start_idx: 0, start_idx: 0,
bank_count: self.bank_count, bank_count: self.bank_count,
canregs: self.canregs, info: self.info,
} }
} }
@ -291,49 +291,49 @@ impl<I: FilterOwner> MasterFilters<'_, I> {
} }
} }
impl<I: MasterInstance> MasterFilters<'_, I> { impl MasterFilters<'_> {
/// Sets the index at which the filter banks owned by the slave peripheral start. /// Sets the index at which the filter banks owned by the slave peripheral start.
pub fn set_split(&mut self, split_index: u8) -> &mut Self { pub fn set_split(&mut self, split_index: u8) -> &mut Self {
assert!(split_index <= I::NUM_FILTER_BANKS); assert!(split_index <= self.info.num_filter_banks);
self.canregs.fmr().modify(|reg| reg.set_can2sb(split_index)); self.info.regs.0.fmr().modify(|reg| reg.set_can2sb(split_index));
self.bank_count = split_index; self.bank_count = split_index;
self self
} }
/// Accesses the filters assigned to the slave peripheral. /// Accesses the filters assigned to the slave peripheral.
pub fn slave_filters(&mut self) -> SlaveFilters<'_, I> { pub fn slave_filters(&mut self) -> SlaveFilters<'_> {
// NB: This mutably borrows `self`, so it has full access to the filter bank registers. // NB: This mutably borrows `self`, so it has full access to the filter bank registers.
SlaveFilters { SlaveFilters {
start_idx: self.bank_count, start_idx: self.bank_count,
bank_count: I::NUM_FILTER_BANKS - self.bank_count, bank_count: self.info.num_filter_banks - self.bank_count,
_can: PhantomData, _phantom: PhantomData,
canregs: self.canregs, info: self.info,
} }
} }
} }
impl<I: FilterOwner> Drop for MasterFilters<'_, I> { impl Drop for MasterFilters<'_> {
#[inline] #[inline]
fn drop(&mut self) { fn drop(&mut self) {
// Leave initialization mode. // Leave initialization mode.
self.canregs.fmr().modify(|regs| regs.set_finit(false)); self.info.regs.0.fmr().modify(|regs| regs.set_finit(false));
} }
} }
/// Interface to the filter banks assigned to a slave peripheral. /// Interface to the filter banks assigned to a slave peripheral.
pub struct SlaveFilters<'a, I: Instance> { pub struct SlaveFilters<'a> {
start_idx: u8, start_idx: u8,
bank_count: u8, bank_count: u8,
_can: PhantomData<&'a mut I>, _phantom: PhantomData<&'a ()>,
canregs: crate::pac::can::Can, info: &'static crate::can::Info,
} }
impl<I: Instance> SlaveFilters<'_, I> { impl SlaveFilters<'_> {
fn banks_imm(&self) -> FilterBanks { fn banks_imm(&self) -> FilterBanks {
FilterBanks { FilterBanks {
start_idx: self.start_idx, start_idx: self.start_idx,
bank_count: self.bank_count, bank_count: self.bank_count,
canregs: self.canregs, info: self.info,
} }
} }
@ -377,14 +377,14 @@ impl<I: Instance> SlaveFilters<'_, I> {
struct FilterBanks { struct FilterBanks {
start_idx: u8, start_idx: u8,
bank_count: u8, bank_count: u8,
canregs: crate::pac::can::Can, info: &'static crate::can::Info,
} }
impl FilterBanks { impl FilterBanks {
fn clear(&mut self) { fn clear(&mut self) {
let mask = filter_bitmask(self.start_idx, self.bank_count); let mask = filter_bitmask(self.start_idx, self.bank_count);
self.canregs.fa1r().modify(|reg| { self.info.regs.0.fa1r().modify(|reg| {
for i in 0..28usize { for i in 0..28usize {
if (0x01u32 << i) & mask != 0 { if (0x01u32 << i) & mask != 0 {
reg.set_fact(i, false); reg.set_fact(i, false);
@ -399,7 +399,11 @@ impl FilterBanks {
fn disable(&mut self, index: u8) { fn disable(&mut self, index: u8) {
self.assert_bank_index(index); self.assert_bank_index(index);
self.canregs.fa1r().modify(|reg| reg.set_fact(index as usize, false)) self.info
.regs
.0
.fa1r()
.modify(|reg| reg.set_fact(index as usize, false))
} }
fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) { fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) {
@ -407,11 +411,11 @@ impl FilterBanks {
// Configure mode. // Configure mode.
let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_)); let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_));
self.canregs.fm1r().modify(|reg| reg.set_fbm(index as usize, mode)); self.info.regs.0.fm1r().modify(|reg| reg.set_fbm(index as usize, mode));
// Configure scale. // Configure scale.
let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_)); let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_));
self.canregs.fs1r().modify(|reg| reg.set_fsc(index as usize, scale)); self.info.regs.0.fs1r().modify(|reg| reg.set_fsc(index as usize, scale));
// Configure filter register. // Configure filter register.
let (fxr1, fxr2); let (fxr1, fxr2);
@ -433,12 +437,12 @@ impl FilterBanks {
fxr2 = a.mask; fxr2 = a.mask;
} }
}; };
let bank = self.canregs.fb(index as usize); let bank = self.info.regs.0.fb(index as usize);
bank.fr1().write(|w| w.0 = fxr1); bank.fr1().write(|w| w.0 = fxr1);
bank.fr2().write(|w| w.0 = fxr2); bank.fr2().write(|w| w.0 = fxr2);
// Assign to the right FIFO // Assign to the right FIFO
self.canregs.ffa1r().modify(|reg| { self.info.regs.0.ffa1r().modify(|reg| {
reg.set_ffa( reg.set_ffa(
index as usize, index as usize,
match fifo { match fifo {
@ -449,7 +453,7 @@ impl FilterBanks {
}); });
// Set active. // Set active.
self.canregs.fa1r().modify(|reg| reg.set_fact(index as usize, true)) self.info.regs.0.fa1r().modify(|reg| reg.set_fact(index as usize, true))
} }
} }

View File

@ -6,7 +6,7 @@ use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::interrupt::InterruptExt; use embassy_hal_internal::interrupt::InterruptExt;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::into_ref;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -91,11 +91,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
} }
/// Configuration proxy returned by [`Can::modify_config`]. /// Configuration proxy returned by [`Can::modify_config`].
pub struct CanConfig<'a, T: Instance> { pub struct CanConfig<'a> {
can: PhantomData<&'a mut T>, phantom: PhantomData<&'a ()>,
info: &'static Info,
periph_clock: crate::time::Hertz,
} }
impl<T: Instance> CanConfig<'_, T> { impl CanConfig<'_> {
/// Configures the bit timings. /// Configures the bit timings.
/// ///
/// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
@ -109,7 +111,7 @@ impl<T: Instance> CanConfig<'_, T> {
/// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr` /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr`
/// parameter to this method. /// parameter to this method.
pub fn set_bit_timing(self, bt: crate::can::util::NominalBitTiming) -> Self { pub fn set_bit_timing(self, bt: crate::can::util::NominalBitTiming) -> Self {
Registers(T::regs()).set_bit_timing(bt); self.info.regs.set_bit_timing(bt);
self self
} }
@ -117,20 +119,20 @@ impl<T: Instance> CanConfig<'_, T> {
/// ///
/// This is a helper that internally calls `set_bit_timing()`[Self::set_bit_timing]. /// This is a helper that internally calls `set_bit_timing()`[Self::set_bit_timing].
pub fn set_bitrate(self, bitrate: u32) -> Self { pub fn set_bitrate(self, bitrate: u32) -> Self {
let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
self.set_bit_timing(bit_timing) self.set_bit_timing(bit_timing)
} }
/// Enables or disables loopback mode: Internally connects the TX and RX /// Enables or disables loopback mode: Internally connects the TX and RX
/// signals together. /// signals together.
pub fn set_loopback(self, enabled: bool) -> Self { pub fn set_loopback(self, enabled: bool) -> Self {
Registers(T::regs()).set_loopback(enabled); self.info.regs.set_loopback(enabled);
self self
} }
/// Enables or disables silent mode: Disconnects the TX signal from the pin. /// Enables or disables silent mode: Disconnects the TX signal from the pin.
pub fn set_silent(self, enabled: bool) -> Self { pub fn set_silent(self, enabled: bool) -> Self {
Registers(T::regs()).set_silent(enabled); self.info.regs.set_silent(enabled);
self self
} }
@ -141,23 +143,24 @@ impl<T: Instance> CanConfig<'_, T> {
/// ///
/// Automatic retransmission is enabled by default. /// Automatic retransmission is enabled by default.
pub fn set_automatic_retransmit(self, enabled: bool) -> Self { pub fn set_automatic_retransmit(self, enabled: bool) -> Self {
Registers(T::regs()).set_automatic_retransmit(enabled); self.info.regs.set_automatic_retransmit(enabled);
self self
} }
} }
impl<T: Instance> Drop for CanConfig<'_, T> { impl Drop for CanConfig<'_> {
#[inline] #[inline]
fn drop(&mut self) { fn drop(&mut self) {
Registers(T::regs()).leave_init_mode(); self.info.regs.leave_init_mode();
} }
} }
/// CAN driver /// CAN driver
pub struct Can<'d, T: Instance> { pub struct Can<'d> {
_peri: PeripheralRef<'d, T>, phantom: PhantomData<&'d ()>,
info: &'static Info, info: &'static Info,
state: &'static State, state: &'static State,
periph_clock: crate::time::Hertz,
} }
/// Error returned by `try_write` /// Error returned by `try_write`
@ -168,11 +171,11 @@ pub enum TryWriteError {
Full, Full,
} }
impl<'d, T: Instance> Can<'d, T> { impl<'d> Can<'d> {
/// Creates a new Bxcan instance, keeping the peripheral in sleep mode. /// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
/// You must call [Can::enable_non_blocking] to use the peripheral. /// You must call [Can::enable_non_blocking] to use the peripheral.
pub fn new( pub fn new<T: Instance>(
peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
_irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>> _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
@ -181,7 +184,7 @@ impl<'d, T: Instance> Can<'d, T> {
+ interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>> + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>>
+ 'd, + 'd,
) -> Self { ) -> Self {
into_ref!(peri, rx, tx); into_ref!(_peri, rx, tx);
let info = T::info(); let info = T::info();
let regs = &T::info().regs; let regs = &T::info().regs;
@ -226,15 +229,16 @@ impl<'d, T: Instance> Can<'d, T> {
Registers(T::regs()).leave_init_mode(); Registers(T::regs()).leave_init_mode();
Self { Self {
_peri: peri, phantom: PhantomData,
info: T::info(), info: T::info(),
state: T::state(), state: T::state(),
periph_clock: T::frequency(),
} }
} }
/// Set CAN bit rate. /// Set CAN bit rate.
pub fn set_bitrate(&mut self, bitrate: u32) { pub fn set_bitrate(&mut self, bitrate: u32) {
let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
self.modify_config().set_bit_timing(bit_timing); self.modify_config().set_bit_timing(bit_timing);
} }
@ -242,10 +246,14 @@ impl<'d, T: Instance> Can<'d, T> {
/// ///
/// Calling this method will enter initialization mode. You must enable the peripheral /// Calling this method will enter initialization mode. You must enable the peripheral
/// again afterwards with [`enable`](Self::enable). /// again afterwards with [`enable`](Self::enable).
pub fn modify_config(&mut self) -> CanConfig<'_, T> { pub fn modify_config(&mut self) -> CanConfig<'_> {
Registers(T::regs()).enter_init_mode(); self.info.regs.enter_init_mode();
CanConfig { can: PhantomData } CanConfig {
phantom: self.phantom,
info: self.info,
periph_clock: self.periph_clock,
}
} }
/// Enables the peripheral and synchronizes with the bus. /// Enables the peripheral and synchronizes with the bus.
@ -253,7 +261,7 @@ impl<'d, T: Instance> Can<'d, T> {
/// This will wait for 11 consecutive recessive bits (bus idle state). /// This will wait for 11 consecutive recessive bits (bus idle state).
/// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting.
pub async fn enable(&mut self) { pub async fn enable(&mut self) {
while Registers(T::regs()).enable_non_blocking().is_err() { while self.info.regs.enable_non_blocking().is_err() {
// SCE interrupt is only generated for entering sleep mode, but not leaving. // SCE interrupt is only generated for entering sleep mode, but not leaving.
// Yield to allow other tasks to execute while can bus is initializing. // Yield to allow other tasks to execute while can bus is initializing.
embassy_futures::yield_now().await; embassy_futures::yield_now().await;
@ -263,7 +271,7 @@ impl<'d, T: Instance> Can<'d, T> {
/// Enables or disables the peripheral from automatically wakeup when a SOF is detected on the bus /// Enables or disables the peripheral from automatically wakeup when a SOF is detected on the bus
/// while the peripheral is in sleep mode /// while the peripheral is in sleep mode
pub fn set_automatic_wakeup(&mut self, enabled: bool) { pub fn set_automatic_wakeup(&mut self, enabled: bool) {
Registers(T::regs()).set_automatic_wakeup(enabled); self.info.regs.set_automatic_wakeup(enabled);
} }
/// Manually wake the peripheral from sleep mode. /// Manually wake the peripheral from sleep mode.
@ -313,12 +321,12 @@ impl<'d, T: Instance> Can<'d, T> {
/// ///
/// FIFO scheduling is disabled by default. /// FIFO scheduling is disabled by default.
pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) { pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) {
Registers(T::regs()).set_tx_fifo_scheduling(enabled) self.info.regs.set_tx_fifo_scheduling(enabled)
} }
/// Checks if FIFO scheduling of outgoing frames is enabled. /// Checks if FIFO scheduling of outgoing frames is enabled.
pub fn tx_fifo_scheduling_enabled(&self) -> bool { pub fn tx_fifo_scheduling_enabled(&self) -> bool {
Registers(T::regs()).tx_fifo_scheduling_enabled() self.info.regs.tx_fifo_scheduling_enabled()
} }
/// Queues the message to be sent. /// Queues the message to be sent.
@ -448,13 +456,13 @@ impl<'d, T: Instance> Can<'d, T> {
} }
} }
impl<'d, T: FilterOwner> Can<'d, T> { impl<'d> Can<'d> {
/// Accesses the filter banks owned by this CAN peripheral. /// Accesses the filter banks owned by this CAN peripheral.
/// ///
/// To modify filters of a slave peripheral, `modify_filters` has to be called on the master /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master
/// peripheral instead. /// peripheral instead.
pub fn modify_filters(&mut self) -> MasterFilters<'_, T> { pub fn modify_filters(&mut self) -> MasterFilters<'_> {
unsafe { MasterFilters::new(self.info.regs.0) } unsafe { MasterFilters::new(self.info) }
} }
} }
@ -819,12 +827,14 @@ impl<'d, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, RX_BUF_SIZE> {
} }
} }
impl<'d, T: Instance> Drop for Can<'d, T> { impl Drop for Can<'_> {
fn drop(&mut self) { fn drop(&mut self) {
// Cannot call `free()` because it moves the instance. // Cannot call `free()` because it moves the instance.
// Manually reset the peripheral. // Manually reset the peripheral.
T::regs().mcr().write(|w| w.set_reset(true)); self.info.regs.0.mcr().write(|w| w.set_reset(true));
rcc::disable::<T>(); self.info.regs.enter_init_mode();
self.info.regs.leave_init_mode();
//rcc::disable::<T>();
} }
} }
@ -1031,6 +1041,11 @@ pub(crate) struct Info {
rx1_interrupt: crate::interrupt::Interrupt, rx1_interrupt: crate::interrupt::Interrupt,
sce_interrupt: crate::interrupt::Interrupt, sce_interrupt: crate::interrupt::Interrupt,
tx_waker: fn(), tx_waker: fn(),
/// The total number of filter banks available to the instance.
///
/// This is usually either 14 or 28, and should be specified in the chip's reference manual or datasheet.
num_filter_banks: u8,
} }
trait SealedInstance { trait SealedInstance {
@ -1095,6 +1110,7 @@ foreach_peripheral!(
rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ, rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ,
sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ, sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend, tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS,
}; };
&INFO &INFO
} }
@ -1148,6 +1164,11 @@ foreach_peripheral!(
} }
} }
}; };
(can, CAN2) => {
unsafe impl FilterOwner for peripherals::CAN2 {
const NUM_FILTER_BANKS: u8 = 0;
}
};
(can, CAN3) => { (can, CAN3) => {
unsafe impl FilterOwner for peripherals::CAN3 { unsafe impl FilterOwner for peripherals::CAN3 {
const NUM_FILTER_BANKS: u8 = 14; const NUM_FILTER_BANKS: u8 = 14;

View File

@ -11,7 +11,7 @@ use crate::can::frame::{Envelope, Frame, Header};
pub(crate) struct Registers(pub crate::pac::can::Can); pub(crate) struct Registers(pub crate::pac::can::Can);
impl Registers { impl Registers {
pub fn enter_init_mode(&mut self) { pub fn enter_init_mode(&self) {
self.0.mcr().modify(|reg| { self.0.mcr().modify(|reg| {
reg.set_sleep(false); reg.set_sleep(false);
reg.set_inrq(true); reg.set_inrq(true);
@ -25,7 +25,7 @@ impl Registers {
} }
// Leaves initialization mode, enters sleep mode. // Leaves initialization mode, enters sleep mode.
pub fn leave_init_mode(&mut self) { pub fn leave_init_mode(&self) {
self.0.mcr().modify(|reg| { self.0.mcr().modify(|reg| {
reg.set_sleep(true); reg.set_sleep(true);
reg.set_inrq(false); reg.set_inrq(false);
@ -38,7 +38,7 @@ impl Registers {
} }
} }
pub fn set_bit_timing(&mut self, bt: crate::can::util::NominalBitTiming) { pub fn set_bit_timing(&self, bt: crate::can::util::NominalBitTiming) {
let prescaler = u16::from(bt.prescaler) & 0x1FF; let prescaler = u16::from(bt.prescaler) & 0x1FF;
let seg1 = u8::from(bt.seg1); let seg1 = u8::from(bt.seg1);
let seg2 = u8::from(bt.seg2) & 0x7F; let seg2 = u8::from(bt.seg2) & 0x7F;
@ -84,7 +84,7 @@ impl Registers {
/// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming /// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming
/// frame. /// frame.
#[allow(dead_code)] #[allow(dead_code)]
pub fn set_automatic_wakeup(&mut self, enabled: bool) { pub fn set_automatic_wakeup(&self, enabled: bool) {
self.0.mcr().modify(|reg| reg.set_awum(enabled)); self.0.mcr().modify(|reg| reg.set_awum(enabled));
} }
@ -96,7 +96,7 @@ impl Registers {
/// If this returns [`WouldBlock`][nb::Error::WouldBlock], the peripheral will enable itself /// If this returns [`WouldBlock`][nb::Error::WouldBlock], the peripheral will enable itself
/// in the background. The peripheral is enabled and ready to use when this method returns /// in the background. The peripheral is enabled and ready to use when this method returns
/// successfully. /// successfully.
pub fn enable_non_blocking(&mut self) -> nb::Result<(), Infallible> { pub fn enable_non_blocking(&self) -> nb::Result<(), Infallible> {
let msr = self.0.msr().read(); let msr = self.0.msr().read();
if msr.slak() { if msr.slak() {
self.0.mcr().modify(|reg| { self.0.mcr().modify(|reg| {
@ -186,7 +186,7 @@ impl Registers {
/// If this is enabled, mailboxes are scheduled based on the time when the transmit request bit of the mailbox was set. /// If this is enabled, mailboxes are scheduled based on the time when the transmit request bit of the mailbox was set.
/// ///
/// If this is disabled, mailboxes are scheduled based on the priority of the frame in the mailbox. /// If this is disabled, mailboxes are scheduled based on the priority of the frame in the mailbox.
pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) { pub fn set_tx_fifo_scheduling(&self, enabled: bool) {
self.0.mcr().modify(|w| w.set_txfp(enabled)) self.0.mcr().modify(|w| w.set_txfp(enabled))
} }

View File

@ -45,7 +45,7 @@ async fn main(spawner: Spawner) {
let rx_pin = Input::new(&mut p.PA15, Pull::Up); let rx_pin = Input::new(&mut p.PA15, Pull::Up);
core::mem::forget(rx_pin); core::mem::forget(rx_pin);
static CAN: StaticCell<Can<'static, CAN3>> = StaticCell::new(); static CAN: StaticCell<Can<'static>> = StaticCell::new();
let can = CAN.init(Can::new(p.CAN3, p.PA8, p.PA15, Irqs)); let can = CAN.init(Can::new(p.CAN3, p.PA8, p.PA15, Irqs));
can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all());

View File

@ -18,10 +18,6 @@ use {defmt_rtt as _, panic_probe as _};
mod can_common; mod can_common;
use can_common::*; use can_common::*;
type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>;
type CanTx<'d> = embassy_stm32::can::CanTx<'d>;
type CanRx<'d> = embassy_stm32::can::CanRx<'d>;
bind_interrupts!(struct Irqs { bind_interrupts!(struct Irqs {
CAN1_RX0 => Rx0InterruptHandler<CAN1>; CAN1_RX0 => Rx0InterruptHandler<CAN1>;
CAN1_RX1 => Rx1InterruptHandler<CAN1>; CAN1_RX1 => Rx1InterruptHandler<CAN1>;
@ -50,7 +46,7 @@ async fn main(_spawner: Spawner) {
let rx_pin = Input::new(&mut rx, Pull::Up); let rx_pin = Input::new(&mut rx, Pull::Up);
core::mem::forget(rx_pin); core::mem::forget(rx_pin);
let mut can = Can::new(can, rx, tx, Irqs); let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs);
info!("Configuring can..."); info!("Configuring can...");

View File

@ -8,7 +8,7 @@ pub struct TestOptions {
pub max_buffered: u8, pub max_buffered: u8,
} }
pub async fn run_can_tests<'d>(can: &mut crate::Can<'d>, options: &TestOptions) { pub async fn run_can_tests<'d>(can: &mut can::Can<'d>, options: &TestOptions) {
//pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) { //pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) {
let mut i: u8 = 0; let mut i: u8 = 0;
loop { loop {
@ -80,7 +80,7 @@ pub async fn run_can_tests<'d>(can: &mut crate::Can<'d>, options: &TestOptions)
} }
} }
pub async fn run_split_can_tests<'d>(tx: &mut crate::CanTx<'d>, rx: &mut crate::CanRx<'d>, options: &TestOptions) { pub async fn run_split_can_tests<'d>(tx: &mut can::CanTx<'d>, rx: &mut can::CanRx<'d>, options: &TestOptions) {
for i in 0..options.max_buffered { for i in 0..options.max_buffered {
// Try filling up the RX FIFO0 buffers // Try filling up the RX FIFO0 buffers
//let tx_frame = if 0 != (i & 0x01) { //let tx_frame = if 0 != (i & 0x01) {

View File

@ -15,10 +15,6 @@ use {defmt_rtt as _, panic_probe as _};
mod can_common; mod can_common;
use can_common::*; use can_common::*;
type Can<'d> = can::Can<'d>;
type CanTx<'d> = can::CanTx<'d>;
type CanRx<'d> = can::CanRx<'d>;
bind_interrupts!(struct Irqs2 { bind_interrupts!(struct Irqs2 {
FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>; FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>; FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;