diff options
| -rw-r--r-- | embassy-stm32/src/can/bxcan.rs | 59 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/can.rs | 13 |
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 | ||
| 6 | pub use bxcan; | 6 | pub use bxcan; |
| 7 | use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; | 7 | use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; |
| 8 | use embassy_cortex_m::interrupt::Interrupt; | ||
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 8 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 10 | use futures::FutureExt; | 9 | use futures::FutureExt; |
| 11 | 10 | ||
| 12 | use crate::gpio::sealed::AFType; | 11 | use crate::gpio::sealed::AFType; |
| 13 | use crate::interrupt::InterruptExt; | 12 | use crate::interrupt::typelevel::Interrupt; |
| 14 | use crate::pac::can::vals::{Lec, RirIde}; | 13 | use crate::pac::can::vals::{Lec, RirIde}; |
| 15 | use crate::rcc::RccPeripheral; | 14 | use crate::rcc::RccPeripheral; |
| 16 | use crate::time::Hertz; | 15 | use crate::time::Hertz; |
| @@ -21,7 +20,7 @@ pub struct TxInterruptHandler<T: Instance> { | |||
| 21 | _phantom: PhantomData<T>, | 20 | _phantom: PhantomData<T>, |
| 22 | } | 21 | } |
| 23 | 22 | ||
| 24 | impl<T: Instance> interrupt::Handler<T::TXInterrupt> for TxInterruptHandler<T> { | 23 | impl<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 | ||
| 40 | impl<T: Instance> interrupt::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> { | 39 | impl<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 | ||
| 51 | impl<T: Instance> interrupt::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> { | 50 | impl<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 | ||
| 62 | impl<T: Instance> interrupt::Handler<T::SCEInterrupt> for SceInterruptHandler<T> { | 61 | impl<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 | ||
| 398 | pub trait TXInstance { | 397 | pub trait TXInstance { |
| 399 | type TXInterrupt: crate::interrupt::Interrupt; | 398 | type TXInterrupt: crate::interrupt::typelevel::Interrupt; |
| 400 | } | 399 | } |
| 401 | 400 | ||
| 402 | pub trait RX0Instance { | 401 | pub trait RX0Instance { |
| 403 | type RX0Interrupt: crate::interrupt::Interrupt; | 402 | type RX0Interrupt: crate::interrupt::typelevel::Interrupt; |
| 404 | } | 403 | } |
| 405 | 404 | ||
| 406 | pub trait RX1Instance { | 405 | pub trait RX1Instance { |
| 407 | type RX1Interrupt: crate::interrupt::Interrupt; | 406 | type RX1Interrupt: crate::interrupt::typelevel::Interrupt; |
| 408 | } | 407 | } |
| 409 | 408 | ||
| 410 | pub trait SCEInstance { | 409 | pub trait SCEInstance { |
| 411 | type SCEInterrupt: crate::interrupt::Interrupt; | 410 | type SCEInterrupt: crate::interrupt::typelevel::Interrupt; |
| 412 | } | 411 | } |
| 413 | 412 | ||
| 414 | pub trait InterruptableInstance: TXInstance + RX0Instance + RX1Instance + SCEInstance {} | 413 | pub 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 | ||
| 5 | use cortex_m_rt::entry; | 5 | use cortex_m_rt::entry; |
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_stm32::bind_interrupts; | ||
| 7 | use embassy_stm32::can::bxcan::filter::Mask32; | 8 | use embassy_stm32::can::bxcan::filter::Mask32; |
| 8 | use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; | 9 | use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; |
| 9 | use embassy_stm32::can::Can; | 10 | use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; |
| 10 | use embassy_stm32::gpio::{Input, Pull}; | 11 | use embassy_stm32::gpio::{Input, Pull}; |
| 12 | use embassy_stm32::peripherals::CAN1; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 14 | ||
| 15 | bind_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] |
| 14 | fn main() -> ! { | 23 | fn 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 | ||
