lpc: Initial lpcxpresso bits
[fw/altos] / src / lpc / ao_interrupt.c
diff --git a/src/lpc/ao_interrupt.c b/src/lpc/ao_interrupt.c
new file mode 100644 (file)
index 0000000..b5e6700
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <string.h>
+
+extern void main(void);
+extern char __stack__;
+extern char __text_start__, __text_end__;
+extern char __data_start__, __data_end__;
+extern char __bss_start__, __bss_end__;
+
+/* Interrupt functions */
+
+void lpc_halt_isr(void)
+{
+       ao_panic(AO_PANIC_CRASH);
+}
+
+void lpc_ignore_isr(void)
+{
+}
+
+int x;
+
+void start(void) {
+       x = 0;
+       memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__);
+       memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
+       main();
+}
+
+#define STRINGIFY(x) #x
+
+#define isr(name) \
+       void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
+       _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_ignore_isr))
+
+#define isr_halt(name) \
+       void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \
+       _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_halt_isr))
+
+isr(nmi)
+isr_halt(hardfault)
+isr_halt(memmanage)
+isr_halt(busfault)
+isr_halt(usagefault)
+isr(svc)
+isr(debugmon)
+isr(pendsv)
+isr(systick)
+
+isr(pin_int0)  /* IRQ0 */
+isr(pin_int1)
+isr(pin_int2)
+isr(pin_int3)
+isr(pin_int4)  /* IRQ4 */
+isr(pin_int5)
+isr(pin_int6)
+isr(pin_int7)
+
+isr(gint0)     /* IRQ8 */
+isr(gint1)
+isr(ssp1)
+isr(i2c)
+
+isr(ct16b0)    /* IRQ16 */
+isr(ct16b1)
+isr(ct32b0)
+isr(ct32b1)
+isr(ssp0)      /* IRQ20 */
+isr(usart)
+isr(usb_irq)
+isr(usb_fiq)
+
+isr(adc)       /* IRQ24 */
+isr(wwdt)
+isr(bod)
+isr(flash)
+
+isr(usb_wakeup)
+
+#define i(addr,name)   [(addr)/4] = lpc_ ## name ## _isr
+#define c(addr,value)  [(addr)/4] = (value)
+
+__attribute__ ((section(".interrupt")))
+const void *lpc_interrupt_vector[] = {
+       [0] = &__stack__,
+       [1] = start,
+       i(0x08, nmi),
+       i(0x0c, hardfault),
+       c(0x10, 0),
+       c(0x14, 0),
+       c(0x18, 0),
+       c(0x1c, 0),
+       c(0x20, 0),
+       c(0x24, 0),
+       c(0x28, 0),
+       i(0x2c, svc),
+       i(0x30, hardfault),
+       i(0x34, hardfault),
+       i(0x38, pendsv),
+       i(0x3c, systick),
+
+       i(0x40, pin_int0),      /* IRQ0 */
+       i(0x44, pin_int1),
+       i(0x48, pin_int2),
+       i(0x4c, pin_int3),
+       i(0x50, pin_int4),      /* IRQ4 */
+       i(0x54, pin_int5),
+       i(0x58, pin_int6),
+       i(0x5c, pin_int7),
+
+       i(0x60, gint0),         /* IRQ8 */
+       i(0x64, gint1),
+       i(0x68, hardfault),
+       i(0x6c, hardfault),
+       i(0x70, hardfault),     /* IRQ12 */
+       i(0x74, hardfault),
+       i(0x78, ssp1),
+       i(0x7c, i2c),
+
+       i(0x80, ct16b0),        /* IRQ16 */
+       i(0x84, ct16b1),
+       i(0x88, ct32b0),
+       i(0x8c, ct32b1),
+       i(0x90, ssp0),          /* IRQ20 */
+       i(0x94, usart),
+       i(0x98, usb_irq),
+       i(0x9c, usb_fiq),
+
+       i(0xa0, adc),           /* IRQ24 */
+       i(0xa4, wwdt),
+       i(0xa8, bod),
+       i(0xac, flash),
+
+       i(0xb0, hardfault),     /* IRQ28 */
+       i(0xb4, hardfault),
+       i(0xb8, usb_wakeup),
+       i(0xbc, hardfault),     
+};