#![no_std]
#![no_main]
use core::sync::atomic::{AtomicU32, Ordering};
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use defmt_rtt as _;
use panic_halt as _;
use gd32e2_hal::fmc::{Event, Page};
use gd32e2_hal::pac::{self, interrupt};
use gd32e2_hal::prelude::*;
use gd32e2_hal::rcu::ClockConfig;
const PAGE: Page = Page::P63;
const MARKER: u32 = 0x0BAD_C0DE;
static ENDS: AtomicU32 = AtomicU32::new(0);
fn rearm() {
NVIC::unpend(pac::Interrupt::FMC);
unsafe { NVIC::unmask(pac::Interrupt::FMC) };
}
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut fmc = dp.fmc.constrain();
let _rcu = dp.rcu.constrain().freeze(&mut fmc, ClockConfig::default());
fmc.with_unlocked(|f| f.listen(Event::End));
defmt::info!("listening: {}", fmc.is_listening(Event::End));
rearm();
match fmc.with_unlocked(|f| f.erase_page(PAGE)) {
Ok(()) => defmt::info!(
"erased, handler ran {} time(s)",
ENDS.load(Ordering::Relaxed)
),
Err(e) => defmt::error!("erase failed: {}", e),
}
rearm();
match fmc.with_unlocked(|f| f.program(PAGE, 0, MARKER)) {
Ok(()) => defmt::info!(
"programmed, handler ran {} time(s)",
ENDS.load(Ordering::Relaxed)
),
Err(e) => defmt::error!("program failed: {}", e),
}
fmc.with_unlocked(|f| f.unlisten(Event::End));
let ends = ENDS.load(Ordering::Relaxed);
if ends == 2 {
defmt::info!("two operations, two interrupts");
} else {
defmt::error!("handler ran {} time(s), expected 2", ends);
}
defmt::info!("done, listening: {}", fmc.is_listening(Event::End));
loop {
cortex_m::asm::wfi();
}
}
#[interrupt]
fn FMC() {
NVIC::mask(pac::Interrupt::FMC);
ENDS.fetch_add(1, Ordering::Relaxed);
}