altos: Always start application if boot pin isn't in use
[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 extern void main(void);
33 extern char __stack__;
34 extern char __text_start__, __text_end__;
35 extern char _start__, _end__;
36 extern char __bss_start__, __bss_end__;
37 #if RELOCATE_INTERRUPT
38 extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__;
39 #endif
40
41 /* Interrupt functions */
42
43 void lpc_halt_isr(void)
44 {
45         ao_panic(AO_PANIC_CRASH);
46 }
47
48 void lpc_ignore_isr(void)
49 {
50 }
51
52 void start(void) {
53 #ifdef AO_BOOT_CHAIN
54         if (ao_boot_check_chain()) {
55 #ifdef AO_BOOT_PIN
56                 if (ao_boot_check_pin())
57 #endif
58                 {
59                         ao_boot_chain(AO_BOOT_APPLICATION_BASE);
60                 }
61         }
62 #endif
63 #if RELOCATE_INTERRUPT
64         memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);
65         lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
66 #endif
67         memcpy(&_start__, &__text_end__, &_end__ - &_start__);
68         memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
69         main();
70 }
71
72 #define STRINGIFY(x) #x
73
74 #define isr(name) \
75         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
76         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_ignore_isr))
77
78 #define isr_halt(name) \
79         void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
80         _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_halt_isr))
81
82 isr(nmi)
83 isr_halt(hardfault)
84 isr_halt(memmanage)
85 isr_halt(busfault)
86 isr_halt(usagefault)
87 isr(svc)
88 isr(debugmon)
89 isr(pendsv)
90 isr(systick)
91
92 isr(pin_int0)   /* IRQ0 */
93 isr(pin_int1)
94 isr(pin_int2)
95 isr(pin_int3)
96 isr(pin_int4)   /* IRQ4 */
97 isr(pin_int5)
98 isr(pin_int6)
99 isr(pin_int7)
100
101 isr(gint0)      /* IRQ8 */
102 isr(gint1)
103 isr(ssp1)
104 isr(i2c)
105
106 isr(ct16b0)     /* IRQ16 */
107 isr(ct16b1)
108 isr(ct32b0)
109 isr(ct32b1)
110 isr(ssp0)       /* IRQ20 */
111 isr(usart)
112 isr(usb_irq)
113 isr(usb_fiq)
114
115 isr(adc)        /* IRQ24 */
116 isr(wwdt)
117 isr(bod)
118 isr(flash)
119
120 isr(usb_wakeup)
121
122 #define i(addr,name)    [(addr)/4] = lpc_ ## name ## _isr
123 #define c(addr,value)   [(addr)/4] = (value)
124
125 __attribute__ ((section(".interrupt")))
126 const void *lpc_interrupt_vector[] = {
127         [0] = &__stack__,
128         [1] = start,
129         i(0x08, nmi),
130         i(0x0c, hardfault),
131         c(0x10, 0),
132         c(0x14, 0),
133         c(0x18, 0),
134         c(0x1c, 0),
135         c(0x20, 0),
136         c(0x24, 0),
137         c(0x28, 0),
138         i(0x2c, svc),
139         i(0x30, hardfault),
140         i(0x34, hardfault),
141         i(0x38, pendsv),
142         i(0x3c, systick),
143
144         i(0x40, pin_int0),      /* IRQ0 */
145         i(0x44, pin_int1),
146         i(0x48, pin_int2),
147         i(0x4c, pin_int3),
148         i(0x50, pin_int4),      /* IRQ4 */
149         i(0x54, pin_int5),
150         i(0x58, pin_int6),
151         i(0x5c, pin_int7),
152
153         i(0x60, gint0),         /* IRQ8 */
154         i(0x64, gint1),
155         i(0x68, hardfault),
156         i(0x6c, hardfault),
157         i(0x70, hardfault),     /* IRQ12 */
158         i(0x74, hardfault),
159         i(0x78, ssp1),
160         i(0x7c, i2c),
161
162         i(0x80, ct16b0),        /* IRQ16 */
163         i(0x84, ct16b1),
164         i(0x88, ct32b0),
165         i(0x8c, ct32b1),
166         i(0x90, ssp0),          /* IRQ20 */
167         i(0x94, usart),
168         i(0x98, usb_irq),
169         i(0x9c, usb_fiq),
170
171         i(0xa0, adc),           /* IRQ24 */
172         i(0xa4, wwdt),
173         i(0xa8, bod),
174         i(0xac, flash),
175
176         i(0xb0, hardfault),     /* IRQ28 */
177         i(0xb4, hardfault),
178         i(0xb8, usb_wakeup),
179         i(0xbc, hardfault),
180 };