aboutsummaryrefslogtreecommitdiff
path: root/playground
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2016-01-02 21:13:31 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2016-01-02 21:13:31 +0100
commitbaedda497d16c5096971eee83a0c467fe663fe6d (patch)
tree2f8925c68d94aed7d5fc7022462abbb359200b9e /playground
parent9129af503c8211d713c8a160a3b6f3f86b328639 (diff)
downloadstm32f103-playground-baedda497d16c5096971eee83a0c467fe663fe6d.tar.gz
stm32f103-playground-baedda497d16c5096971eee83a0c467fe663fe6d.tar.bz2
stm32f103-playground-baedda497d16c5096971eee83a0c467fe663fe6d.tar.xz
stm32f103-playground-baedda497d16c5096971eee83a0c467fe663fe6d.zip
o Moving around a lot of files.
Diffstat (limited to 'playground')
-rw-r--r--playground/include/debug.h44
-rw-r--r--playground/include/init_high.h120
-rw-r--r--playground/include/playground.h12
-rw-r--r--playground/include/stm32f10x_conf.h38
-rw-r--r--playground/src/debug.cpp44
-rw-r--r--playground/src/init_high.cpp315
-rw-r--r--playground/src/init_low.s42
7 files changed, 615 insertions, 0 deletions
diff --git a/playground/include/debug.h b/playground/include/debug.h
new file mode 100644
index 0000000..d2926b3
--- /dev/null
+++ b/playground/include/debug.h
@@ -0,0 +1,44 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__attribute__((format (printf, 1, 2)))
+void dbg_printf(const char *fmt, ...);
+
+void dbg_putc(void * junk, char);
+
+enum SemihostingCmd {
+ SYS_CLOSE = 0x02,
+ SYS_CLOCK = 0x10,
+ SYS_ELAPSED = 0x30,
+ SYS_ERRNO = 0x13,
+ SYS_FLEN = 0x0C,
+ SYS_GET_CMDLINE = 0x15,
+ SYS_HEAPINFO = 0x16,
+ SYS_ISERROR = 0x08,
+ SYS_ISTTY = 0x09,
+ SYS_OPEN = 0x01,
+ SYS_READ = 0x06,
+ SYS_READC = 0x07,
+ SYS_REMOVE = 0x0E,
+ SYS_RENAME = 0x0F,
+ SYS_SEEK = 0x0A,
+ SYS_SYSTEM = 0x12,
+ SYS_TICKFREQ = 0x31,
+ SYS_TIME = 0x11,
+ SYS_TMPNAM = 0x0D,
+ SYS_WRITE = 0x05,
+ SYS_WRITEC = 0x03,
+ SYS_WRITE0 = 0x04,
+};
+
+void send_command(enum SemihostingCmd command, void *message);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/playground/include/init_high.h b/playground/include/init_high.h
new file mode 100644
index 0000000..c6da514
--- /dev/null
+++ b/playground/include/init_high.h
@@ -0,0 +1,120 @@
+#ifndef INIT_HIGH_H
+#define INIT_HIGH_H
+
+extern "C" {
+
+void init_high();
+
+/**
+ * Declare all the interrupt/event handlers as weak symbols and make them aliases of the default handler.
+ */
+extern void Default_Handler() __attribute__((weak));
+
+extern void _Reset_Handler();
+
+extern void NMI_Handler();
+
+extern void HardFault_Handler();
+
+extern void MemManage_Handler();
+
+extern void BusFault_Handler();
+
+extern void UsageFault_Handler();
+
+extern void SVC_Handler();
+
+extern void DebugMon_Handler();
+
+extern void PendSV_Handler();
+
+extern void SysTick_Handler();
+
+extern void WWDG_IRQHandler();
+
+extern void PVD_IRQHandler();
+
+extern void TAMPER_IRQHandler();
+
+extern void RTC_IRQHandler();
+
+extern void FLASH_IRQHandler();
+
+extern void RCC_IRQHandler();
+
+extern void EXTI0_IRQHandler();
+
+extern void EXTI1_IRQHandler();
+
+extern void EXTI2_IRQHandler();
+
+extern void EXTI3_IRQHandler();
+
+extern void EXTI4_IRQHandler();
+
+extern void DMA1_Channel1_IRQHandler();
+
+extern void DMA1_Channel2_IRQHandler();
+
+extern void DMA1_Channel3_IRQHandler();
+
+extern void DMA1_Channel4_IRQHandler();
+
+extern void DMA1_Channel5_IRQHandler();
+
+extern void DMA1_Channel6_IRQHandler();
+
+extern void DMA1_Channel7_IRQHandler();
+
+extern void ADC1_2_IRQHandler();
+
+extern void USB_HP_CAN1_TX_IRQHandler();
+
+extern void USB_LP_CAN1_RX0_IRQHandler();
+
+extern void CAN1_RX1_IRQHandler();
+
+extern void CAN1_SCE_IRQHandler();
+
+extern void EXTI9_5_IRQHandler();
+
+extern void TIM1_BRK_IRQHandler();
+
+extern void TIM1_UP_IRQHandler();
+
+extern void TIM1_TRG_COM_IRQHandler();
+
+extern void TIM1_CC_IRQHandler();
+
+extern void TIM2_IRQHandler();
+
+extern void TIM3_IRQHandler();
+
+extern void TIM4_IRQHandler();
+
+extern void I2C1_EV_IRQHandler();
+
+extern void I2C1_ER_IRQHandler();
+
+extern void I2C2_EV_IRQHandler();
+
+extern void I2C2_ER_IRQHandler();
+
+extern void SPI1_IRQHandler();
+
+extern void SPI2_IRQHandler();
+
+extern void USART1_IRQHandler();
+
+extern void USART2_IRQHandler();
+
+extern void USART3_IRQHandler();
+
+extern void EXTI15_10_IRQHandler();
+
+extern void RTCAlarm_IRQHandler();
+
+extern void USBWakeUp_IRQHandler();
+}
+
+#endif
diff --git a/playground/include/playground.h b/playground/include/playground.h
new file mode 100644
index 0000000..c224908
--- /dev/null
+++ b/playground/include/playground.h
@@ -0,0 +1,12 @@
+#ifndef PLAYGROUND_H
+#define PLAYGROUND_H
+
+extern "C" void halt();
+
+template<typename T, size_t N>
+static inline
+size_t SizeOfArray(const T(&)[N]) {
+ return N;
+}
+
+#endif
diff --git a/playground/include/stm32f10x_conf.h b/playground/include/stm32f10x_conf.h
new file mode 100644
index 0000000..f663d12
--- /dev/null
+++ b/playground/include/stm32f10x_conf.h
@@ -0,0 +1,38 @@
+#ifndef __STM32F10x_CONF_H
+#define __STM32F10x_CONF_H
+
+/*
+#include "stm32f10x_adc.h"
+#include "stm32f10x_bkp.h"
+#include "stm32f10x_can.h"
+#include "stm32f10x_cec.h"
+#include "stm32f10x_crc.h"
+#include "stm32f10x_dac.h"
+#include "stm32f10x_dbgmcu.h"
+#include "stm32f10x_dma.h"
+#include "stm32f10x_exti.h"
+#include "stm32f10x_flash.h"
+#include "stm32f10x_fsmc.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_i2c.h"
+#include "stm32f10x_iwdg.h"
+#include "stm32f10x_pwr.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_rtc.h"
+#include "stm32f10x_sdio.h"
+#include "stm32f10x_spi.h"
+#include "stm32f10x_tim.h"
+#include "stm32f10x_usart.h"
+#include "stm32f10x_wwdg.h"
+#include "misc.h"
+*/
+
+#ifdef USE_FULL_ASSERT
+ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0)
+#endif
+
+#endif
diff --git a/playground/src/debug.cpp b/playground/src/debug.cpp
new file mode 100644
index 0000000..40f2169
--- /dev/null
+++ b/playground/src/debug.cpp
@@ -0,0 +1,44 @@
+#include "debug.h"
+#include "tinyprintf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static void append_char(void *v, char c) {
+ *(*((char **) v))++ = c;
+}
+
+void dbg_printf(const char *fmt, ...) {
+ char msg[100];
+ msg[0] = 0;
+
+ va_list va;
+ va_start(va, fmt);
+ char *a = msg;
+ char **b = &a;
+ tfp_format(b, append_char, fmt, va);
+ va_end(va);
+ append_char(b, '\0');
+
+ send_command(SYS_WRITE0, msg);
+}
+
+void dbg_putc(void *, char c) {
+ char cc = c;
+ send_command(SYS_WRITEC, &cc);
+}
+
+void send_command(enum SemihostingCmd command, void *message) {
+ int c = command;
+
+ __asm volatile (
+ "mov r0, %[cmd];"
+ "mov r1, %[msg];"
+ "bkpt #0xAB" : : [cmd] "r"(c), [msg] "r"(message) : "r0", "r1", "memory"
+ );
+}
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/playground/src/init_high.cpp b/playground/src/init_high.cpp
new file mode 100644
index 0000000..700d17a
--- /dev/null
+++ b/playground/src/init_high.cpp
@@ -0,0 +1,315 @@
+#include <cstdint>
+#include <cstddef>
+#include "stm32f10x.h"
+#include "debug.h"
+#include "init_high.h"
+#include "playground.h"
+
+/**
+ * Symbols that are defined by the linker
+ */
+extern uint32_t _copy_data_load, _copy_data_store, _copy_data_store_end;
+extern uint32_t _bss_start, _bss_end;
+
+extern int main();
+
+void init_high() {
+ // Copy data from flash to ram
+ uint32_t *src = &_copy_data_load;
+ uint32_t *dest = &_copy_data_store;
+ uint32_t *end = &_copy_data_store_end;
+
+ while (dest <= end) {
+ *dest++ = *src++;
+ }
+
+ // Clear the BSS segment
+ dest = &_bss_start;
+ end = &_bss_end;
+ while (dest <= end) {
+ *dest++ = 0;
+ }
+
+ main();
+}
+
+__attribute__((used))
+struct {
+ uint32_t CFSR;
+ uint32_t HFSR;
+ uint32_t DFSR;
+ uint32_t AFSR;
+// uint32_t MMAR;
+ uint32_t BFAR;
+} Default_Handler_Info;
+
+__attribute__((used))
+void Default_Handler() {
+ Default_Handler_Info = {
+ CFSR: SCB->CFSR,
+ HFSR: SCB->HFSR,
+ DFSR: SCB->DFSR,
+ AFSR: SCB->AFSR,
+ BFAR: SCB->BFAR,
+ };
+
+ dbg_printf("Default handler:\n");
+
+ dbg_printf("HFSR: 0x%08lx\n", Default_Handler_Info.HFSR);
+ if (Default_Handler_Info.HFSR & SCB_HFSR_DEBUGEVT) {
+ dbg_printf(" HFSR.DEBUGEVT\n");
+ }
+ if (Default_Handler_Info.HFSR & SCB_HFSR_FORCED) {
+ dbg_printf(" HFSR.FORCED\n");
+ }
+ if (Default_Handler_Info.HFSR & SCB_HFSR_VECTTBL) {
+ dbg_printf(" HFSR.VECTTBL\n");
+ }
+
+ dbg_printf("CFSR: 0x%08lx\n", Default_Handler_Info.CFSR);
+ if (Default_Handler_Info.CFSR & SCB_CFSR_DIVBYZERO) {
+ dbg_printf(" UFSR.DIVBYZERO\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_UNALIGNED) {
+ dbg_printf(" UFSR.UNALIGED\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_NOCP) {
+ dbg_printf(" UFSR.NOCP\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_INVPC) {
+ dbg_printf(" UFSR.INVPC\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_INVSTATE) {
+ dbg_printf(" UFSR.INVSTATE\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_UNDEFINSTR) {
+ dbg_printf(" UFSR.UNDEFINSTR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) {
+ dbg_printf(" BFSR.BFARVALID\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_STKERR) {
+ dbg_printf(" BFSR.STKERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_UNSTKERR) {
+ dbg_printf(" BFSR.UNSTKERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) {
+ dbg_printf(" BFSR.IMPRECISERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) {
+ dbg_printf(" BFSR.IMPRECISERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_PRECISERR) {
+ dbg_printf(" BFSR.PRECISERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_IBUSERR) {
+ dbg_printf(" BFSR.IBUSERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_MMARVALID) {
+ dbg_printf(" MMFSR.MMARVALID\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_MSTKERR) {
+ dbg_printf(" MMFSR.MSTKERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_MUNSTKERR) {
+ dbg_printf(" MMFSR.MUNSTKERR\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_DACCVIOL) {
+ dbg_printf(" MMFSR.DACCVIOL\n");
+ }
+ if (Default_Handler_Info.CFSR & SCB_CFSR_IACCVIOL) {
+ dbg_printf(" MMFSR.IACCVIOL\n");
+ }
+ dbg_printf("DFSR: 0x%08lx\n", Default_Handler_Info.DFSR);
+ dbg_printf("AFSR: 0x%08lx\n", Default_Handler_Info.AFSR);
+
+ if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) {
+ dbg_printf("BFAR: 0x%08lx\n", Default_Handler_Info.BFAR);
+ } else {
+ dbg_printf("BFAR: <invalid>\n");
+ }
+
+ dbg_printf("NVIC:\n");
+ for (size_t i = 0; i < SizeOfArray(NVIC->IABR); i++) {
+ dbg_printf(" IABR[%d]: 0x%08lx\n", i, NVIC->IABR[i]);
+ }
+
+ halt();
+}
+
+void _Reset_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void NMI_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void HardFault_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void MemManage_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void BusFault_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void UsageFault_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void SVC_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DebugMon_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void PendSV_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void SysTick_Handler() __attribute__ ((weak, alias("Default_Handler")));
+
+void WWDG_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void PVD_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TAMPER_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void RTC_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void FLASH_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void RCC_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI0_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI3_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI4_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel1_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel2_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel3_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel4_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel5_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel6_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void DMA1_Channel7_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void ADC1_2_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void USB_HP_CAN1_TX_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void USB_LP_CAN1_RX0_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void CAN1_RX1_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void CAN1_SCE_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI9_5_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM1_BRK_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM1_UP_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM1_TRG_COM_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM1_CC_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM2_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM3_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void TIM4_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void I2C1_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void I2C1_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void I2C2_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void I2C2_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void SPI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void SPI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void USART1_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void USART2_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void USART3_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void EXTI15_10_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void RTCAlarm_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+void USBWakeUp_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
+
+__attribute__((section(".isr_vectors"), used))
+uint32_t isr_vectors[74] = {
+ (uint32_t) _Reset_Handler,
+ (uint32_t) NMI_Handler,
+ (uint32_t) HardFault_Handler,
+ (uint32_t) MemManage_Handler,
+ (uint32_t) BusFault_Handler,
+ (uint32_t) UsageFault_Handler,
+ 0,
+ 0,
+ 0,
+ 0,
+ (uint32_t) SVC_Handler,
+ (uint32_t) DebugMon_Handler,
+ 0,
+ (uint32_t) PendSV_Handler,
+ (uint32_t) SysTick_Handler,
+ (uint32_t) WWDG_IRQHandler,
+ (uint32_t) PVD_IRQHandler,
+ (uint32_t) TAMPER_IRQHandler,
+ (uint32_t) RTC_IRQHandler,
+ (uint32_t) FLASH_IRQHandler,
+ (uint32_t) RCC_IRQHandler,
+ (uint32_t) EXTI0_IRQHandler,
+ (uint32_t) EXTI1_IRQHandler,
+ (uint32_t) EXTI2_IRQHandler,
+ (uint32_t) EXTI3_IRQHandler,
+ (uint32_t) EXTI4_IRQHandler,
+ (uint32_t) DMA1_Channel1_IRQHandler,
+ (uint32_t) DMA1_Channel2_IRQHandler,
+ (uint32_t) DMA1_Channel3_IRQHandler,
+ (uint32_t) DMA1_Channel4_IRQHandler,
+ (uint32_t) DMA1_Channel5_IRQHandler,
+ (uint32_t) DMA1_Channel6_IRQHandler,
+ (uint32_t) DMA1_Channel7_IRQHandler,
+ (uint32_t) ADC1_2_IRQHandler,
+ (uint32_t) USB_HP_CAN1_TX_IRQHandler,
+ (uint32_t) USB_LP_CAN1_RX0_IRQHandler,
+ (uint32_t) CAN1_RX1_IRQHandler,
+ (uint32_t) CAN1_SCE_IRQHandler,
+ (uint32_t) EXTI9_5_IRQHandler,
+ (uint32_t) TIM1_BRK_IRQHandler,
+ (uint32_t) TIM1_UP_IRQHandler,
+ (uint32_t) TIM1_TRG_COM_IRQHandler,
+ (uint32_t) TIM1_CC_IRQHandler,
+ (uint32_t) TIM2_IRQHandler,
+ (uint32_t) TIM3_IRQHandler,
+ (uint32_t) TIM4_IRQHandler,
+ (uint32_t) I2C1_EV_IRQHandler,
+ (uint32_t) I2C1_ER_IRQHandler,
+ (uint32_t) I2C2_EV_IRQHandler,
+ (uint32_t) I2C2_ER_IRQHandler,
+ (uint32_t) SPI1_IRQHandler,
+ (uint32_t) SPI2_IRQHandler,
+ (uint32_t) USART1_IRQHandler,
+ (uint32_t) USART2_IRQHandler,
+ (uint32_t) USART3_IRQHandler,
+ (uint32_t) EXTI15_10_IRQHandler,
+ (uint32_t) RTCAlarm_IRQHandler,
+ (uint32_t) USBWakeUp_IRQHandler,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
diff --git a/playground/src/init_low.s b/playground/src/init_low.s
new file mode 100644
index 0000000..bc12b5b
--- /dev/null
+++ b/playground/src/init_low.s
@@ -0,0 +1,42 @@
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+.thumb_func
+.global _Reset_Handler
+_Reset_Handler:
+ bl init_high
+ b halt
+
+.thumb_func
+.global halt
+halt:
+ b .
+
+.thumb_func
+NMI_Handler:
+ b halt
+
+.thumb_func
+HardFault_Handler:
+ tst lr, #4
+ ite eq
+ mrseq r0, msp
+ mrsne r0, psp
+ b HardFault_Handler_C
+
+.thumb_func
+MemManage_Handler:
+ b halt
+
+.thumb_func
+BusFault_Handler:
+ b halt
+
+.thumb_func
+UsageFault_Handler:
+ b halt
+
+.end