Skip to content

Commit

Permalink
Merge pull request #413 from quartiq/issue/355/reboot-to-dfu
Browse files Browse the repository at this point in the history
Refactoring reboot to DFU
  • Loading branch information
jordens authored Jul 2, 2024
2 parents 6c1eb12 + c145e17 commit 6294c32
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 31 deletions.
File renamed without changes.
4 changes: 3 additions & 1 deletion memory.x
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ MEMORY
/* NOTE 1 K = 1 KiBi = 1024 bytes */
/* Note: The last 256KB flash sector is reserved for settings storage. */
FLASH : ORIGIN = 0x08000000, LENGTH = 768K
RAM : ORIGIN = 0x20000000, LENGTH = 127K
RAM : ORIGIN = 0x20000000, LENGTH = 126K
PANDUMP : ORIGIN = 0x2001FC00, LENGTH = 1K
BOOTFLAG_RAM: ORIGIN = 0x2001F800, LENGTH = 1K
}

_bootflag = ORIGIN(BOOTFLAG_RAM);
_panic_dump_start = ORIGIN(PANDUMP);
_panic_dump_end = ORIGIN(PANDUMP) + LENGTH(PANDUMP);

Expand Down
76 changes: 47 additions & 29 deletions src/hardware/platform.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Booster NGFW Application

// Flag used to indicate that a reboot to DFU is requested.
const DFU_REBOOT_FLAG: u32 = 0xDEAD_BEEF;

use super::hal;

use hal::hal_02::{blocking::delay::DelayUs, digital::v2::OutputPin};
Expand Down Expand Up @@ -116,45 +119,60 @@ pub fn clear_reset_flags() {
rcc.csr.modify(|_, w| w.rmvf().set_bit());
}

/// Reset the device to the internal DFU bootloader.
pub fn reset_to_dfu_bootloader() {
// Disable the SysTick peripheral.
let systick = unsafe { &*cortex_m::peripheral::SYST::PTR };
unsafe {
systick.csr.write(0);
systick.rvr.write(0);
systick.cvr.write(0);
pub fn start_dfu_reboot() {
extern "C" {
static mut _bootflag: u32;
}

// Disable the USB peripheral.
let usb_otg = unsafe { &*hal::pac::OTG_FS_GLOBAL::ptr() };
usb_otg.gccfg.write(|w| unsafe { w.bits(0) });
unsafe {
let start_ptr = core::ptr::addr_of_mut!(_bootflag);
core::ptr::write_unaligned(start_ptr, DFU_REBOOT_FLAG)
}

// Reset the RCC configuration.
let rcc = unsafe { &*hal::pac::RCC::ptr() };
cortex_m::peripheral::SCB::sys_reset();
}

// Enable the HSI - we will be switching back to it shortly for the DFU bootloader.
rcc.cr.modify(|_, w| w.hsion().set_bit());
pub fn dfu_bootflag() -> bool {
// Obtain panic region start and end from linker symbol _panic_dump_start and _panic_dump_end
extern "C" {
static mut _bootflag: u32;
}

// Reset the CFGR and begin using the HSI for the system bus.
rcc.cfgr.reset();
unsafe {
let start_ptr = core::ptr::addr_of_mut!(_bootflag);
let set = DFU_REBOOT_FLAG == core::ptr::read_unaligned(start_ptr);

// Reset the configuration register.
rcc.cr.reset();
// Clear the boot flag after checking it to ensure it doesn't stick between reboots.
core::ptr::write_unaligned(start_ptr, 0);
set
}
}

// Reset the PLL configuration now that PLLs are unused.
rcc.pllcfgr.reset();
/// Reset the device to the internal DFU bootloader.
pub fn execute_system_bootloader() -> ! {
cortex_m::interrupt::disable();

// Remap to system memory.
rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit());
// Disable the SysTick peripheral.
let systick = unsafe { &*cortex_m::peripheral::SYST::PTR };
unsafe {
systick.csr.write(0);
systick.rvr.write(0);
systick.cvr.write(0);
}

let syscfg = unsafe { &*hal::pac::SYSCFG::ptr() };
syscfg.memrm.write(|w| unsafe { w.mem_mode().bits(0b01) });
// Clear NVIC interrupt flags and enables.
let nvic = unsafe { &*cortex_m::peripheral::NVIC::PTR };
for reg in nvic.icer.iter() {
unsafe {
reg.write(u32::MAX);
}
}

// Now that the remap is complete, impose instruction and memory barriers on the
// CPU.
cortex_m::asm::isb();
cortex_m::asm::dsb();
for reg in nvic.icpr.iter() {
unsafe {
reg.write(u32::MAX);
}
}

// It appears that they must be enabled for the USB-based DFU bootloader to operate.
unsafe { cortex_m::interrupt::enable() };
Expand Down
4 changes: 4 additions & 0 deletions src/hardware/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ pub fn setup(

log::info!("Starting initialization");

if platform::dfu_bootflag() {
platform::execute_system_bootloader();
}

core.DWT.enable_cycle_counter();
core.DCB.enable_trace();

Expand Down
2 changes: 1 addition & 1 deletion src/settings/flash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl serial_settings::Platform<5> for SerialSettingsPlatform {
// Power off all output channels and reset the MCU.
platform::shutdown_channels();

platform::reset_to_dfu_bootloader();
platform::start_dfu_reboot();
}
"service" => {
writeln!(
Expand Down

0 comments on commit 6294c32

Please sign in to comment.