software_dfu #46
13
src/dfu.rs
13
src/dfu.rs
|
@ -1,23 +1,30 @@
|
||||||
use cortex_m_rt::{pre_init};
|
use cortex_m_rt::{pre_init};
|
||||||
|
|
||||||
|
/// RAM location used to store DFU trigger message
|
||||||
const DFU_MSG_ADDR: usize = 0x2001BC00;
|
const DFU_MSG_ADDR: usize = 0x2001BC00;
|
||||||
|
|
||||||
|
/// DFU trigger message
|
||||||
const DFU_TRIG_MSG: usize = 0xDECAFBAD;
|
const DFU_TRIG_MSG: usize = 0xDECAFBAD;
|
||||||
|
|
||||||
|
/// Set DFU trigger message
|
||||||
pub unsafe fn trig_dfu() {
|
pub unsafe fn trig_dfu() {
|
||||||
let dfu_msg_addr = DFU_MSG_ADDR as *mut usize;
|
let dfu_msg_addr = DFU_MSG_ADDR as *mut usize;
|
||||||
*dfu_msg_addr = DFU_TRIG_MSG;
|
*dfu_msg_addr = DFU_TRIG_MSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called by reset handler in lib.rs immediately after reset, checks if booting into dfu is needed
|
||||||
#[pre_init]
|
#[pre_init]
|
||||||
#[no_mangle]
|
|
||||||
unsafe fn __pre_init() {
|
unsafe fn __pre_init() {
|
||||||
|
|
||||||
let dfu_msg_addr = DFU_MSG_ADDR as *mut usize;
|
let dfu_msg_addr = DFU_MSG_ADDR as *mut usize;
|
||||||
|
|
||||||
|
// Check DFU trigger message
|
||||||
if *dfu_msg_addr == DFU_TRIG_MSG{
|
if *dfu_msg_addr == DFU_TRIG_MSG{
|
||||||
|
|
||||||
|
|||||||
|
// Reset message
|
||||||
*dfu_msg_addr = 0x00000000;
|
*dfu_msg_addr = 0x00000000;
|
||||||
|
|
||||||
|
// Enable system config controller clock
|
||||||
const RCC_APB2ENR: *mut u32 = 0xE000_ED88 as *mut u32;
|
const RCC_APB2ENR: *mut u32 = 0xE000_ED88 as *mut u32;
|
||||||
const RCC_APB2ENR_ENABLE_SYSCFG_CLOCK: u32 = 0x00004000;
|
const RCC_APB2ENR_ENABLE_SYSCFG_CLOCK: u32 = 0x00004000;
|
||||||
|
|
||||||
|
@ -26,6 +33,7 @@ unsafe fn __pre_init() {
|
||||||
*RCC_APB2ENR | RCC_APB2ENR_ENABLE_SYSCFG_CLOCK,
|
*RCC_APB2ENR | RCC_APB2ENR_ENABLE_SYSCFG_CLOCK,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Bypass BOOT pins and remap bootloader to 0x00000000
|
||||||
const SYSCFG_MEMRMP: *mut u32 = 0x40013800 as *mut u32;
|
const SYSCFG_MEMRMP: *mut u32 = 0x40013800 as *mut u32;
|
||||||
const SYSCFG_MEMRMP_MAP_ROM: u32 = 0x00000001;
|
const SYSCFG_MEMRMP_MAP_ROM: u32 = 0x00000001;
|
||||||
|
|
||||||
|
@ -34,8 +42,11 @@ unsafe fn __pre_init() {
|
||||||
*SYSCFG_MEMRMP | SYSCFG_MEMRMP_MAP_ROM,
|
*SYSCFG_MEMRMP | SYSCFG_MEMRMP_MAP_ROM,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set stack pointer to bootloader location
|
||||||
asm!("LDR R0, =0x1FFF0000");
|
asm!("LDR R0, =0x1FFF0000");
|
||||||
asm!("LDR SP,[R0, #0]");
|
asm!("LDR SP,[R0, #0]");
|
||||||
|
|
||||||
|
// Jump to bootloader
|
||||||
asm!("LDR R0,[R0, #4]");
|
asm!("LDR R0,[R0, #4]");
|
||||||
asm!("BX R0");
|
asm!("BX R0");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
remove blank line