exti.rs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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 stm32f1xx_hal::gpio::*;
  16. // These two are owned by the ISR. main() may only access them during the initialization phase,
  17. // where the interrupt is not yet enabled (i.e. no concurrent accesses can occur).
  18. // After enabling the interrupt, main() may not have any references to these objects any more.
  19. // For the sake of minimalism, we do not use RTFM here, which would be the better way.
  20. static mut LED : MaybeUninit<stm32f1xx_hal::gpio::gpioc::PC13<Output<PushPull>>> = MaybeUninit::uninit();
  21. static mut INT_PIN : MaybeUninit<stm32f1xx_hal::gpio::gpioa::PA7<Input<Floating>>> = MaybeUninit::uninit();
  22. #[interrupt]
  23. fn EXTI9_5() {
  24. let led = unsafe { &mut *LED.as_mut_ptr()};
  25. let int_pin = unsafe { &mut *INT_PIN.as_mut_ptr()};
  26. if int_pin.check_interrupt() {
  27. led.toggle().unwrap();
  28. // if we don't clear this bit, the ISR would trigger indefinitely
  29. int_pin.clear_interrupt_pending_bit();
  30. }
  31. }
  32. #[entry]
  33. fn main() -> ! {
  34. // initialization phase
  35. let p = pac::Peripherals::take().unwrap();
  36. let _cp = cortex_m::peripheral::Peripherals::take().unwrap();
  37. {
  38. // the scope ensures that the int_pin reference is dropped before the first ISR can be executed.
  39. let mut rcc = p.RCC.constrain();
  40. let mut gpioa = p.GPIOA.split(&mut rcc.apb2);
  41. let mut gpioc = p.GPIOC.split(&mut rcc.apb2);
  42. let mut afio = p.AFIO.constrain(&mut rcc.apb2);
  43. let led = unsafe { &mut *LED.as_mut_ptr()};
  44. *led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
  45. let int_pin = unsafe { &mut *INT_PIN.as_mut_ptr()};
  46. *int_pin = gpioa.pa7.into_floating_input(&mut gpioa.crl);
  47. int_pin.make_interrupt_source(&mut afio);
  48. int_pin.trigger_on_edge(&p.EXTI, Edge::RISING_FALLING);
  49. int_pin.enable_interrupt(&p.EXTI);
  50. } // initialization ends here
  51. unsafe { pac::NVIC::unmask(pac::Interrupt::EXTI9_5); }
  52. loop {}
  53. }