summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/stm32_it.c
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal/stm32_it.c')
-rw-r--r--stmhal/stm32_it.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c
index e1129ac397..913f1c9315 100644
--- a/stmhal/stm32_it.c
+++ b/stmhal/stm32_it.c
@@ -70,9 +70,13 @@
#include "stm32_it.h"
#include STM32_HAL_H
+#include "py/mpstate.h"
#include "py/obj.h"
+#include "py/mphal.h"
#include "pendsv.h"
#include "irq.h"
+#include "pybthread.h"
+#include "gccollect.h"
#include "extint.h"
#include "timer.h"
#include "uart.h"
@@ -80,6 +84,7 @@
#include "can.h"
#include "dma.h"
#include "i2c.h"
+#include "usb.h"
extern void __fatal_error(const char*);
extern PCD_HandleTypeDef pcd_fs_handle;
@@ -92,11 +97,6 @@ extern PCD_HandleTypeDef pcd_hs_handle;
// Set the following to 1 to get some more information on the Hard Fault
// More information about decoding the fault registers can be found here:
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0646a/Cihdjcfc.html
-#define REPORT_HARD_FAULT_REGS 0
-
-#if REPORT_HARD_FAULT_REGS
-
-#include "py/mphal.h"
STATIC char *fmt_hex(uint32_t val, char *buf) {
const char *hexDig = "0123456789abcdef";
@@ -122,6 +122,15 @@ STATIC void print_reg(const char *label, uint32_t val) {
mp_hal_stdout_tx_str("\r\n");
}
+STATIC void print_hex_hex(const char *label, uint32_t val1, uint32_t val2) {
+ char hex_str[9];
+ mp_hal_stdout_tx_str(label);
+ mp_hal_stdout_tx_str(fmt_hex(val1, hex_str));
+ mp_hal_stdout_tx_str(" ");
+ mp_hal_stdout_tx_str(fmt_hex(val2, hex_str));
+ mp_hal_stdout_tx_str("\r\n");
+}
+
// The ARMv7M Architecture manual (section B.1.5.6) says that upon entry
// to an exception, that the registers will be in the following order on the
// // stack: R0, R1, R2, R3, R12, LR, PC, XPSR
@@ -130,12 +139,25 @@ typedef struct {
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
} ExceptionRegisters_t;
+int pyb_hard_fault_debug = 0;
+
void HardFault_C_Handler(ExceptionRegisters_t *regs) {
+ if (!pyb_hard_fault_debug) {
+ NVIC_SystemReset();
+ }
+
+ // We need to disable the USB so it doesn't try to write data out on
+ // the VCP and then block indefinitely waiting for the buffer to drain.
+ pyb_usb_flags = 0;
+
+ mp_hal_stdout_tx_str("HardFault\r\n");
+
print_reg("R0 ", regs->r0);
print_reg("R1 ", regs->r1);
print_reg("R2 ", regs->r2);
print_reg("R3 ", regs->r3);
print_reg("R12 ", regs->r12);
+ print_reg("SP ", (uint32_t)regs);
print_reg("LR ", regs->lr);
print_reg("PC ", regs->pc);
print_reg("XPSR ", regs->xpsr);
@@ -150,6 +172,19 @@ void HardFault_C_Handler(ExceptionRegisters_t *regs) {
if (cfsr & 0x8000) {
print_reg("BFAR ", SCB->BFAR);
}
+
+ if ((void*)&_ram_start <= (void*)regs && (void*)regs < (void*)&_ram_end) {
+ mp_hal_stdout_tx_str("Stack:\r\n");
+ uint32_t *stack_top = &_estack;
+ if ((void*)regs < (void*)&_heap_end) {
+ // stack not in static stack area so limit the amount we print
+ stack_top = (uint32_t*)regs + 32;
+ }
+ for (uint32_t *sp = (uint32_t*)regs; sp < stack_top; ++sp) {
+ print_hex_hex(" ", (uint32_t)sp, *sp);
+ }
+ }
+
/* Go to infinite loop when Hard Fault exception occurs */
while (1) {
__fatal_error("HardFault");
@@ -177,14 +212,6 @@ void HardFault_Handler(void) {
" b HardFault_C_Handler \n" // Off to C land
);
}
-#else
-void HardFault_Handler(void) {
- /* Go to infinite loop when Hard Fault exception occurs */
- while (1) {
- __fatal_error("HardFault");
- }
-}
-#endif // REPORT_HARD_FAULT_REGS
/**
* @brief This function handles NMI exception.
@@ -271,7 +298,7 @@ void SysTick_Handler(void) {
uwTick += 1;
// Read the systick control regster. This has the side effect of clearing
- // the COUNTFLAG bit, which makes the logic in sys_tick_get_microseconds
+ // the COUNTFLAG bit, which makes the logic in mp_hal_ticks_us
// work properly.
SysTick->CTRL;
@@ -287,6 +314,18 @@ void SysTick_Handler(void) {
if (DMA_IDLE_ENABLED() && DMA_IDLE_TICK(uwTick)) {
dma_idle_handler(uwTick);
}
+
+ #if MICROPY_PY_THREAD
+ if (pyb_thread_enabled) {
+ if (pyb_thread_cur->timeslice == 0) {
+ if (pyb_thread_cur->run_next != pyb_thread_cur) {
+ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+ }
+ } else {
+ --pyb_thread_cur->timeslice;
+ }
+ }
+ #endif
}
/******************************************************************************/