exti.rs 2.3 KB

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