const DFU_REBOOT_FLAG: u32 = 0xDEAD_BEEF;
extern "C" {
static mut _bootflag: u8;
}
pub fn start_dfu_reboot() {
unsafe {
core::ptr::write_unaligned(
core::ptr::addr_of_mut!(_bootflag).cast(),
DFU_REBOOT_FLAG,
);
}
cortex_m::peripheral::SCB::sys_reset();
}
pub fn dfu_bootflag() -> bool {
unsafe {
let start_ptr = core::ptr::addr_of_mut!(_bootflag).cast();
let set = DFU_REBOOT_FLAG == core::ptr::read_unaligned(start_ptr);
core::ptr::write_unaligned(start_ptr, 0);
set
}
}
pub fn execute_system_bootloader() {
cortex_m::interrupt::disable();
let systick = unsafe { &*cortex_m::peripheral::SYST::PTR };
unsafe {
systick.csr.write(0);
systick.rvr.write(0);
systick.cvr.write(0);
}
let nvic = unsafe { &*cortex_m::peripheral::NVIC::PTR };
for reg in nvic.icer.iter() {
unsafe {
reg.write(u32::MAX);
}
}
for reg in nvic.icpr.iter() {
unsafe {
reg.write(u32::MAX);
}
}
unsafe { cortex_m::interrupt::enable() };
unsafe {
let system_memory_address: *const u32 = 0x1FF0_9800 as *const u32;
log::info!("Jumping to DFU");
cortex_m::asm::bootload(system_memory_address);
}
}