summaryrefslogtreecommitdiffhomepage
path: root/digital/io-hub/src/apbirthday/hardware.stm32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'digital/io-hub/src/apbirthday/hardware.stm32.cc')
-rw-r--r--digital/io-hub/src/apbirthday/hardware.stm32.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/digital/io-hub/src/apbirthday/hardware.stm32.cc b/digital/io-hub/src/apbirthday/hardware.stm32.cc
index b5123038..e60ebf78 100644
--- a/digital/io-hub/src/apbirthday/hardware.stm32.cc
+++ b/digital/io-hub/src/apbirthday/hardware.stm32.cc
@@ -25,6 +25,7 @@
#include <libopencm3/stm32/f4/rcc.h>
#include <libopencm3/stm32/f4/timer.h>
+#include <libopencm3/cm3/scb.h>
#include "ucoolib/hal/gpio/gpio.hh"
#include "zb_avrisp.stm32.hh"
@@ -153,3 +154,22 @@ Hardware::zb_handle (ucoo::Stream &s)
zb_uart.enable (38400, ucoo::Uart::EVEN, 1);
}
+void
+Hardware::bootloader ()
+{
+ // Reset every peripherals.
+ RCC_AHB1RSTR = 0xffffffff;
+ RCC_AHB2RSTR = 0xffffffff;
+ RCC_APB1RSTR = 0xffffffff;
+ RCC_APB2RSTR = 0xffffffff;
+ RCC_AHB1RSTR = 0;
+ RCC_AHB2RSTR = 0;
+ RCC_APB1RSTR = 0;
+ RCC_APB2RSTR = 0;
+ // Jump to bootloader.
+ uint32_t bootloader_address = 0x080e0000;
+ SCB_VTOR = bootloader_address & 0x1fffff;
+ asm volatile ("msr msp, %0" : : "r" (* (uint32_t *) bootloader_address));
+ (*(void (**) ()) (bootloader_address + 4)) ();
+}
+