aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/can/fdcan.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/can/fdcan.rs')
-rw-r--r--embassy-stm32/src/can/fdcan.rs27
1 files changed, 17 insertions, 10 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index d8f71e03e..9883aff57 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -3,8 +3,8 @@ use core::future::poll_fn;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::interrupt::InterruptExt;
7use embassy_hal_internal::PeripheralType; 6use embassy_hal_internal::PeripheralType;
7use embassy_hal_internal::interrupt::InterruptExt;
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::Channel; 9use embassy_sync::channel::Channel;
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
@@ -13,7 +13,7 @@ use crate::can::fd::peripheral::Registers;
13use crate::gpio::{AfType, OutputType, Pull, SealedPin as _, Speed}; 13use crate::gpio::{AfType, OutputType, Pull, SealedPin as _, Speed};
14use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::{self, RccPeripheral}; 15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peri}; 16use crate::{Peri, interrupt, peripherals};
17 17
18pub(crate) mod fd; 18pub(crate) mod fd;
19 19
@@ -53,7 +53,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
53 regs.ir().write(|w| w.set_tefn(true)); 53 regs.ir().write(|w| w.set_tefn(true));
54 } 54 }
55 55
56 T::info().state.lock(|s| { 56 let recover_from_bo = T::info().state.lock(|s| {
57 let state = s.borrow_mut(); 57 let state = s.borrow_mut();
58 match &state.tx_mode { 58 match &state.tx_mode {
59 TxMode::NonBuffered(waker) => waker.wake(), 59 TxMode::NonBuffered(waker) => waker.wake(),
@@ -85,11 +85,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
85 if ir.rfn(1) { 85 if ir.rfn(1) {
86 state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick); 86 state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick);
87 } 87 }
88
89 state.automatic_bus_off_recovery
88 }); 90 });
89 91
90 if ir.bo() { 92 if ir.bo() {
91 regs.ir().write(|w| w.set_bo(true)); 93 regs.ir().write(|w| w.set_bo(true));
92 if regs.psr().read().bo() { 94 if let Some(true) = recover_from_bo
95 && regs.psr().read().bo()
96 {
93 // Initiate bus-off recovery sequence by resetting CCCR.INIT 97 // Initiate bus-off recovery sequence by resetting CCCR.INIT
94 regs.cccr().modify(|w| w.set_init(false)); 98 regs.cccr().modify(|w| w.set_init(false));
95 } 99 }
@@ -182,8 +186,8 @@ impl<'d> CanConfigurator<'d> {
182 rx: Peri<'d, impl RxPin<T>>, 186 rx: Peri<'d, impl RxPin<T>>,
183 tx: Peri<'d, impl TxPin<T>>, 187 tx: Peri<'d, impl TxPin<T>>,
184 _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>> 188 _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
185 + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>> 189 + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
186 + 'd, 190 + 'd,
187 ) -> CanConfigurator<'d> { 191 ) -> CanConfigurator<'d> {
188 set_as_af!(rx, AfType::input(Pull::None)); 192 set_as_af!(rx, AfType::input(Pull::None));
189 set_as_af!(tx, AfType::output(OutputType::PushPull, Speed::VeryHigh)); 193 set_as_af!(tx, AfType::output(OutputType::PushPull, Speed::VeryHigh));
@@ -263,7 +267,9 @@ impl<'d> CanConfigurator<'d> {
263 pub fn start(self, mode: OperatingMode) -> Can<'d> { 267 pub fn start(self, mode: OperatingMode) -> Can<'d> {
264 let ns_per_timer_tick = calc_ns_per_timer_tick(&self.info, self.periph_clock, self.config.frame_transmit); 268 let ns_per_timer_tick = calc_ns_per_timer_tick(&self.info, self.periph_clock, self.config.frame_transmit);
265 self.info.state.lock(|s| { 269 self.info.state.lock(|s| {
266 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick; 270 let mut state = s.borrow_mut();
271 state.ns_per_timer_tick = ns_per_timer_tick;
272 state.automatic_bus_off_recovery = Some(self.config.automatic_bus_off_recovery);
267 }); 273 });
268 self.info.regs.into_mode(self.config, mode); 274 self.info.regs.into_mode(self.config, mode);
269 Can { 275 Can {
@@ -459,7 +465,7 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
459 pub async fn write(&mut self, frame: Frame) { 465 pub async fn write(&mut self, frame: Frame) {
460 self.tx_buf.send(frame).await; 466 self.tx_buf.send(frame).await;
461 self.info.interrupt0.pend(); // Wake for Tx 467 self.info.interrupt0.pend(); // Wake for Tx
462 //T::IT0Interrupt::pend(); // Wake for Tx 468 //T::IT0Interrupt::pend(); // Wake for Tx
463 } 469 }
464 470
465 /// Async read frame from RX buffer. 471 /// Async read frame from RX buffer.
@@ -548,7 +554,7 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
548 pub async fn write(&mut self, frame: FdFrame) { 554 pub async fn write(&mut self, frame: FdFrame) {
549 self.tx_buf.send(frame).await; 555 self.tx_buf.send(frame).await;
550 self.info.interrupt0.pend(); // Wake for Tx 556 self.info.interrupt0.pend(); // Wake for Tx
551 //T::IT0Interrupt::pend(); // Wake for Tx 557 //T::IT0Interrupt::pend(); // Wake for Tx
552 } 558 }
553 559
554 /// Async read frame from RX buffer. 560 /// Async read frame from RX buffer.
@@ -861,7 +867,7 @@ struct State {
861 sender_instance_count: usize, 867 sender_instance_count: usize,
862 tx_pin_port: Option<u8>, 868 tx_pin_port: Option<u8>,
863 rx_pin_port: Option<u8>, 869 rx_pin_port: Option<u8>,
864 870 automatic_bus_off_recovery: Option<bool>, // controlled by CanConfigurator::start()
865 pub err_waker: AtomicWaker, 871 pub err_waker: AtomicWaker,
866} 872}
867 873
@@ -876,6 +882,7 @@ impl State {
876 sender_instance_count: 0, 882 sender_instance_count: 0,
877 tx_pin_port: None, 883 tx_pin_port: None,
878 rx_pin_port: None, 884 rx_pin_port: None,
885 automatic_bus_off_recovery: None,
879 } 886 }
880 } 887 }
881} 888}