radomctld/firmware/src/bootloader.rs
2025-12-23 15:16:17 +01:00

54 lines
1.2 KiB
Rust

use core::mem::MaybeUninit;
use stm32f4xx_hal::pac;
fn jump_to_bootloader() {
unsafe {
cortex_m::interrupt::disable();
let address: u32 = 0x1FFF0000;
let device = pac::Peripherals::steal();
device.SYSCFG.memrmp().modify(|_, w| w.bits(0x01));
let mut p = cortex_m::Peripherals::steal();
p.SCB.invalidate_icache();
p.SCB.vtor.write(address as u32);
cortex_m::interrupt::enable();
cortex_m::asm::bootload(address as *const u32);
}
}
const BOOTLOADER_REQUESTED: u32 = 0xdecafbad;
#[link_section = ".uninit.DFU_FLAG"]
static mut DFU_FLAG: MaybeUninit<u32> = MaybeUninit::uninit();
fn get_bootloader_flag() -> u32 {
unsafe { DFU_FLAG.assume_init() }
}
fn set_bootloader_flag() {
unsafe { DFU_FLAG.write(BOOTLOADER_REQUESTED) };
}
fn clear_bootloader_flag() {
unsafe { DFU_FLAG.write(0) };
}
pub fn init() {
let requested = get_bootloader_flag() == BOOTLOADER_REQUESTED;
if requested {
jump_to_bootloader();
}
clear_bootloader_flag();
}
pub fn reboot_to_bootloader() -> ! {
defmt::info!("Rebooting into the bootloader");
set_bootloader_flag();
cortex_m::peripheral::SCB::sys_reset();
}