#![deny(warnings)]
#![no_main]
#![no_std]
use core::cell::{Cell, RefCell};
use cortex_m::interrupt::{free, Mutex};
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use stm32h7xx_hal::gpio::{Edge, ExtiPin, Input, Output, PushPull};
use stm32h7xx_hal::{interrupt, pac, prelude::*};
use stm32h7xx_hal::gpio::gpioa::PA1;
use stm32h7xx_hal::gpio::gpioc::PC5;
use stm32h7xx_hal::gpio::gpioe::PE3;
#[macro_use]
mod utilities;
use log::info;
static SEMAPHORE: Mutex<Cell<bool>> = Mutex::new(Cell::new(true));
static BUTTON1_PIN: Mutex<RefCell<Option<PE3<Input>>>> =
Mutex::new(RefCell::new(None));
static BUTTON2_PIN: Mutex<RefCell<Option<PC5<Input>>>> =
Mutex::new(RefCell::new(None));
static LED: Mutex<RefCell<Option<PA1<Output<PushPull>>>>> =
Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
utilities::logger::init();
info!("stm32h7xx-hal example - EXTI Interrupt");
let mut cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
info!("Setup PWR...");
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
info!("Setup RCC...");
let rcc = dp.RCC.constrain();
let ccdr = rcc.sys_ck(100.MHz()).freeze(pwrcfg, &dp.SYSCFG);
let mut syscfg = dp.SYSCFG;
let mut exti = dp.EXTI;
let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE);
let mut button1 = gpioe.pe3.into_pull_up_input();
button1.make_interrupt_source(&mut syscfg);
button1.trigger_on_edge(&mut exti, Edge::Rising);
button1.enable_interrupt(&mut exti);
let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC);
let mut button2 = gpioc.pc5.into_pull_up_input();
button2.make_interrupt_source(&mut syscfg);
button2.trigger_on_edge(&mut exti, Edge::Rising);
button2.enable_interrupt(&mut exti);
let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
let led = gpioa.pa1.into_push_pull_output();
free(|cs| {
BUTTON1_PIN.borrow(cs).replace(Some(button1));
BUTTON2_PIN.borrow(cs).replace(Some(button2));
LED.borrow(cs).replace(Some(led));
});
unsafe {
cp.NVIC.set_priority(interrupt::EXTI3, 1);
cp.NVIC.set_priority(interrupt::EXTI9_5, 1);
NVIC::unmask::<interrupt>(interrupt::EXTI3);
NVIC::unmask::<interrupt>(interrupt::EXTI9_5);
}
loop {
cortex_m::asm::nop();
}
}
fn toggle_led(on_or_off: bool) {
free(|cs| {
if let Some(b) = LED.borrow(cs).borrow_mut().as_mut() {
if on_or_off {
b.set_high();
} else {
b.set_low();
}
}
});
}
#[interrupt]
fn EXTI9_5() {
info!("EXTI9_5 fired!");
toggle_led(true);
free(|cs| {
if let Some(b) = BUTTON2_PIN.borrow(cs).borrow_mut().as_mut() {
b.clear_interrupt_pending_bit()
}
SEMAPHORE.borrow(cs).set(false);
});
}
#[interrupt]
fn EXTI3() {
info!("EXTI3 fired!");
toggle_led(false);
free(|cs| {
if let Some(b) = BUTTON1_PIN.borrow(cs).borrow_mut().as_mut() {
b.clear_interrupt_pending_bit()
}
SEMAPHORE.borrow(cs).set(false);
});
}