summaryrefslogtreecommitdiff
path: root/firmware/src/simtrace/main_simtrace.c
diff options
context:
space:
mode:
authorMin Xu <min.xu@min-info.net>2014-10-25 21:30:23 +0200
committerHarald Welte <laforge@gnumonks.org>2014-11-11 22:30:55 +0100
commit8701086cacca088ae34580908cec45f77042b94e (patch)
tree0755b6b6439acf52ed66ef9b8d1c093247137a64 /firmware/src/simtrace/main_simtrace.c
parent6bafd0cfb40c2d201f8723a3678dd4f04b380842 (diff)
Retrieve + print previous PC from stack to debug wdog/spurious IRQ
Retrive previous PC from the stack before entering specific interrupt handler routines. Allow user to trace where interrupt occured: e.g. WatchDog and Spurious interrupt Prior to this change, spurious interrupt would occur so much (observed via gdb/remote debug) so it appears that the board stalled. Once a custom spurious interrupt installed, the code continues after the interrupt instead of re-entering the interrupt.
Diffstat (limited to 'firmware/src/simtrace/main_simtrace.c')
-rw-r--r--firmware/src/simtrace/main_simtrace.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/firmware/src/simtrace/main_simtrace.c b/firmware/src/simtrace/main_simtrace.c
index b3f2665..b84525f 100644
--- a/firmware/src/simtrace/main_simtrace.c
+++ b/firmware/src/simtrace/main_simtrace.c
@@ -136,8 +136,24 @@ static int simtrace_usb_in(struct req_ctx *rctx)
}
}
+void custom_spurious_handler(unsigned previous_pc)
+{
+ char dbg_buf[100];
+ sprintf(dbg_buf, "SPURRIOUS IRQ [Old PC = %08X]\n\r", previous_pc);
+ AT91F_DBGU_Frame(dbg_buf);
+}
+
+void custom_spurious_entry(void)
+{
+ register unsigned *previous_pc asm("r0");
+ asm("ADD R1, SP, #16; LDR R0, [R1]");
+ custom_spurious_handler(previous_pc);
+}
+
void _init_func(void)
{
+ AT91C_BASE_AIC->AIC_SPU = (int)custom_spurious_entry;
+
/* low-level hardware initialization */
pio_irq_init();
iso_uart_init();
personal git repositories of Harald Welte. Your mileage may vary