Skip to content

Commit a6f3a91

Browse files
seanybagginsPiroro-hs
authored andcommitted
added interrupt example
1 parent 907e553 commit a6f3a91

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ required-features = ["stm32f303xc"]
152152
name = "gpio_erased"
153153
required-features = ["rt", "stm32f303xc"]
154154

155+
[[example]]
156+
name = "gpio_interrupts"
157+
required-features = ["rt", "stm32f303xc"]
158+
155159
[[test]]
156160
name = "rcc"
157161
required-features = ["rt", "defmt"]

examples/gpio_interrupts.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use panic_semihosting as _;
5+
6+
use stm32f3xx_hal as hal;
7+
8+
use core::cell::RefCell;
9+
use cortex_m::asm;
10+
use cortex_m::interrupt::Mutex;
11+
use cortex_m_rt::entry;
12+
use hal::gpio::{gpioa, gpioe, Edge, Input, Output, PushPull};
13+
use hal::interrupt;
14+
use hal::pac;
15+
use hal::pac::{Interrupt, NVIC};
16+
use hal::prelude::*;
17+
18+
type LedPin = gpioe::PE9<Output<PushPull>>;
19+
static LED: Mutex<RefCell<Option<LedPin>>> = Mutex::new(RefCell::new(None));
20+
21+
type ButtonPin = gpioa::PA0<Input>;
22+
static BUTTON: Mutex<RefCell<Option<ButtonPin>>> = Mutex::new(RefCell::new(None));
23+
24+
// When the user button is pressed. The north LED with toggle.
25+
#[entry]
26+
fn main() -> ! {
27+
// Getting access to registers we will need for configuration.
28+
let device_peripherals = pac::Peripherals::take().unwrap();
29+
let mut rcc = device_peripherals.RCC.constrain();
30+
let mut syscfg = device_peripherals.SYSCFG.constrain(&mut rcc.apb2);
31+
let mut exti = device_peripherals.EXTI;
32+
let mut gpioe = device_peripherals.GPIOE.split(&mut rcc.ahb);
33+
let mut gpioa = device_peripherals.GPIOA.split(&mut rcc.ahb);
34+
35+
let mut led = gpioe
36+
.pe9
37+
.into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper);
38+
// Turn the led on so we know the configuration step occurred.
39+
led.toggle().expect("unable to toggle led in configuration");
40+
41+
// Move the ownership of the led to the global LED
42+
cortex_m::interrupt::free(|cs| *LED.borrow(cs).borrow_mut() = Some(led));
43+
44+
// Configuring the user button to trigger an interrupt when the button is pressed.
45+
let mut user_button = gpioa
46+
.pa0
47+
.into_pull_down_input(&mut gpioa.moder, &mut gpioa.pupdr);
48+
user_button.make_interrupt_source(&mut syscfg);
49+
user_button.trigger_on_edge(&mut exti, Edge::Rising);
50+
user_button.enable_interrupt(&mut exti);
51+
// Moving ownership to the global BUTTON so we can clear the interrupt pending bit.
52+
cortex_m::interrupt::free(|cs| *BUTTON.borrow(cs).borrow_mut() = Some(user_button));
53+
54+
unsafe { NVIC::unmask(Interrupt::EXTI0) };
55+
56+
loop {
57+
asm::wfi();
58+
}
59+
}
60+
61+
// Button Pressed interrupt.
62+
// The exti# maps to the pin number that is being used as an external interrupt.
63+
// See page 295 of the stm32f303 reference manual for proof:
64+
// http://www.st.com/resource/en/reference_manual/dm00043574.pdf
65+
//
66+
// This may be called more than once per button press from the user since the button may not be debounced.
67+
#[interrupt]
68+
fn EXTI0() {
69+
cortex_m::interrupt::free(|cs| {
70+
// Toggle the LED
71+
LED.borrow(cs)
72+
.borrow_mut()
73+
.as_mut()
74+
.unwrap()
75+
.toggle()
76+
.unwrap();
77+
78+
// Clear the interrupt pending bit so we don't infinitely call this routine
79+
BUTTON
80+
.borrow(cs)
81+
.borrow_mut()
82+
.as_mut()
83+
.unwrap()
84+
.clear_interrupt_pending_bit();
85+
})
86+
}

0 commit comments

Comments
 (0)