#![no_main]
#![no_std]
extern crate panic_halt;
use core::cell::RefCell;
use core::ops::DerefMut;
use cortex_m::asm;
use cortex_m::interrupt::Mutex;
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use stm32l0xx_hal::{
exti::TriggerEdge,
gpio::*,
pac::{self, interrupt, Interrupt, EXTI},
prelude::*,
rcc::Config,
syscfg::SYSCFG,
};
static INT: Mutex<RefCell<Option<EXTI>>> = Mutex::new(RefCell::new(None));
static LED: Mutex<RefCell<Option<gpiob::PB6<Output<PushPull>>>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut rcc = dp.RCC.freeze(Config::hsi16());
let gpiob = dp.GPIOB.split(&mut rcc);
let led = gpiob.pb6.into_push_pull_output();
let button = gpiob.pb2.into_pull_up_input();
#[cfg(feature = "stm32l0x1")]
let mut syscfg = SYSCFG::new(dp.SYSCFG, &mut rcc);
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
let mut syscfg = SYSCFG::new(dp.SYSCFG_COMP, &mut rcc);
let exti = dp.EXTI;
exti.listen(&mut syscfg, button.port, button.i, TriggerEdge::Falling);
cortex_m::interrupt::free(|cs| {
*INT.borrow(cs).borrow_mut() = Some(exti);
*LED.borrow(cs).borrow_mut() = Some(led);
});
unsafe { NVIC::unmask(Interrupt::EXTI2_3); }
loop {
asm::wfi();
}
}
#[interrupt]
fn EXTI2_3() {
static mut STATE: bool = false;
cortex_m::interrupt::free(|cs| {
if let Some(ref mut exti) = INT.borrow(cs).borrow_mut().deref_mut() {
exti.clear_irq(2);
if let Some(ref mut led) = LED.borrow(cs).borrow_mut().deref_mut() {
if *STATE {
led.set_low().unwrap();
*STATE = false;
} else {
led.set_high().unwrap();
*STATE = true;
}
}
}
});
}