f2c16806741beb724e8b2ca4ac18c2c10c232b25
[fw/altos] / src / lpc / ao_interrupt.c
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <ao.h>
20 #include <string.h>
21 #include <ao_boot.h>
22
23 #ifndef IS_FLASH_LOADER
24 #error Should define IS_FLASH_LOADER
25 #define IS_FLASH_LOADER 0
26 #endif
27
28 #if !IS_FLASH_LOADER
29 #define RELOCATE_INTERRUPT      1
30 #endif
31
32 /* Interrupt functions */
33
34 void lpc_halt_isr(void)
35 {
36         ao_panic(AO_PANIC_CRASH);
37 }
38
39 void lpc_ignore_isr(void)
40 {
41 }
42
43 #define STRINGIFY(x) #x
44
45 #define isr(name) \
46         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
47         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_ignore_isr))
48
49 #define isr_halt(name) \
50         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
51         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_halt_isr))
52
53 isr(nmi)
54 isr_halt(hardfault)
55 isr_halt(memmanage)
56 isr_halt(busfault)
57 isr_halt(usagefault)
58 isr(svc)
59 isr(debugmon)
60 isr(pendsv)
61 isr(systick)
62
63 isr(pin_int0)   /* IRQ0 */
64 isr(pin_int1)
65 isr(pin_int2)
66 isr(pin_int3)
67 isr(pin_int4)   /* IRQ4 */
68 isr(pin_int5)
69 isr(pin_int6)
70 isr(pin_int7)
71
72 isr(gint0)      /* IRQ8 */
73 isr(gint1)
74 isr(ssp1)
75 isr(i2c)
76
77 isr(ct16b0)     /* IRQ16 */
78 isr(ct16b1)
79 isr(ct32b0)
80 isr(ct32b1)
81 isr(ssp0)       /* IRQ20 */
82 isr(usart)
83 isr(usb_irq)
84 isr(usb_fiq)
85
86 isr(adc)        /* IRQ24 */
87 isr(wwdt)
88 isr(bod)
89 isr(flash)
90
91 isr(usb_wakeup)
92
93 #define i(addr,name)    [(addr)/4] = lpc_ ## name ## _isr
94 #define c(addr,value)   [(addr)/4] = (value)
95
96 extern char __stack[];
97 extern void _start(void);
98
99 __attribute__ ((section(".init")))
100 const void *const lpc_interrupt_vector[0x40] = {
101         [0] = __stack,
102         [1] = _start,
103         i(0x08, nmi),
104         i(0x0c, hardfault),
105         c(0x10, 0),
106         c(0x14, 0),
107         c(0x18, 0),
108         c(0x1c, 0),
109         c(0x20, 0),
110         c(0x24, 0),
111         c(0x28, 0),
112         i(0x2c, svc),
113         i(0x30, hardfault),
114         i(0x34, hardfault),
115         i(0x38, pendsv),
116         i(0x3c, systick),
117
118         i(0x40, pin_int0),      /* IRQ0 */
119         i(0x44, pin_int1),
120         i(0x48, pin_int2),
121         i(0x4c, pin_int3),
122         i(0x50, pin_int4),      /* IRQ4 */
123         i(0x54, pin_int5),
124         i(0x58, pin_int6),
125         i(0x5c, pin_int7),
126
127         i(0x60, gint0),         /* IRQ8 */
128         i(0x64, gint1),
129         i(0x68, hardfault),
130         i(0x6c, hardfault),
131         i(0x70, hardfault),     /* IRQ12 */
132         i(0x74, hardfault),
133         i(0x78, ssp1),
134         i(0x7c, i2c),
135
136         i(0x80, ct16b0),        /* IRQ16 */
137         i(0x84, ct16b1),
138         i(0x88, ct32b0),
139         i(0x8c, ct32b1),
140         i(0x90, ssp0),          /* IRQ20 */
141         i(0x94, usart),
142         i(0x98, usb_irq),
143         i(0x9c, usb_fiq),
144
145         i(0xa0, adc),           /* IRQ24 */
146         i(0xa4, wwdt),
147         i(0xa8, bod),
148         i(0xac, flash),
149
150         i(0xb0, hardfault),     /* IRQ28 */
151         i(0xb4, hardfault),
152         i(0xb8, usb_wakeup),
153         i(0xbc, hardfault),
154 };
155
156 extern char __interrupt_start[];
157
158 void _init(void);
159
160 void _init(void)
161 {
162 #ifdef AO_BOOT_CHAIN
163         if (ao_boot_check_chain()) {
164 #ifdef AO_BOOT_PIN
165                 ao_boot_check_pin();
166 #endif
167         }
168 #endif
169 #if RELOCATE_INTERRUPT
170         /* This will erase the boot chain data */
171         memcpy(__interrupt_start, lpc_interrupt_vector, sizeof (lpc_interrupt_vector));
172         lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
173 #endif
174 }
175