aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/bxcan.rs59
-rw-r--r--examples/stm32f4/src/bin/can.rs13
2 files changed, 40 insertions, 32 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 9cd40fd8b..e23ce6863 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -5,12 +5,11 @@ use core::task::Poll;
5 5
6pub use bxcan; 6pub use bxcan;
7use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; 7use bxcan::{Data, ExtendedId, Frame, Id, StandardId};
8use embassy_cortex_m::interrupt::Interrupt;
9use embassy_hal_common::{into_ref, PeripheralRef}; 8use embassy_hal_common::{into_ref, PeripheralRef};
10use futures::FutureExt; 9use futures::FutureExt;
11 10
12use crate::gpio::sealed::AFType; 11use crate::gpio::sealed::AFType;
13use crate::interrupt::InterruptExt; 12use crate::interrupt::typelevel::Interrupt;
14use crate::pac::can::vals::{Lec, RirIde}; 13use crate::pac::can::vals::{Lec, RirIde};
15use crate::rcc::RccPeripheral; 14use crate::rcc::RccPeripheral;
16use crate::time::Hertz; 15use crate::time::Hertz;
@@ -21,7 +20,7 @@ pub struct TxInterruptHandler<T: Instance> {
21 _phantom: PhantomData<T>, 20 _phantom: PhantomData<T>,
22} 21}
23 22
24impl<T: Instance> interrupt::Handler<T::TXInterrupt> for TxInterruptHandler<T> { 23impl<T: Instance> interrupt::typelevel::Handler<T::TXInterrupt> for TxInterruptHandler<T> {
25 unsafe fn on_interrupt() { 24 unsafe fn on_interrupt() {
26 T::regs().tsr().write(|v| { 25 T::regs().tsr().write(|v| {
27 v.set_rqcp(0, true); 26 v.set_rqcp(0, true);
@@ -37,7 +36,7 @@ pub struct Rx0InterruptHandler<T: Instance> {
37 _phantom: PhantomData<T>, 36 _phantom: PhantomData<T>,
38} 37}
39 38
40impl<T: Instance> interrupt::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> { 39impl<T: Instance> interrupt::typelevel::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> {
41 unsafe fn on_interrupt() { 40 unsafe fn on_interrupt() {
42 // info!("rx0 irq"); 41 // info!("rx0 irq");
43 Can::<T>::receive_fifo(RxFifo::Fifo0); 42 Can::<T>::receive_fifo(RxFifo::Fifo0);
@@ -48,7 +47,7 @@ pub struct Rx1InterruptHandler<T: Instance> {
48 _phantom: PhantomData<T>, 47 _phantom: PhantomData<T>,
49} 48}
50 49
51impl<T: Instance> interrupt::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> { 50impl<T: Instance> interrupt::typelevel::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> {
52 unsafe fn on_interrupt() { 51 unsafe fn on_interrupt() {
53 // info!("rx1 irq"); 52 // info!("rx1 irq");
54 Can::<T>::receive_fifo(RxFifo::Fifo1); 53 Can::<T>::receive_fifo(RxFifo::Fifo1);
@@ -59,7 +58,7 @@ pub struct SceInterruptHandler<T: Instance> {
59 _phantom: PhantomData<T>, 58 _phantom: PhantomData<T>,
60} 59}
61 60
62impl<T: Instance> interrupt::Handler<T::SCEInterrupt> for SceInterruptHandler<T> { 61impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterruptHandler<T> {
63 unsafe fn on_interrupt() { 62 unsafe fn on_interrupt() {
64 // info!("sce irq"); 63 // info!("sce irq");
65 let msr = T::regs().msr(); 64 let msr = T::regs().msr();
@@ -97,10 +96,10 @@ impl<'d, T: Instance> Can<'d, T> {
97 peri: impl Peripheral<P = T> + 'd, 96 peri: impl Peripheral<P = T> + 'd,
98 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 97 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
99 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 98 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
100 _irqs: impl interrupt::Binding<T::TXInterrupt, TxInterruptHandler<T>> 99 _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
101 + interrupt::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>> 100 + interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>>
102 + interrupt::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>> 101 + interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>>
103 + interrupt::Binding<T::SCEInterrupt, SceInterruptHandler<T>> 102 + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>>
104 + 'd, 103 + 'd,
105 ) -> Self { 104 ) -> Self {
106 into_ref!(peri, rx, tx); 105 into_ref!(peri, rx, tx);
@@ -111,7 +110,7 @@ impl<'d, T: Instance> Can<'d, T> {
111 T::enable(); 110 T::enable();
112 T::reset(); 111 T::reset();
113 112
114 unsafe { 113 {
115 use crate::pac::can::vals::{Errie, Fmpie, Tmeie}; 114 use crate::pac::can::vals::{Errie, Fmpie, Tmeie};
116 115
117 T::regs().ier().write(|w| { 116 T::regs().ier().write(|w| {
@@ -127,21 +126,21 @@ impl<'d, T: Instance> Can<'d, T> {
127 // Enable timestamps on rx messages 126 // Enable timestamps on rx messages
128 127
129 w.set_ttcm(true); 128 w.set_ttcm(true);
130 }) 129 });
131 } 130 }
132 131
133 unsafe { 132 unsafe {
134 T::TXInterrupt::steal().unpend(); 133 T::TXInterrupt::unpend();
135 T::TXInterrupt::steal().enable(); 134 T::TXInterrupt::enable();
136 135
137 T::RX0Interrupt::steal().unpend(); 136 T::RX0Interrupt::unpend();
138 T::RX0Interrupt::steal().enable(); 137 T::RX0Interrupt::enable();
139 138
140 T::RX1Interrupt::steal().unpend(); 139 T::RX1Interrupt::unpend();
141 T::RX1Interrupt::steal().enable(); 140 T::RX1Interrupt::enable();
142 141
143 T::SCEInterrupt::steal().unpend(); 142 T::SCEInterrupt::unpend();
144 T::SCEInterrupt::steal().enable(); 143 T::SCEInterrupt::enable();
145 } 144 }
146 145
147 rx.set_as_af(rx.af_num(), AFType::Input); 146 rx.set_as_af(rx.af_num(), AFType::Input);
@@ -169,7 +168,7 @@ impl<'d, T: Instance> Can<'d, T> {
169 } 168 }
170 169
171 pub async fn flush(&self, mb: bxcan::Mailbox) { 170 pub async fn flush(&self, mb: bxcan::Mailbox) {
172 poll_fn(|cx| unsafe { 171 poll_fn(|cx| {
173 if T::regs().tsr().read().tme(mb.index()) { 172 if T::regs().tsr().read().tme(mb.index()) {
174 return Poll::Ready(()); 173 return Poll::Ready(());
175 } 174 }
@@ -194,7 +193,7 @@ impl<'d, T: Instance> Can<'d, T> {
194 } 193 }
195 194
196 fn curr_error(&self) -> Option<BusError> { 195 fn curr_error(&self) -> Option<BusError> {
197 let err = unsafe { T::regs().esr().read() }; 196 let err = { T::regs().esr().read() };
198 if err.boff() { 197 if err.boff() {
199 return Some(BusError::BusOff); 198 return Some(BusError::BusOff);
200 } else if err.epvf() { 199 } else if err.epvf() {
@@ -396,19 +395,19 @@ pub(crate) mod sealed {
396} 395}
397 396
398pub trait TXInstance { 397pub trait TXInstance {
399 type TXInterrupt: crate::interrupt::Interrupt; 398 type TXInterrupt: crate::interrupt::typelevel::Interrupt;
400} 399}
401 400
402pub trait RX0Instance { 401pub trait RX0Instance {
403 type RX0Interrupt: crate::interrupt::Interrupt; 402 type RX0Interrupt: crate::interrupt::typelevel::Interrupt;
404} 403}
405 404
406pub trait RX1Instance { 405pub trait RX1Instance {
407 type RX1Interrupt: crate::interrupt::Interrupt; 406 type RX1Interrupt: crate::interrupt::typelevel::Interrupt;
408} 407}
409 408
410pub trait SCEInstance { 409pub trait SCEInstance {
411 type SCEInterrupt: crate::interrupt::Interrupt; 410 type SCEInterrupt: crate::interrupt::typelevel::Interrupt;
412} 411}
413 412
414pub trait InterruptableInstance: TXInstance + RX0Instance + RX1Instance + SCEInstance {} 413pub trait InterruptableInstance: TXInstance + RX0Instance + RX1Instance + SCEInstance {}
@@ -440,22 +439,22 @@ foreach_peripheral!(
440 foreach_interrupt!( 439 foreach_interrupt!(
441 ($inst,can,CAN,TX,$irq:ident) => { 440 ($inst,can,CAN,TX,$irq:ident) => {
442 impl TXInstance for peripherals::$inst { 441 impl TXInstance for peripherals::$inst {
443 type TXInterrupt = crate::interrupt::$irq; 442 type TXInterrupt = crate::interrupt::typelevel::$irq;
444 } 443 }
445 }; 444 };
446 ($inst,can,CAN,RX0,$irq:ident) => { 445 ($inst,can,CAN,RX0,$irq:ident) => {
447 impl RX0Instance for peripherals::$inst { 446 impl RX0Instance for peripherals::$inst {
448 type RX0Interrupt = crate::interrupt::$irq; 447 type RX0Interrupt = crate::interrupt::typelevel::$irq;
449 } 448 }
450 }; 449 };
451 ($inst,can,CAN,RX1,$irq:ident) => { 450 ($inst,can,CAN,RX1,$irq:ident) => {
452 impl RX1Instance for peripherals::$inst { 451 impl RX1Instance for peripherals::$inst {
453 type RX1Interrupt = crate::interrupt::$irq; 452 type RX1Interrupt = crate::interrupt::typelevel::$irq;
454 } 453 }
455 }; 454 };
456 ($inst,can,CAN,SCE,$irq:ident) => { 455 ($inst,can,CAN,SCE,$irq:ident) => {
457 impl SCEInstance for peripherals::$inst { 456 impl SCEInstance for peripherals::$inst {
458 type SCEInterrupt = crate::interrupt::$irq; 457 type SCEInterrupt = crate::interrupt::typelevel::$irq;
459 } 458 }
460 }; 459 };
461 ); 460 );
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs
index e8377b9a1..da8955053 100644
--- a/examples/stm32f4/src/bin/can.rs
+++ b/examples/stm32f4/src/bin/can.rs
@@ -4,12 +4,21 @@
4 4
5use cortex_m_rt::entry; 5use cortex_m_rt::entry;
6use defmt::*; 6use defmt::*;
7use embassy_stm32::bind_interrupts;
7use embassy_stm32::can::bxcan::filter::Mask32; 8use embassy_stm32::can::bxcan::filter::Mask32;
8use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; 9use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId};
9use embassy_stm32::can::Can; 10use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler};
10use embassy_stm32::gpio::{Input, Pull}; 11use embassy_stm32::gpio::{Input, Pull};
12use embassy_stm32::peripherals::CAN1;
11use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
12 14
15bind_interrupts!(struct Irqs {
16 CAN1_RX0 => Rx0InterruptHandler<CAN1>;
17 CAN1_RX1 => Rx1InterruptHandler<CAN1>;
18 CAN1_SCE => SceInterruptHandler<CAN1>;
19 CAN1_TX => TxInterruptHandler<CAN1>;
20});
21
13#[entry] 22#[entry]
14fn main() -> ! { 23fn main() -> ! {
15 info!("Hello World!"); 24 info!("Hello World!");
@@ -23,7 +32,7 @@ fn main() -> ! {
23 let rx_pin = Input::new(&mut p.PA11, Pull::Up); 32 let rx_pin = Input::new(&mut p.PA11, Pull::Up);
24 core::mem::forget(rx_pin); 33 core::mem::forget(rx_pin);
25 34
26 let mut can = Can::new(p.CAN1, p.PA11, p.PA12); 35 let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs);
27 36
28 can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); 37 can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
29 38