1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
4 * 2019/7/20 - ROBIN KRENS
18 * These values are pushed on the stack just before
19 * entering the ISR. Normally, this would require
20 * assembly or inline assembly code. I use a so-called
21 * 'naked function' __attribute__ ((interrupt)) which
22 * gives me a little bit more control over the caller
24 * The following register are pushed to the stack
28 struct interrupt_frame {
41 * Vector table, each entry contains an interrupt
44 * interrupt vector 1-15: processor exceptions
45 * interrupt vector 16-92: irq0 - irq ..
48 uint32_t __attribute__((aligned(0x100))) ivt[92];
50 /* each message corresponds to each and every exception.
51 * We get the correct message by accessing
52 * exception_message[interrupt_number]
53 * exception_message[0] is not used (=MSP)*/
55 char * exception_message(uint8_t intnr) {
81 if (intnr < 20) // TODO: strlen
82 return messages[intnr];
87 void ivt_set_gate(unsigned char num, void * isr(), short pri) {
89 ivt[num] = (uint32_t) isr;
90 *NVIC_ISER0 = (1 << ((uint32_t)(num) & 0x1F));
96 // __attribute__ ((interrupt))
97 void * dummy_isr(/* struct interrupt_frame * frame */) {
99 uint8_t nr = *SCB_VTOR_ST & 0xFF;
101 uart_puts("EXCEPTION: ");
102 uart_puts(exception_message(nr));
103 uart_puts("\nSYSTEM HALTED\n");
108 /* Initialize interrupt vector */
111 /* clear entiry IVT, in SRAM location for SRAM + .data (in .bss section) */
112 memset(&ivt, 0, (sizeof(uint32_t) * 92));
114 // stack top is loaded from the first entry table on boot/reset
115 // don't need to relocate or init this here
116 extern void * reset, * nmi, * hardfault;
118 for (int i = 1; i <= 64 ; i++) {
119 ivt_set_gate(i, dummy_isr, 0);
123 /* the vector table starts at 0x0. Since the address 0x0 point to
124 * bootcode, it is on ROM or FLASH. The vector table can be
125 * relocated to other memory locations. We can do this by setting
126 * a register in the NVIC called the vector table offset register */
128 //*SCB_VTOR = (volatile uint32_t) &ivt;
129 regw_u32(SCB_VTOR, (uint32_t) &ivt, 0, OWRITE);