altos/test: Adjust CRC error rate after FEC fix
[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 void _start(void) __attribute__((__noreturn__));
98
99 __attribute__ ((section(".init")))
100 const void *const __interrupt_vector[0x30] = {
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 /*
157  * Previous versions of this code had a 256 byte interupt vector. Add
158  * some padding to make sure the other low ROM variables land at the
159  * same address
160  */
161
162 __attribute__ ((section(".init.0")))
163 const void *const __interrupt_pad[0x10];
164
165 #if IS_FLASH_LOADER
166 /* Flash loader needs a magic value at 0x2fc to be 0x4E69 7370 */
167 __attribute__ ((section(".no_isp")))
168 const uint32_t force_no_isp = 0x4E697370;
169 #endif
170
171 void main(void) __attribute__((__noreturn__));
172
173 void *__interrupt_ram[sizeof(__interrupt_vector)/sizeof(__interrupt_vector[0])] __attribute((section(".preserve.1")));
174
175 extern char __data_source[];
176 extern char __data_start[];
177 extern char __data_size[];
178 extern char __bss_start[];
179 extern char __bss_size[];
180
181 void _start(void) {
182         memcpy(__data_start, __data_source, (uintptr_t) __data_size);
183         memset(__bss_start, '\0', (uintptr_t) __bss_size);
184
185 #ifdef AO_BOOT_CHAIN
186         if (ao_boot_check_chain()) {
187 #ifdef AO_BOOT_PIN
188                 if (ao_boot_check_pin())
189 #endif
190                 {
191                         ao_boot_chain(AO_BOOT_APPLICATION_BASE);
192                 }
193         }
194 #endif
195 #if RELOCATE_INTERRUPT
196         memcpy(__interrupt_ram, __interrupt_vector, sizeof(__interrupt_ram));
197         lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
198 #endif
199         main();
200 }