exti.rs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //! Turns the user LED on
  2. //!
  3. //! Listens for interrupts on the pa7 pin. On any rising or falling edge, toggles
  4. //! the pc13 pin (which is connected to the LED on the blue pill board, hence the `led` name).
  5. #![no_main]
  6. #![no_std]
  7. use panic_halt as _;
  8. use stm32f1xx_hal::{
  9. prelude::*,
  10. pac
  11. };
  12. use cortex_m_rt::entry;
  13. use pac::interrupt;
  14. use core::mem::MaybeUninit;
  15. use embedded_hal::digital::v2::OutputPin;
  16. use stm32f1xx_hal::gpio::*;
  17. // These two are owned by the ISR. main() may only access them during the initialization phase,
  18. // where the interrupt is not yet enabled (i.e. no concurrent accesses can occur).
  19. // After enabling the interrupt, main() may not have any references to these objects any more.
  20. // For the sake of minimalism, we do not use RTFM here, which would be the better way.
  21. static mut LED : MaybeUninit<stm32f1xx_hal::gpio::gpioc::PC13<Output<PushPull>>> = MaybeUninit::uninit();
  22. static mut EXTI : MaybeUninit<stm32f1xx_hal::gpio::gpioa::PA7<Input<Floating>>> = MaybeUninit::uninit();
  23. #[interrupt]
  24. fn EXTI9_5() {
  25. let led = unsafe { &mut *LED.as_mut_ptr()};
  26. let exti = unsafe { &mut *EXTI.as_mut_ptr()};
  27. if exti.check_interrupt() {
  28. led.toggle();
  29. // if we don't clear this bit, the ISR would trigger indefinitely
  30. exti.clear_interrupt_pending_bit();
  31. }
  32. }
  33. #[entry]
  34. fn main() -> ! {
  35. // initialization phase
  36. let p = pac::Peripherals::take().unwrap();
  37. let cp = cortex_m::peripheral::Peripherals::take().unwrap();
  38. {
  39. // the scope ensures that the exti reference is dropped before the first ISR can be executed.
  40. let mut rcc = p.RCC.constrain();
  41. let mut gpioa = p.GPIOA.split(&mut rcc.apb2);
  42. let mut gpioc = p.GPIOC.split(&mut rcc.apb2);
  43. let mut afio = p.AFIO.constrain(&mut rcc.apb2);
  44. let led = unsafe { &mut *LED.as_mut_ptr()};
  45. *led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
  46. let exti = unsafe { &mut *EXTI.as_mut_ptr()};
  47. *exti = gpioa.pa7.into_floating_input(&mut gpioa.crl);
  48. exti.make_interrupt_source(&mut afio);
  49. exti.trigger_on_edge(&p.EXTI, Edge::RISING_FALLING);
  50. exti.enable_interrupt(&p.EXTI);
  51. } // initialization ends here
  52. let mut nvic = cp.NVIC;
  53. nvic.enable(pac::Interrupt::EXTI9_5);
  54. loop {}
  55. }