8 * These values are pushed on the stack just before
9 * entering the ISR. Normally, this would require
10 * assembly or inline assembly code. I use a so-called
11 * 'naked function' __attribute__ ((interrupt)) which
12 * gives me a little bit more control over the caller
14 * The following register are pushed to the stack
18 struct interrupt_frame {
31 * Vector table, each entry contains an interrupt
34 * interrupt vector 1-15: processor exceptions
35 * interrupt vector 16-64: irq0 - irq ..
40 /* each message corresponds to each and every exception.
41 * We get the correct message by accessing
42 * exception_message[interrupt_number]
43 * exception_message[0] is not used (=MSP)*/
44 unsigned char *exception_messages[] =
66 void ivt_set_gate(unsigned char num, void * isr(), short pri) {
68 ivt[num] = (uint32_t) isr;
69 *NVIC_ISER0 = (1 << ((uint32_t)(num) & 0x1F));
75 __attribute__ ((interrupt))
76 void * dummy_isr(struct interrupt_frame * frame) {
79 uint32_t * p = (volatile uint32_t *) 0x21000000;
85 addrtohex(frame->r12);
88 addrtohex(frame->psr);
90 //__asm__ __volatile__ ("MRS r0, IPSR");
91 //addrtohex(frame->r0);
92 uart_puts("EXCEPTION X: SYSTEM HALTED\n");
97 /* Initialize interrupt vector */
100 /* clear entiry IVT, in SRAM location for SRAM + .data (in .bss section) */
101 memset(&ivt, 0, (sizeof(uint32_t) * 87));
103 // stack top is loaded from the first entry table on boot/reset
104 // don't need to relocate or init this here
105 extern void * reset, * nmi, * hardfault;
107 for (int i = 1; i < 7; i++) {
108 ivt_set_gate(i, dummy_isr, 0);
111 /* the vector table starts at 0x0. Since the address 0x0 point to
112 * bootcode, it is on ROM or FLASH. The vector table can be
113 * relocated to other memory locations. We can do this by setting
114 * a register in the NVIC called the vector table offset register */
116 //*SCB_VTOR = (volatile uint32_t) &ivt;
117 regw_u32(SCB_VTOR, (uint32_t) &ivt, 0, 0x01);