Hi, I'm writing a small program to record the button clicks on the microbit-v2 board. This is the initial code I wrote: ``` #![no_main] #![no_std] use core::cell::RefCell; use cortex_m::interrupt::Mutex; use cortex_m_rt::entry; use microbit::{ hal::gpiote::Gpiote, pac::{interrupt, Interrupt, NVIC}, Board, }; use panic_rtt_target as _; use rtt_target::{rprintln, rtt_init_print}; static GPIO: Mutex>> = Mutex::new(RefCell::new(None)); #[entry] fn main() -> ! { rtt_init_print!(); let board = Board::take().expect("Could not find board."); let gpiote = Gpiote::new(board.GPIOTE); let channel0 = gpiote.channel0(); channel0 .input_pin(&board.buttons.button_a.degrade()) .hi_to_lo() .enable_interrupt(); channel0.reset_events(); let channel1 = gpiote.channel1(); channel1 .input_pin(&board.buttons.button_b.degrade()) .hi_to_lo() .enable_interrupt(); channel1.reset_events(); cortex_m::interrupt::free(move |cs| { unsafe { NVIC::unmask(Interrupt::GPIOTE); } NVIC::unpend(Interrupt::GPIOTE); *GPIO.borrow(cs).borrow_mut() = Some(gpiote); rprintln!("Press one or both the buttons!"); }); loop { continue; } } #[interrupt] fn GPIOTE() { cortex_m::interrupt::free(|cs| { if let Some(gpiote) = GPIO.borrow(cs).borrow().as_ref() { for _ in 0..100000 { cortex_m::asm::nop(); } let buttonapressed = gpiote.channel0().is_event_triggered(); let buttonbpressed = gpiote.channel1().is_event_triggered(); let buttons_pressed = match (buttonapressed, buttonbpressed) { (false, false) => "", (true, false) => "A", (false, true) => "B", (true, true) => "A + B", }; rprintln!("Button pressed {:?}", buttons_pressed); gpiote.channel0().reset_events(); gpiote.channel1().reset_events(); } }); } ``` I added this because when I press both the buttons together, individual buttons clicks are getting records but not A+B ``` for _ in 0..100000 { cortex_m::asm::nop(); } ``` I wanted to improve this using Timers and this is the improvement I made ``` #![no_main] #![no_std] use core::cell::RefCell; use cortex_m::interrupt::{free, Mutex}; use cortex_m_rt::entry; use microbit::{ hal::{ gpiote::Gpiote, timer::{Instance, Timer, Prescaler}, }, pac::{interrupt, Interrupt, NVIC, TIMER0}, Board, }; use panic_rtt_target as _; use rtt_target::{rprintln, rtt_init_print}; static GPIO: Mutex>> = Mutex::new(RefCell::new(None)); static TIMER: Mutex>>> = Mutex::new(RefCell::new(None)); const DEBOUNCE_DELAY_MS: u32 = 50; #[entry] fn main() -> ! { rtt_init_print!(); let board = Board::take().expect("Could not find board."); let gpiote = Gpiote::new(board.GPIOTE); let mut timer = Timer::new(board.TIMER0); timer.reset(); timer.enable_interrupt(); let channel0 = gpiote.channel0(); channel0 .input_pin(&board.buttons.button_a.degrade()) .hi_to_lo() .enable_interrupt(); channel0.reset_events(); let channel1 = gpiote.channel1(); channel1 .input_pin(&board.buttons.button_b.degrade()) .hi_to_lo() .enable_interrupt(); channel1.reset_events(); free(move |cs| { unsafe { NVIC::unmask(Interrupt::GPIOTE); NVIC::unmask(Interrupt::TIMER0); } NVIC::unpend(Interrupt::GPIOTE); NVIC::unpend(Interrupt::TIMER0); *GPIO.borrow(cs).borrow_mut() = Some(gpiote); *TIMER.borrow(cs).borrow_mut() = Some(timer); rprintln!("Press one or both the buttons!"); }); loop { continue; } } #[interrupt] fn GPIOTE() { free(|cs| { if let Some(gpiote) = GPIO.borrow(cs).borrow().as_ref() { if let Some(timer) = TIMER.borrow(cs).borrow_mut().as_mut() { timer.start(DEBOUNCE_DELAY_MS); } gpiote.channel0().reset_events(); gpiote.channel1().reset_events(); } }); } #[interrupt] fn TIMER0() { free(|cs| { if let Some(gpiote) = GPIO.borrow(cs).borrow().as_ref() { if let Some(timer) = TIMER.borrow(cs).borrow_mut().as_mut() { timer.reset_event(); let buttonapressed = gpiote.channel0().is_input_high() == false; let buttonbpressed = gpiote.channel1().is_input_high() == false; let buttons_pressed = match (buttonapressed, buttonbpressed) { (false, false) => "", (true, false) => "A", (false, true) => "B", (true, true) => "A + B", }; rprintln!("Button pressed {:?}", buttons_pressed); } } }); } ``` But now every time I press a button I get - Button pressed "". And I think it's because of ``` gpiote.channel0().reset_events(); gpiote.channel1().reset_events(); ``` But when I move this to the TIMER interrupt, the GPIOTE interrupt gets stuck in a loop as the events are not reset. What should I do to resolve this issue? Am I doing something fundamentally wrong?