This gets the LPC11U14 clock set to the PLL and blinks the LED.
Signed-off-by: Keith Packard <keithp@keithp.com>
--- /dev/null
+vpath % ../lpc:../product:../drivers:../core:../util:../kalman:../aes:..
+vpath make-altitude ../util
+vpath make-kalman ../util
+vpath kalman.5c ../kalman
+vpath kalman_filter.5c ../kalman
+vpath load_csv.5c ../kalman
+vpath matrix.5c ../kalman
+vpath ao-make-product.5c ../util
+
+CC=arm-none-eabi-gcc
+SAT=/opt/cortex
+SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a
+SAT_CFLAGS=-I$(SAT)/include
+
+ifndef VERSION
+include ../Version
+endif
+
+AO_CFLAGS=-I. -I../lpc -I../core -I../drivers -I..
+LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS)
+
+LDFLAGS=-L../stm -Wl,-Taltos.ld
+
+NICKLE=nickle
+
+V=0
+# The user has explicitly enabled quiet compilation.
+ifeq ($(V),0)
+quiet = @printf " $1 $2 $@\n"; $($1)
+endif
+# Otherwise, print the full command line.
+quiet ?= $($1)
+
+.c.o:
+ $(call quiet,CC) -c $(CFLAGS) -o $@ $<
+
+ao_serial_lpc.h: ../lpc/baud_rate ao_pins.h
+ nickle ../lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@
+
+ao_serial_lpc.o: ao_serial_lpc.h
+
+.DEFAULT_GOAL=all
--- /dev/null
+/*
+ * Copyright © 2012 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.
+ */
+
+MEMORY {
+ rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K
+ ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K
+}
+
+INCLUDE registers.ld
+
+EXTERN (lpc_interrupt_vector)
+
+SECTIONS {
+ /*
+ * Rom contents
+ */
+
+ .text ORIGIN(rom) : {
+ __text_start__ = .;
+ *(.interrupt) /* Interrupt vectors */
+
+ . = ORIGIN(rom) + 0x100;
+
+ ao_romconfig.o(.romconfig*)
+ ao_product.o(.romconfig*)
+
+ *(.text*) /* Executable code */
+ *(.rodata*) /* Constants */
+
+ } > rom
+
+ .ARM.exidx : {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ __text_end__ = .;
+ } > rom
+
+ /* Data -- relocated to RAM, but written to ROM
+ */
+ .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) {
+ __data_start__ = .;
+ *(.data) /* initialized data */
+ __data_end__ = .;
+ __bss_start__ = .;
+ } >ram
+
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ __bss_end__ = .;
+ } >ram
+
+ PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram));
+ PROVIDE(end = .);
+}
+
+ENTRY(start);
+
+
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef _AO_ARCH_H_
+#define _AO_ARCH_H_
+
+#include <lpc.h>
+
+/*
+ * LPC11U14 definitions and code fragments for AltOS
+ */
+
+#define AO_STACK_SIZE 512
+
+#define AO_LED_TYPE uint16_t
+
+#ifndef AO_TICK_TYPE
+#define AO_TICK_TYPE uint16_t
+#define AO_TICK_SIGNED int16_t
+#endif
+
+/* Various definitions to make GCC look more like SDCC */
+
+#define ao_arch_naked_declare __attribute__((naked))
+#define ao_arch_naked_define
+#define __pdata
+#define __data
+#define __xdata
+#define __code const
+#define __reentrant
+#define __interrupt(n)
+#define __at(n)
+
+#define ao_arch_reboot()
+
+#define ao_arch_nop() asm("nop")
+
+#define ao_arch_interrupt(n) /* nothing */
+
+#undef putchar
+#undef getchar
+#define putchar(c) ao_putchar(c)
+#define getchar ao_getchar
+
+extern void putchar(char c);
+extern char getchar(void);
+
+/*
+ * ao_romconfig.c
+ */
+
+#define AO_ROMCONFIG_VERSION 2
+
+#define AO_ROMCONFIG_SYMBOL(a) __attribute__((section(".romconfig"))) const
+
+extern const uint16_t ao_romconfig_version;
+extern const uint16_t ao_romconfig_check;
+extern const uint16_t ao_serial_number;
+extern const uint32_t ao_radio_cal;
+
+#define ao_arch_task_members\
+ uint32_t *sp; /* saved stack pointer */
+
+#define ao_arch_block_interrupts() asm("cpsid i")
+#define ao_arch_release_interrupts() asm("cpsie i")
+
+/*
+ * For now, we're running at a weird frequency
+ */
+
+#if AO_HSE
+#define AO_PLLSRC AO_HSE
+#else
+#define AO_PLLSRC STM_HSI_FREQ
+#endif
+
+#define AO_PLLVCO (AO_PLLSRC * AO_PLLMUL)
+#define AO_SYSCLK (AO_PLLVCO / AO_PLLDIV)
+#define AO_HCLK (AO_SYSCLK / AO_AHB_PRESCALER)
+#define AO_PCLK1 (AO_HCLK / AO_APB1_PRESCALER)
+#define AO_PCLK2 (AO_HCLK / AO_APB2_PRESCALER)
+
+#if AO_APB1_PRESCALER == 1
+#define AO_TIM23467_CLK AO_PCLK1
+#else
+#define AO_TIM23467_CLK (2 * AO_PCLK1)
+#endif
+
+#if AO_APB2_PRESCALER == 1
+#define AO_TIM91011_CLK AO_PCLK2
+#else
+#define AO_TIM91011_CLK (2 * AO_PCLK2)
+#endif
+
+#define AO_STM_NVIC_HIGH_PRIORITY 4
+#define AO_STM_NVIC_CLOCK_PRIORITY 6
+#define AO_STM_NVIC_MED_PRIORITY 8
+#define AO_STM_NVIC_LOW_PRIORITY 10
+
+void
+ao_adc_init(void);
+
+
+
+void
+ao_serial_init(void);
+
+#endif /* _AO_ARCH_H_ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef _AO_ARCH_FUNCS_H_
+#define _AO_ARCH_FUNCS_H_
+
+#define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<<bit),bus,speed)
+#define ao_spi_put_bit(reg,bit,pin,bus) ao_spi_put_mask(reg,(1<<bit),bus)
+
+#define ao_enable_port(port) (lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO))
+
+#define lpc_all_bit(port,bit) (((port) << 5) | (bit))
+
+#define ao_gpio_set(port, bit, pin, v) (lpc_gpio.byte[lpc_all_bit(port,bit)] = v)
+
+#define ao_gpio_get(port, bit, pin) (lpc_gpio_byte[lpc_all_bit(port,bit)])
+
+#define ao_enable_output(port,bit,pin,v) do { \
+ ao_enable_port(port); \
+ ao_gpio_set(port, bit, pin, v); \
+ lpc_gpio.dir[port] |= (1 << bit); \
+ } while (0)
+
+#define ao_enable_input(port,bit,mode) do { \
+ ao_enable_port(port); \
+ lpc_gpio.dir[port] &= ~(1 << bit); \
+ if (mode == AO_EXTI_MODE_PULL_UP) \
+ stm_pupdr_set(port, bit, STM_PUPDR_PULL_UP); \
+ else if (mode == AO_EXTI_MODE_PULL_DOWN) \
+ stm_pupdr_set(port, bit, STM_PUPDR_PULL_DOWN); \
+ else \
+ stm_pupdr_set(port, bit, STM_PUPDR_NONE); \
+ } while (0)
+
+#define ARM_PUSH32(stack, val) (*(--(stack)) = (val))
+
+static inline uint32_t
+ao_arch_irqsave(void) {
+ uint32_t primask;
+ asm("mrs %0,primask" : "=&r" (primask));
+ ao_arch_block_interrupts();
+ return primask;
+}
+
+static inline void
+ao_arch_irqrestore(uint32_t primask) {
+ asm("msr primask,%0" : : "r" (primask));
+}
+
+static inline void
+ao_arch_memory_barrier() {
+ asm volatile("" ::: "memory");
+}
+
+static inline void
+ao_arch_init_stack(struct ao_task *task, void *start)
+{
+ uint32_t *sp = (uint32_t *) (task->stack + AO_STACK_SIZE);
+ uint32_t a = (uint32_t) start;
+ int i;
+
+ /* Return address (goes into LR) */
+ ARM_PUSH32(sp, a);
+
+ /* Clear register values r0-r7 */
+ i = 8;
+ while (i--)
+ ARM_PUSH32(sp, 0);
+
+ /* APSR */
+ ARM_PUSH32(sp, 0);
+
+ /* PRIMASK with interrupts enabled */
+ ARM_PUSH32(sp, 0);
+
+ task->sp = sp;
+}
+
+static inline void ao_arch_save_regs(void) {
+ /* Save general registers */
+ asm("push {r0-r7,lr}\n");
+
+ /* Save APSR */
+ asm("mrs r0,apsr");
+ asm("push {r0}");
+
+ /* Save PRIMASK */
+ asm("mrs r0,primask");
+ asm("push {r0}");
+}
+
+static inline void ao_arch_save_stack(void) {
+ uint32_t *sp;
+ asm("mov %0,sp" : "=&r" (sp) );
+ ao_cur_task->sp = (sp);
+ if ((uint8_t *) sp < &ao_cur_task->stack[0])
+ ao_panic (AO_PANIC_STACK);
+}
+
+static inline void ao_arch_restore_stack(void) {
+ uint32_t sp;
+ sp = (uint32_t) ao_cur_task->sp;
+
+ /* Switch stacks */
+ asm("mov sp, %0" : : "r" (sp) );
+
+ /* Restore PRIMASK */
+ asm("pop {r0}");
+ asm("msr primask,r0");
+
+ /* Restore APSR */
+ asm("pop {r0}");
+ asm("msr apsr,r0");
+
+ /* Restore general registers and return */
+ asm("pop {r0-r7,pc}\n");
+}
+
+#define ao_arch_isr_stack()
+
+#define ao_arch_wait_interrupt() do { \
+ asm(".global ao_idle_loc\n\twfi\nao_idle_loc:"); \
+ ao_arch_release_interrupts(); \
+ ao_arch_block_interrupts(); \
+ } while (0)
+
+#define ao_arch_critical(b) do { \
+ ao_arch_block_interrupts(); \
+ do { b } while (0); \
+ ao_arch_release_interrupts(); \
+ } while (0)
+
+#endif /* _AO_ARCH_FUNCS_H_ */
--- /dev/null
+/*
+ * 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),
+};
--- /dev/null
+/*
+ * 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>
+
+__pdata uint16_t ao_led_enable;
+
+void
+ao_led_on(uint16_t colors)
+{
+ lpc_gpio.pin[LED_PORT] = 0xffffffff;
+}
+
+void
+ao_led_off(uint16_t colors)
+{
+ lpc_gpio.pin[LED_PORT] = 0;
+}
+
+void
+ao_led_set(uint16_t colors)
+{
+ uint16_t on = colors & ao_led_enable;
+ uint16_t off = ~colors & ao_led_enable;
+
+ ao_led_off(off);
+ ao_led_on(on);
+}
+
+void
+ao_led_toggle(uint16_t colors)
+{
+}
+
+void
+ao_led_for(uint16_t colors, uint16_t ticks) __reentrant
+{
+ ao_led_on(colors);
+ ao_delay(ticks);
+ ao_led_off(colors);
+}
+
+void
+ao_led_init(uint16_t enable)
+{
+ int bit;
+
+ ao_led_enable = enable;
+ lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO);
+ lpc_gpio.dir[LED_PORT] |= enable;
+}
--- /dev/null
+/*
+ * Copyright © 2011 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"
+
+AO_ROMCONFIG_SYMBOL (0) uint16_t ao_romconfig_version = AO_ROMCONFIG_VERSION;
+AO_ROMCONFIG_SYMBOL (0) uint16_t ao_romconfig_check = ~AO_ROMCONFIG_VERSION;
+AO_ROMCONFIG_SYMBOL (0) uint16_t ao_serial_number = 0;
+#ifdef AO_RADIO_CAL_DEFAULT
+AO_ROMCONFIG_SYMBOL (0) uint32_t ao_radio_cal = AO_RADIO_CAL_DEFAULT;
+#endif
--- /dev/null
+/*
+ * 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 <ao_serial.h>
+
+struct ao_fifo ao_usart_rx_fifo;
+struct ao_fifo ao_usart_tx_fifo;
+uint8_t ao_usart_tx_started;
+
+void
+ao_debug_out(char c)
+{
+ if (c == '\n')
+ ao_debug_out('\r');
+#if 0
+ while (!(stm_usart1.sr & (1 << STM_USART_SR_TXE)));
+ stm_usart1.dr = c;
+#endif
+}
+
+static void
+_ao_serial_tx_start(void)
+{
+ if (!ao_fifo_empty(ao_usart_tx_fifo) & !ao_usart_tx_started)
+ {
+ ao_usart_tx_started = 1;
+#if 0
+ ao_fifo_remove(ao_usart_tx_fifo, usart->reg->dr);
+#endif
+ }
+}
+
+void
+lpc_usart_isr(void)
+{
+#if 0
+ uint32_t sr;
+
+ sr = usart->reg->sr;
+ usart->reg->sr = 0;
+
+ if (sr & (1 << STM_USART_SR_RXNE)) {
+ char c = usart->reg->dr;
+ if (!ao_fifo_full(ao_usart_rx_fifo))
+ ao_fifo_insert(ao_usart_rx_fifo, c);
+ ao_wakeup(ao_usart_rx_fifo);
+ if (stdin)
+ ao_wakeup(&ao_stdin_ready);
+ }
+ if (sr & (1 << STM_USART_SR_TC)) {
+ ao_usart_tx_started = 0;
+ _ao_usart_tx_start(usart);
+ ao_wakeup(ao_usart_tx_fifo);
+ }
+#endif
+}
+
+int
+_ao_serial_pollchar(void)
+{
+ int c;
+
+ if (ao_fifo_empty(ao_usart_rx_fifo))
+ c = AO_READ_AGAIN;
+ else {
+ uint8_t u;
+ ao_fifo_remove(ao_usart_rx_fifo,u);
+ c = u;
+ }
+ return c;
+}
+
+char
+ao_serial_getchar(void)
+{
+ int c;
+ ao_arch_block_interrupts();
+ while ((c = _ao_serial_pollchar()) == AO_READ_AGAIN)
+ ao_sleep(&ao_usart_rx_fifo);
+ ao_arch_release_interrupts();
+ return (char) c;
+}
+
+void
+ao_serial_putchar(char c)
+{
+ ao_arch_block_interrupts();
+ while (ao_fifo_full(ao_usart_tx_fifo))
+ ao_sleep(&ao_usart_tx_fifo);
+ ao_fifo_insert(ao_usart_tx_fifo, c);
+ _ao_serial_tx_start();
+ ao_arch_release_interrupts();
+}
+
+void
+ao_serial_drain(void)
+{
+ ao_arch_block_interrupts();
+ while (!ao_fifo_empty(ao_usart_tx_fifo))
+ ao_sleep(&ao_usart_tx_fifo);
+ ao_arch_release_interrupts();
+}
+
+void
+ao_serial_set_speed(uint8_t speed)
+{
+ if (speed > AO_SERIAL_SPEED_115200)
+ return;
+#if 0
+ usart->reg->brr = ao_usart_speeds[speed].brr;
+#endif
+}
+
+#include "ao_serial_lpc.h"
+
+void
+ao_serial_init(void)
+{
+ /* Turn on the USART clock */
+ lpc_scb.uartclkdiv = 1;
+
+#if SERIAL_0_18_19
+ lpc_ioconf.pio0_18 = ((LPC_IOCONF_FUNC_PIO0_18_RXD << LPC_IOCONF_FUNC) |
+ (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) |
+ (0 << LPC_IOCONF_HYS) |
+ (0 << LPC_IOCONF_INV) |
+ (0 << LPC_IOCONF_OD));
+ lpc_ioconf.pio0_19 = ((LPC_IOCONF_FUNC_PIO0_19_TXD << LPC_IOCONF_FUNC) |
+ (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) |
+ (0 << LPC_IOCONF_HYS) |
+ (0 << LPC_IOCONF_INV) |
+ (0 << LPC_IOCONF_OD));
+#endif
+
+ /* Turn on the USART */
+ lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_USART);
+}
+
+
--- /dev/null
+/*
+ * 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>
+
+volatile __data AO_TICK_TYPE ao_tick_count;
+
+uint16_t
+ao_time(void)
+{
+ return ao_tick_count;
+}
+
+#if AO_DATA_ALL
+volatile __data uint8_t ao_data_interval = 1;
+volatile __data uint8_t ao_data_count;
+#endif
+
+void lpc_systick_isr(void)
+{
+ if (lpc_systick.csr & (1 << LPC_SYSTICK_CSR_COUNTFLAG)) {
+ ++ao_tick_count;
+#if HAS_TASK_QUEUE
+ if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0)
+ ao_task_check_alarm((uint16_t) ao_tick_count);
+#endif
+#if AO_DATA_ALL
+ if (++ao_data_count == ao_data_interval) {
+ ao_data_count = 0;
+ ao_adc_poll();
+#if (AO_DATA_ALL & ~(AO_DATA_ADC))
+ ao_wakeup((void *) &ao_data_count);
+#endif
+ }
+#endif
+ }
+}
+
+#if HAS_ADC
+void
+ao_timer_set_adc_interval(uint8_t interval)
+{
+ ao_arch_critical(
+ ao_data_interval = interval;
+ ao_data_count = 0;
+ );
+}
+#endif
+
+#define SYSTICK_RELOAD ((AO_LPC_CLKOUT / 2) / 100 - 1)
+
+/* Initialize our 100Hz clock */
+void
+ao_timer_init(void)
+{
+ lpc_systick.rvr = SYSTICK_RELOAD;
+ lpc_systick.cvr = 0;
+ lpc_systick.csr = ((1 << LPC_SYSTICK_CSR_ENABLE) |
+ (1 << LPC_SYSTICK_CSR_TICKINT) |
+ (LPC_SYSTICK_CSR_CLKSOURCE_CPU_OVER_2 << LPC_SYSTICK_CSR_CLKSOURCE));
+}
+
+#define AO_LPC_M ((AO_LPC_CLKOUT / AO_LPC_CLKIN) - 1)
+
+#define AO_LPC_FCCO_MIN 156000000
+
+void
+ao_clock_init(void)
+{
+ uint8_t p;
+ uint32_t i;
+
+ /* Turn off all perhipherals except for GPIO configuration */
+ lpc_scb.sysahbclkctrl = ((1 << LPC_SCB_SYSAHBCLKCTRL_SYS) |
+ (1 << LPC_SCB_SYSAHBCLKCTRL_ROM) |
+ (1 << LPC_SCB_SYSAHBCLKCTRL_RAM0) |
+ (1 << LPC_SCB_SYSAHBCLKCTRL_FLASHARRAY) |
+ (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO) |
+ (1 << LPC_SCB_SYSAHBCLKCTRL_IOCON));
+
+ /* Turn the IRC clock back on */
+ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_IRC_PD);
+
+ /* Switch to the IRC clock */
+ lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL;
+ lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA);
+ lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA);
+
+ /* Find a PLL post divider ratio that gets the FCCO in range */
+ for (p = 0; p < 4; p++)
+ if (AO_LPC_CLKOUT << (1 + p) >= AO_LPC_FCCO_MIN)
+ break;
+
+ if (p == 4)
+ ao_panic(AO_PANIC_CRASH);
+
+ /* Power down the PLL before touching the registers */
+ lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_SYSPLL_PD);
+
+ /* Set PLL divider values */
+ lpc_scb.syspllctrl = ((AO_LPC_M << LPC_SCB_SYSPLLCTRL_MSEL) |
+ (p << LPC_SCB_SYSPLLCTRL_PSEL));
+
+
+ /* Turn off the external crystal clock */
+ lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_SYSOSC_PD);
+
+ /* Configure the crystal clock */
+ lpc_scb.sysoscctrl = ((0 << LPC_SCB_SYSOSCCTRL_BYPASS) | /* using a crystal */
+ ((AO_LPC_CLKIN > 15000000) << LPC_SCB_SYSOSCCTRL_FREQRANGE));/* set range */
+
+ /* Turn on the external crystal clock */
+ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_SYSOSC_PD);
+
+ /* Select crystal as PLL input */
+
+ lpc_scb.syspllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL);
+ lpc_scb.syspllclkuen = 0;
+ lpc_scb.syspllclkuen = (1 << LPC_SCB_SYSPLLCLKUEN_ENA);
+
+ /* Turn on the PLL */
+ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_SYSPLL_PD);
+
+ /* Wait for it to lock */
+
+ for (i = 0; i < 20000; i++)
+ if (lpc_scb.syspllstat & (1 << LPC_SCB_SYSPLLSTAT_LOCK))
+ break;
+ if (i == 20000)
+ ao_panic(AO_PANIC_CRASH);
+
+ /* Switch to the PLL */
+ lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_PLL_OUTPUT << LPC_SCB_MAINCLKSEL_SEL;
+ lpc_scb.mainclkuen = 0 << LPC_SCB_MAINCLKUEN_ENA;
+ lpc_scb.mainclkuen = 1 << LPC_SCB_MAINCLKUEN_ENA;
+
+ /* Set system clock divider */
+ lpc_scb.sysahbclkdiv = AO_LPC_CLKOUT / AO_LPC_SYSCLK;
+
+ /* Set USB clock source */
+ lpc_scb.usbclksel = (LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK << LPC_SCB_USBCLKSEL_SEL);
+ lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA);
+ lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA);
+
+ /* Shut down perhipheral clocks (enabled as needed) */
+ lpc_scb.ssp0clkdiv = 0;
+ lpc_scb.uartclkdiv = 0;
+ lpc_scb.ssp1clkdiv = 0;
+ lpc_scb.usbclkdiv = 0;
+ lpc_scb.clkoutdiv = 0;
+}
--- /dev/null
+#!/usr/bin/env nickle
+
+/*
+ * Given a main clock frequency,
+ * compute USART clock freq and a table
+ * of USART config parameters for our target baud rates
+ */
+
+real main_clock = 0;
+real usart_clock = 0;
+
+real[] baud_rates = { 4800, 9600, 19200, 57600, 115200 };
+
+void
+compute_baud_rate(real rate) {
+ int divaddval;
+ int mulval;
+
+ real dl_est = usart_clock / (16 * rate);
+
+ if (dl_est == floor(dl_est)) {
+ divaddval = 0;
+ mulval = 1;
+ } else {
+ if (false) {
+
+ /* This is how the docs suggest doing it; this
+ * generates a rate which is reasonably close
+ */
+
+ real fr_est = 1.5;
+
+ /* Compute fractional estimate */
+ do {
+ dl_est = floor(usart_clock / (16 * rate * fr_est) + 0.5);
+ fr_est = usart_clock / (16 * rate * dl_est);
+ } while (fr_est <= 1.1 || 1.9 <= fr_est);
+
+ /* Given fractional estimate, compute divaddval/mulvals that work best */
+
+ real best_dist = 1000;
+ for (int tmp_divaddval = 1; tmp_divaddval < 15; tmp_divaddval++) {
+ for (int tmp_mulval = 1; tmp_mulval < 16; tmp_mulval++) {
+ real fr = 1 + tmp_divaddval / tmp_mulval;
+ real dist = abs(fr - fr_est);
+ if (dist < best_dist) {
+ divaddval = tmp_divaddval;
+ mulval = tmp_mulval;
+ best_dist = dist;
+ }
+ }
+ }
+ } else {
+
+ /* This exhaustively searches for the best match */
+
+ real my_best_dist = 1e20;
+ int my_best_dl;
+ int my_best_divaddval;
+ int my_best_mulval;
+ for (int my_dl = 1; my_dl < 1024; my_dl++) {
+ for (int my_mulval = 1; my_mulval < 16; my_mulval++) {
+ for (int my_divaddval = 0; my_divaddval < my_mulval; my_divaddval++) {
+ real my_rate = usart_clock / ((16 * my_dl) * (1 + my_divaddval/my_mulval));
+
+ real my_dist = abs(rate - my_rate);
+
+ if (my_dist == 0 && my_divaddval == 0) {
+ my_dist = -1;
+ }
+
+ if (my_dist < my_best_dist) {
+ my_best_dl = my_dl;
+ my_best_divaddval = my_divaddval;
+ my_best_mulval = my_mulval;
+ my_best_dist = my_dist;
+ }
+ }
+ }
+ }
+
+ dl_est = my_best_dl;
+ divaddval = my_best_divaddval;
+ mulval = my_best_mulval;
+ }
+ }
+
+ int dl = floor (dl_est);
+
+ real actual = usart_clock / ((16 * dl) * (1 + divaddval/mulval));
+
+ printf("\t[AO_SERIAL_SPEED_%d] = { /* actual = %8.2f */\n", floor(rate), actual);
+ printf("\t\t.dl = %d,\n", dl);
+ printf("\t\t.divaddval = %d,\n", divaddval);
+ printf("\t\t.mulval = %d\n", mulval);
+ printf("\t},\n");
+}
+
+void
+main() {
+ if (dim(argv) < 2) {
+ printf ("usage: %s <main-clock>\n", argv[0]);
+ exit(1);
+ }
+ main_clock = string_to_real(argv[1]);
+
+ for (int div = 0; div < 4; div++) {
+ if (main_clock / (1 << div) <= 12000000) {
+ usart_clock = main_clock / (1 << div);
+ break;
+ }
+ }
+
+ if (usart_clock == 0) {
+ printf ("can't get usart clock in range\n");
+ exit(1);
+ }
+
+ printf ("#define AO_LPC_USARTCLK %d\n\n", floor(usart_clock));
+ printf("static const struct {\n");
+ printf("\tuint16_t dl;\n");
+ printf("\tuint8_t divaddval;\n");
+ printf("\tuint8_t mulval;\n");
+ printf("} ao_usart_speeds[] = {\n");
+ for (int i = 0; i < dim(baud_rates); i++) {
+ compute_baud_rate(baud_rates[i]);
+ }
+ printf ("};\n");
+}
+
+main();
--- /dev/null
+#!/usr/bin/env nickle
+
+autoimport Process;
+
+int byteflip(int x) {
+ return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | ((x << 24) & 0xff000000);
+}
+
+void main () {
+ file input = popen(popen_direction.read, true, "objdump",
+ "objdump", "-j", ".text",
+ "--start-address=0",
+ "--stop-address=0x20",
+ "-s", argv[1]);
+ int sum = 0;
+
+ void add_in(int addr, int value) {
+ if (addr < 0x1c) {
+ sum += value;
+ } else if (addr == 0x1c) {
+ printf ("-DCKSUM=0x%08x\n", -sum & 0xffffffff);
+ exit(0);
+ }
+ }
+ while (!File::end(input)) {
+ string line = File::fgets(input);
+ string[] words = String::wordsplit(line, " ");
+
+ if (dim(words) < 5)
+ continue;
+ if (words[0] == "0000" || words[0] == "0010") {
+ int addr = string_to_integer(words[0], 16);
+ for (int i = 0; i < 4; i++)
+ add_in(addr + i * 4, byteflip(string_to_integer(words[i+1], 16)));
+ }
+ }
+}
+
+main();
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef _LPC_H_
+#define _LPC_H_
+
+#include <stdint.h>
+
+typedef volatile uint32_t vuint32_t;
+typedef volatile uint16_t vuint16_t;
+typedef volatile uint8_t vuint8_t;
+typedef volatile void * vvoid_t;
+
+struct lpc_ioconf {
+ vuint32_t pio0_0;
+ vuint32_t pio0_1;
+ vuint32_t pio0_2;
+ vuint32_t pio0_3;
+
+ vuint32_t pio0_4;
+ vuint32_t pio0_5;
+ vuint32_t pio0_6;
+ vuint32_t pio0_7;
+
+ vuint32_t pio0_8;
+ vuint32_t pio0_9;
+ vuint32_t pio0_10;
+ vuint32_t pio0_11;
+
+ vuint32_t pio0_12;
+ vuint32_t pio0_13;
+ vuint32_t pio0_14;
+ vuint32_t pio0_15;
+
+ vuint32_t pio0_16;
+ vuint32_t pio0_17;
+ vuint32_t pio0_18;
+ vuint32_t pio0_19;
+
+ vuint32_t pio0_20;
+ vuint32_t pio0_21;
+ vuint32_t pio0_22;
+ vuint32_t pio0_23;
+
+ vuint32_t pio1_0; /* 0x60 */
+ vuint32_t pio1_1;
+ vuint32_t pio1_2;
+ vuint32_t pio1_3;
+
+ vuint32_t pio1_4;
+ vuint32_t pio1_5;
+ vuint32_t pio1_6;
+ vuint32_t pio1_7;
+
+ vuint32_t pio1_8; /* 0x80 */
+ vuint32_t pio1_9;
+ vuint32_t pio1_10;
+ vuint32_t pio1_11;
+
+ vuint32_t pio1_12;
+ vuint32_t pio1_13;
+ vuint32_t pio1_14;
+ vuint32_t pio1_15;
+
+ vuint32_t pio1_16; /* 0xa0 */
+ vuint32_t pio1_17;
+ vuint32_t pio1_18;
+ vuint32_t pio1_19;
+
+ vuint32_t pio1_20;
+ vuint32_t pio1_21;
+ vuint32_t pio1_22;
+ vuint32_t pio1_23;
+
+ vuint32_t pio1_24; /* 0xc0 */
+ vuint32_t pio1_25;
+ vuint32_t pio1_26;
+ vuint32_t pio1_27;
+
+ vuint32_t pio1_28;
+ vuint32_t pio1_29;
+ vuint32_t pio1_30;
+ vuint32_t pio1_31;
+};
+
+extern struct lpc_ioconf lpc_ioconf;
+
+#define LPC_IOCONF_FUNC 0
+
+/* PIO0_0 */
+#define LPC_IOCONF_FUNC_RESET 0
+#define LPC_IOCONF_FUNC_PIO0_0 1
+
+/* PIO0_1 */
+#define LPC_IOCONF_FUNC_PIO0_1 0
+#define LPC_IOCONF_FUNC_CLKOUT 1
+#define LPC_IOCONF_FUNC_CT32B0_MAT2 2
+#define LPC_IOCONF_FUNC_USB_FTOGGLE 3
+
+/* PIO0_2 */
+#define LPC_IOCONF_FUNC_PIO0_2 0
+#define LPC_IOCONF_FUNC_SSEL0 1
+#define LPC_IOCONF_FUNC_CT16B0_CAP0 2
+
+/* PIO0_3
+#define LPC_IOCONF_FUNC_PIO0_3 0
+#define LPC_IOCONF_FUNC_USB_VBUS 1
+
+/* PIO0_4
+#define LPC_IOCONF_FUNC_PIO0_4 0
+#define LPC_IOCONF_FUNC_I2C_SCL 1
+
+/* PIO0_5 */
+#define LPC_IOCONF_FUNC_PIO0_5 0
+#define LPC_IOCONF_FUNC_I2C_SDA 1
+
+/* PIO0_6 */
+#define LPC_IOCONF_FUNC_PIO0_6 0
+#define LPC_IOCONF_FUNC_USB_CONNECT 1
+#define LPC_IOCONF_FUNC_SCK0 2
+
+/* PIO0_7 */
+#define LPC_IOCONF_FUNC_PIO0_7 0
+#define LPC_IOCONF_FUNC_CTS 1
+
+/* PIO0_8
+#define LPC_IOCONF_FUNC_PIO0_8 0
+#define LPC_IOCONF_FUNC_MISO0 1
+#define LPC_IOCONF_FUNC_CT16B0_MAT0 2
+
+/* PIO0_9 */
+#define LPC_IOCONF_FUNC_PIO0_9 0
+#define LPC_IOCONF_FUNC_MOSI0 1
+#define LPC_IOCONF_FUNC_CT16B0_MAT1 2
+
+/* PIO0_10 */
+#define LPC_IOCONF_FUNC_SWCLK 0
+#define LPC_IOCONF_FUNC_PIO0_10 1
+#define LPC_IOCONF_FUNC_SCK0 2
+#define LPC_IOCONF_FUNC_CT16B0_MAT2 3
+
+/* PIO0_11 */
+#define LPC_IOCONF_FUNC_TDI 0
+#define LPC_IOCONF_FUNC_PIO0_11 1
+#define LPC_IOCONF_FUNC_AD0 2
+#define LPC_IOCONF_FUNC_CT32B0_MAT3 3
+
+/* PIO0_12 */
+#define LPC_IOCONF_FUNC_TMS 0
+#define LPC_IOCONF_FUNC_PIO0_12 1
+#define LPC_IOCONF_FUNC_AD1 2
+#define LPC_IOCONF_FUNC_CT32B1_CAP0 3
+
+/* PIO0_13 */
+#define LPC_IOCONF_FUNC_TD0 0
+#define LPC_IOCONF_FUNC_PIO0_13 1
+#define LPC_IOCONF_FUNC_AD2 2
+#define LPC_IOCONF_FUNC_CT32B1_MAT0 3
+
+/* PIO0_14 */
+#define LPC_IOCONF_FUNC_TRST 0
+#define LPC_IOCONF_FUNC_PIO0_14 1
+#define LPC_IOCONF_FUNC_AD3 2
+#define LPC_IOCONF_FUNC_PIO0_14_CT32B1_MAT1 3
+
+/* PIO0_15 */
+#define LPC_IOCONF_FUNC_SWDIO 0
+#define LPC_IOCONF_FUNC_PIO0_15 1
+#define LPC_IOCONF_FUNC_AD4 2
+#define LPC_IOCONF_FUNC_CT32B1_MAT2 3
+
+/* PIO0_16 */
+#define LPC_IOCONF_FUNC_PIO0_16 0
+#define LPC_IOCONF_FUNC_AD5 1
+#define LPC_IOCONF_FUNC_CT32B1_MAT3 2
+
+/* PIO0_17 */
+#define LPC_IOCONF_FUNC_PIO0_17 0
+#define LPC_IOCONF_FUNC_RTS 1
+#define LPC_IOCONF_FUNC_CT32B0_CAP0 2
+#define LPC_IOCONF_FUNC_SCLK 3
+
+/* PIO0_18 */
+#define LPC_IOCONF_FUNC_PIO0_18 0
+#define LPC_IOCONF_FUNC_PIO0_18_RXD 1
+#define LPC_IOCONF_FUNC_PIO0_18_CT32B0_MAT0 2
+
+/* PIO0_19 */
+#define LPC_IOCONF_FUNC_PIO0_19 0
+#define LPC_IOCONF_FUNC_PIO0_19_TXD 1
+#define LPC_IOCONF_FUNC_PIO0_19_CT32B0_MAT1 2
+
+/* PIO0_20 */
+#define LPC_IOCONF_FUNC_PIO0_20 0
+#define LPC_IOCONF_FUNC_CT16B1_CAP0 1
+
+/* PIO0_21 */
+#define LPC_IOCONF_FUNC_PIO0_21 0
+#define LPC_IOCONF_FUNC_CT16B1_MAT0 1
+#define LPC_IOCONF_FUNC_MOSI1 2
+
+/* PIO0_22 */
+#define LPC_IOCONF_FUNC_PIO0_22 0
+#define LPC_IOCONF_FUNC_AD6 1
+#define LPC_IOCONF_FUNC_CT16B1_MAT1 2
+#define LPC_IOCONF_FUNC_MISO1 3
+
+/* PIO0_23 */
+#define LPC_IOCONF_FUNC_PIO0_23 0
+#define LPC_IOCONF_FUNC_AD7 1
+
+/* PIO1_0 */
+#define LPC_IOCONF_FUNC_PIO1_0 0
+#define LPC_IOCONF_FUNC_CT32B1_MAT1 1
+
+/* PIO1_1 */
+#define LPC_IOCONF_FUNC_PIO1_1 0
+#define LPC_IOCONF_FUNC_CT32B1_MAT1 1
+
+/* PIO1_2 */
+#define LPC_IOCONF_FUNC_PIO1_2 0
+#define LPC_IOCONF_FUNC_PIO1_2_CT32B1_MAT2 1
+
+/* PIO1_3*/
+#define LPC_IOCONF_FUNC_PIO1_3 0
+#define LPC_IOCONF_FUNC_PIO1_3_CT32B1_MAT3 1
+
+/* PIO1_4 */
+#define LPC_IOCONF_FUNC_PIO1_4 0
+#define LPC_IOCONF_FUNC_PIO1_4_CT32B1_CAP0 1
+
+/* PIO1_5 */
+#define LPC_IOCONF_FUNC_PIO1_5 0
+#define LPC_IOCONF_FUNC_CT32B1_CAP1 1
+
+/* PIO1_6 */
+#define LPC_IOCONF_FUNC_PIO1_6 0
+
+/* PIO1_7 */
+#define LPC_IOCONF_FUNC_PIO1_7 0
+
+/* PIO1_8 */
+#define LPC_IOCONF_FUNC_PIO1_8 0
+
+/* PIO1_9 */
+#define LPC_IOCONF_FUNC_PIO1_9 0
+
+/* PIO1_10 */
+#define LPC_IOCONF_FUNC_PIO1_10 0
+
+/* PIO1_11 */
+#define LPC_IOCONF_FUNC_PIO1_11 0
+
+/* PIO1_12 */
+#define LPC_IOCONF_FUNC_PIO1_12 0
+
+/* PIO1_13 */
+#define LPC_IOCONF_FUNC_PIO1_13 0
+#define LPC_IOCONF_FUNC_DTR 1
+#define LPC_IOCONF_FUNC_CT16B0_MAT0 2
+#define LPC_IOCONF_FUNC_PIO1_13_TXD 3
+
+/* PIO1_14 */
+#define LPC_IOCONF_FUNC_PIO1_14 0
+#define LPC_IOCONF_FUNC_DSR 1
+#define LPC_IOCONF_FUNC_CT16B0_MAT1 2
+#define LPC_IOCONF_FUNC_PIO1_13_RXD 3
+
+/* PIO1_15 */
+#define LPC_IOCONF_FUNC_PIO1_15 0
+#define LPC_IOCONF_FUNC_DCD 1
+#define LPC_IOCONF_FUNC_PIO1_15_CT16B0_MAT2 2
+#define LPC_IOCONF_FUNC_SCK1 3
+
+/* PIO1_16 */
+#define LPC_IOCONF_FUNC_PIO1_16 0
+#define LPC_IOCONF_FUNC_RI 1
+#define LPC_IOCONF_FUNC_CT16B0_CAP0 2
+
+/* PIO1_17 */
+#define LPC_IOCONF_FUNC_PIO1_17 0
+#define LPC_IOCONF_FUNC_CT16B0_CAP1 1
+#define LPC_IOCONF_FUNC_PIO1_17_RXD 2
+
+/* PIO1_18 */
+#define LPC_IOCONF_FUNC_PIO1_18 0
+#define LPC_IOCONF_FUNC_CT16B1_CAP1 1
+#define LPC_IOCONF_FUNC_PIO1_18_TXD 2
+
+/* PIO1_19 */
+#define LPC_IOCONF_FUNC_PIO1_19 0
+#define LPC_IOCONF_FUNC_DTR 1
+#define LPC_IOCONF_FUNC_SSEL1 2
+
+/* PIO1_20 */
+#define LPC_IOCONF_FUNC_PIO1_20 0
+#define LPC_IOCONF_FUNC_DSR 1
+#define LPC_IOCONF_FUNC_PIO1_20_SCK1 2
+
+/* PIO1_21 */
+#define LPC_IOCONF_FUNC_PIO1_21 0
+#define LPC_IOCONF_FUNC_DCD 1
+#define LPC_IOCONF_FUNC_PIO1_21_MISO1 2
+
+/* PIO1_22 */
+#define LPC_IOCONF_FUNC_PIO1_22 0
+#define LPC_IOCONF_FUNC_RI 1
+#define LPC_IOCONF_FUNC_MOSI1 2
+
+/* PIO1_23 */
+#define LPC_IOCONF_FUNC_PIO1_23 0
+#define LPC_IOCONF_FUNC_PIO1_23_CT16B1_MAT1 1
+#define LPC_IOCONF_FUNC_SSEL1 2
+
+/* PIO1_24 */
+#define LPC_IOCONF_FUNC_PIO1_24 0
+#define LPC_IOCONF_FUNC_PIO1_24_CT32B0_MAT0 1
+
+/* PIO1_25 */
+#define LPC_IOCONF_FUNC_PIO1_25 0
+#define LPC_IOCONF_FUNC_PIO1_25_CT32B0_MAT1 1
+
+/* PIO1_26 */
+#define LPC_IOCONF_FUNC_PIO1_26 0
+#define LPC_IOCONF_FUNC_PIO1_26_CT32B0_MAT2 1
+#define LPC_IOCONF_FUNC_PIO1_26_RXD 2
+
+/* PIO1_27 */
+#define LPC_IOCONF_FUNC_PIO1_27 0
+#define LPC_IOCONF_FUNC_PIO1_27_CT32B0_MAT3 1
+#define LPC_IOCONF_FUNC_PIO1_27_TXD 2
+
+/* PIO1_28 */
+#define LPC_IOCONF_FUNC_PIO1_28 0
+#define LPC_IOCONF_FUNC_PIO1_28_CT32B0_CAP0 1
+#define LPC_IOCONF_FUNC_PIO1_28_SCLK 2
+
+/* PIO1_29 */
+#define LPC_IOCONF_FUNC_PIO1_29 0
+#define LPC_IOCONF_FUNC_PIO1_29_SCK0 1
+#define LPC_IOCONF_FUNC_PIO1_29_CT32B0_CAP1 2
+
+/* PIO1_31 */
+#define LPC_IOCONF_FUNC_PIO1_31 0
+
+#define LPC_IOCONF_FUNC_MASK 0x7
+
+#define LPC_IOCONF_MODE 3
+#define LPC_IOCONF_MODE_INACTIVE 0
+#define LPC_IOCONF_MODE_PULL_DOWN 1
+#define LPC_IOCONF_MODE_PULL_UP 2
+#define LPC_IOCONF_MODE_REPEATER 3
+#define LPC_IOCONF_MODE_MASK 3
+
+#define LPC_IOCONF_HYS 5
+
+#define LPC_IOCONF_INV 6
+#define LPC_IOCONF_OD 10
+
+struct lpc_scb {
+ vuint32_t sysmemremap; /* 0x00 */
+ vuint32_t presetctrl;
+ vuint32_t syspllctrl;
+ vuint32_t syspllstat;
+
+ vuint32_t usbpllctrl; /* 0x10 */
+ vuint32_t usbpllstat;
+ uint32_t r18;
+ uint32_t r1c;
+
+ vuint32_t sysoscctrl; /* 0x20 */
+ vuint32_t wdtoscctrl;
+ uint32_t r28;
+ uint32_t r2c;
+
+ vuint32_t sysrststat; /* 0x30 */
+ uint32_t r34;
+ uint32_t r38;
+ uint32_t r3c;
+
+ vuint32_t syspllclksel; /* 0x40 */
+ vuint32_t syspllclkuen;
+ vuint32_t usbpllclksel;
+ vuint32_t usbplllclkuen;
+
+ uint32_t r50[8];
+
+ vuint32_t mainclksel; /* 0x70 */
+ vuint32_t mainclkuen;
+ vuint32_t sysahbclkdiv;
+ uint32_t r7c;
+
+ vuint32_t sysahbclkctrl; /* 0x80 */
+ uint32_t r84[3];
+
+ uint32_t r90; /* 0x90 */
+ vuint32_t ssp0clkdiv;
+ vuint32_t uartclkdiv;
+ vuint32_t ssp1clkdiv;
+
+ uint32_t ra0[8];
+
+ vuint32_t usbclksel; /* 0xc0 */
+ vuint32_t usbclkuen;
+ vuint32_t usbclkdiv;
+ uint32_t rcc;
+
+ uint32_t rd0[4];
+
+ vuint32_t clkoutsel; /* 0xe0 */
+ vuint32_t clkoutuen;
+ vuint32_t clkoutdiv;
+ uint32_t rec;
+
+ uint32_t rf0[4]; /* 0xf0 */
+
+ vuint32_t pioporcap0; /* 0x100 */
+ vuint32_t pioporcap1;
+ uint32_t r102[2];
+
+ uint32_t r110[4]; /* 0x110 */
+ uint32_t r120[4]; /* 0x120 */
+ uint32_t r130[4]; /* 0x130 */
+ uint32_t r140[4]; /* 0x140 */
+
+ vuint32_t bodctrl; /* 0x150 */
+ vuint32_t systckcal;
+ uint32_t r158[2];
+
+ uint32_t r160[4]; /* 0x160 */
+
+ vuint32_t irqlatency; /* 0x170 */
+ vuint32_t nmisrc;
+ vuint32_t pintsel0;
+ vuint32_t pintsel1;
+
+ vuint32_t pintsel2; /* 0x180 */
+ vuint32_t pintsel3;
+ vuint32_t pintsel4;
+ vuint32_t pintsel5;
+
+ vuint32_t pintsel6; /* 0x190 */
+ vuint32_t pintsel7;
+ vuint32_t usbclkctrl;
+ vuint32_t usbclkst;
+
+ uint32_t r1a0[6*4]; /* 0x1a0 */
+
+ uint32_t r200; /* 0x200 */
+ vuint32_t starterp0;
+ uint32_t r208[2];
+
+ uint32_t r210; /* 0x210 */
+ vuint32_t starterp1;
+ uint32_t r218[2];
+
+ uint32_t r220[4]; /* 0x220 */
+
+ vuint32_t pdsleepcfg; /* 0x230 */
+ vuint32_t pdawakecfg;
+ vuint32_t pdruncfg;
+ uint32_t r23c;
+
+ uint32_t r240[12 * 4]; /* 0x240 */
+
+ uint32_t r300[15 * 4]; /* 0x300 */
+
+ uint32_t r3f0; /* 0x3f0 */
+ vuint32_t device_id;
+};
+
+extern struct lpc_scb lpc_scb;
+
+#define LPC_SCB_PRESETCTRL_SSP0_RST_N 0
+#define LPC_SCB_PRESETCTRL_I2C_RST_N 1
+#define LPC_SCB_PRESETCTRL_SSP1_RST_N 2
+
+#define LPC_SCB_SYSPLLCTRL_MSEL 0
+#define LPC_SCB_SYSPLLCTRL_PSEL 5
+#define LPC_SCB_SYSPLLCTRL_PSEL_1 0
+#define LPC_SCB_SYSPLLCTRL_PSEL_2 1
+#define LPC_SCB_SYSPLLCTRL_PSEL_4 2
+#define LPC_SCB_SYSPLLCTRL_PSEL_8 3
+#define LPC_SCB_SYSPLLCTRL_PSEL_MASK 3
+
+#define LPC_SCB_SYSPLLSTAT_LOCK 0
+
+#define LPC_SCB_USBPLLCTRL_MSEL 0
+#define LPC_SCB_USBPLLCTRL_PSEL 5
+#define LPC_SCB_USBPLLCTRL_PSEL_1 0
+#define LPC_SCB_USBPLLCTRL_PSEL_2 1
+#define LPC_SCB_USBPLLCTRL_PSEL_4 2
+#define LPC_SCB_USBPLLCTRL_PSEL_8 3
+#define LPC_SCB_USBPLLCTRL_PSEL_MASK 3
+
+#define LPC_SCB_USBPLLSTAT_LOCK 0
+
+#define LPC_SCB_SYSOSCCTRL_BYPASS 0
+#define LPC_SCB_SYSOSCCTRL_FREQRANGE 1
+#define LPC_SCB_SYSOSCCTRL_FREQRANGE_1_20 0
+#define LPC_SCB_SYSOSCCTRL_FREQRANGE_15_25 1
+
+#define LPC_SCB_WDTOSCCTRL_DIVSEL 0
+#define LPC_SCB_WDTOSCCTRL_DIVSEL_MASK 0x1f
+#define LPC_SCB_WDTOSCCTRL_FREQSEL 5
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_0_6 1
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_1_05 2
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_1_4 3
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_1_75 4
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_2_1 5
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_2_4 6
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_2_7 7
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_0 8
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_25 9
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_5 0x0a
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_75 0x0b
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_0 0x0c
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_2 0x0d
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_4 0x0e
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_6 0x0f
+#define LPC_SCB_WDTOSCCTRL_FREQSEL_MASK 0x0f
+
+#define LPC_SCB_SYSRSTSTAT_POR 0
+#define LPC_SCB_SYSRSTSTAT_EXTRST 1
+#define LPC_SCB_SYSRSTSTAT_WDT 2
+#define LPC_SCB_SYSRSTSTAT_BOD 3
+#define LPC_SCB_SYSRSTSTAT_SYSRST 4
+
+#define LPC_SCB_SYSPLLCLKSEL_SEL 0
+#define LPC_SCB_SYSPLLCLKSEL_SEL_IRC 0
+#define LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC 1
+#define LPC_SCB_SYSPLLCLKSEL_SEL_MASK 3
+
+#define LPC_SCB_SYSPLLCLKUEN_ENA 0
+
+#define LPC_SCB_USBPLLCLKSEL_SEL 0
+#define LPC_SCB_USBPLLCLKSEL_SEL_IRC 0
+#define LPC_SCB_USBPLLCLKSEL_SEL_SYSOSC 1
+#define LPC_SCB_USBPLLCLKSEL_SEL_MASK 3
+
+#define LPC_SCB_USBPLLCLKUEN_ENA 0
+
+#define LPC_SCB_MAINCLKSEL_SEL 0
+#define LPC_SCB_MAINCLKSEL_SEL_IRC 0
+#define LPC_SCB_MAINCLKSEL_SEL_PLL_INPUT 1
+#define LPC_SCB_MAINCLKSEL_SEL_WATCHDOG 2
+#define LPC_SCB_MAINCLKSEL_SEL_PLL_OUTPUT 3
+#define LPC_SCB_MAINCLKSEL_SEL_MASK 3
+
+#define LPC_SCB_MAINCLKUEN_ENA 0
+
+#define LPC_SCB_SYSAHBCLKDIV_DIV 0
+
+#define LPC_SCB_SYSAHBCLKCTRL_SYS 0
+#define LPC_SCB_SYSAHBCLKCTRL_ROM 1
+#define LPC_SCB_SYSAHBCLKCTRL_RAM0 2
+#define LPC_SCB_SYSAHBCLKCTRL_FLASHREG 3
+#define LPC_SCB_SYSAHBCLKCTRL_FLASHARRAY 4
+#define LPC_SCB_SYSAHBCLKCTRL_I2C 5
+#define LPC_SCB_SYSAHBCLKCTRL_GPIO 6
+#define LPC_SCB_SYSAHBCLKCTRL_CT16B0 7
+#define LPC_SCB_SYSAHBCLKCTRL_CT16B1 8
+#define LPC_SCB_SYSAHBCLKCTRL_CT32B0 9
+#define LPC_SCB_SYSAHBCLKCTRL_CT32B1 10
+#define LPC_SCB_SYSAHBCLKCTRL_SSP0 11
+#define LPC_SCB_SYSAHBCLKCTRL_USART 12
+#define LPC_SCB_SYSAHBCLKCTRL_ADC 13
+#define LPC_SCB_SYSAHBCLKCTRL_USB 14
+#define LPC_SCB_SYSAHBCLKCTRL_WWDT 15
+#define LPC_SCB_SYSAHBCLKCTRL_IOCON 16
+#define LPC_SCB_SYSAHBCLKCTRL_SSP1 18
+#define LPC_SCB_SYSAHBCLKCTRL_PINT 19
+#define LPC_SCB_SYSAHBCLKCTRL_GROUP0INT 23
+#define LPC_SCB_SYSAHBCLKCTRL_GROUP1INT 24
+#define LPC_SCB_SYSAHBCLKCTRL_RAM1 26
+#define LPC_SCB_SYSAHBCLKCTRL_USBRAM 27
+
+#define LPC_SCB_SSP0CLKDIV_
+#define LPC_SCB_UARTCLKDIV_
+#define LPC_SCB_SSP1CLKDIV_
+
+#define LPC_SCB_USBCLKSEL_SEL 0
+#define LPC_SCB_USBCLKSEL_SEL_USB_PLL 0
+#define LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK 1
+
+#define LPC_SCB_USBCLKUEN_ENA 0
+#define LPC_SCB_USBCLKDIV_DIV 0
+
+#define LPC_SCB_CLKOUTSEL_
+#define LPC_SCB_CLKOUTUEN_
+
+#define LPC_SCB_PDRUNCFG_IRCOUT_PD 0
+#define LPC_SCB_PDRUNCFG_IRC_PD 1
+#define LPC_SCB_PDRUNCFG_FLASH_PD 2
+#define LPC_SCB_PDRUNCFG_BOD_PD 3
+#define LPC_SCB_PDRUNCFG_ADC_PD 4
+#define LPC_SCB_PDRUNCFG_SYSOSC_PD 5
+#define LPC_SCB_PDRUNCFG_WDTOSC_PD 6
+#define LPC_SCB_PDRUNCFG_SYSPLL_PD 7
+#define LPC_SCB_PDRUNCFG_USBPLL_PD 8
+#define LPC_SCB_PDRUNCFG_USBPAD_PD 10
+
+struct lpc_flash {
+ uint32_t r0[4]; /* 0x0 */
+
+ vuint32_t flashcfg; /* 0x10 */
+};
+
+extern struct lpc_flash lpc_flash;
+
+struct lpc_gpio_pin {
+};
+
+extern struct lpc_gpio_pin lpc_gpio_pin;
+
+struct lpc_gpio_group0 {
+};
+
+extern struct lpc_gpio_group0 lpc_gpio_group0;
+
+struct lpc_gpio_group1 {
+};
+
+extern struct lpc_gpio_group1 lpc_gpio_group1;
+
+struct lpc_gpio {
+ vuint8_t byte[0x40]; /* 0x0000 */
+
+ uint8_t r0030[0x1000 - 0x40];
+
+ vuint32_t word[0x40]; /* 0x1000 */
+
+ uint8_t r1100[0x2000 - 0x1100];
+
+ vuint32_t dir[2]; /* 0x2000 */
+
+ uint8_t r2008[0x2080 - 0x2008];
+
+ vuint32_t mask[2]; /* 0x2080 */
+
+ uint8_t r2088[0x2100 - 0x2088];
+
+ vuint32_t pin[2]; /* 0x2100 */
+
+ uint8_t r2108[0x2200 - 0x2108];
+
+ vuint32_t set[2]; /* 0x2200 */
+
+ uint8_t r2208[0x2280 - 0x2208];
+
+ vuint32_t clr[2]; /* 0x2280 */
+
+ uint8_t r2288[0x2300 - 0x2288];
+
+ vuint32_t not[2]; /* 0x2300 */
+};
+
+extern struct lpc_gpio lpc_gpio;
+
+struct lpc_systick {
+ uint8_t r0000[0x10]; /* 0x0000 */
+
+ vuint32_t csr; /* 0x0010 */
+ vuint32_t rvr;
+ vuint32_t cvr;
+ vuint32_t calib;
+};
+
+extern struct lpc_systick lpc_systick;
+
+#define LPC_SYSTICK_CSR_ENABLE 0
+#define LPC_SYSTICK_CSR_TICKINT 1
+#define LPC_SYSTICK_CSR_CLKSOURCE 2
+#define LPC_SYSTICK_CSR_CLKSOURCE_CPU_OVER_2 0
+#define LPC_SYSTICK_CSR_CLKSOURCE_CPU 1
+#define LPC_SYSTICK_CSR_COUNTFLAG 16
+
+struct lpc_usart {
+ vuint32_t rbr_thr; /* 0x0000 */
+ vuint32_t ier;
+ vuint32_t iir_fcr;
+ vuint32_t lcr;
+
+ vuint32_t mcr; /* 0x0010 */
+ vuint32_t lsr;
+ vuint32_t msr;
+ vuint32_t scr;
+
+ vuint32_t acr; /* 0x0020 */
+ vuint32_t icr;
+ vuint32_t fdr;
+ vuint32_t osr;
+
+ vuint32_t ter; /* 0x0030 */
+ uint32_t r34[3];
+
+ vuint32_t hden; /* 0x0040 */
+ uint32_t r44;
+ vuint32_t scictrl;
+ vuint32_t rs485ctrl;
+
+ vuint32_t rs485addrmatch; /* 0x0050 */
+ vuint32_t rs485dly;
+ vuint32_t syncctrl;
+};
+
+extern struct lpc_usart lpc_usart;
+
+#endif /* _LPC_H_ */
--- /dev/null
+lpc_usart = 0x40008000;
+lpc_flash = 0x4003c000;
+lpc_ioconf = 0x40044000;
+lpc_scb = 0x40048000;
+lpc_gpio_pin = 0x4004c000;
+lpc_gpio_group0 = 0x4005c000;
+lpc_gpio_group1 = 0x40060000;
+lpc_gpio = 0x50000000;
+lpc_systick = 0xe000e000;
--- /dev/null
+#
+# AltOS build
+#
+#
+
+include ../lpc/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ lpc.h
+
+#
+# Common AltOS sources
+#
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_romconfig.c \
+ ao_product.c \
+ ao_panic.c \
+ ao_led_lpc.c \
+ ao_task.c \
+ ao_timer_lpc.c \
+ ao_serial_lpc.c \
+ ao_stdio.c
+
+PRODUCT=LpcDemo-v0.0
+PRODUCT_DEF=-DLPC_DEMO
+IDPRODUCT=0x000a
+
+CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os
+
+PROG=lpc-demo.elf
+
+SRC=$(ALTOS_SRC) ao_demo.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG)
+
+LDFLAGS=-L../lpc -Wl,-Taltos.ld
+
+$(PROG): Makefile $(OBJ)
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+$(OBJ): $(INC)
+
+load: $(PROG)
+ lpc-load $(PROG)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROG)
+ rm -f ao_product.h
+
+install:
+
+uninstall:
--- /dev/null
+/*
+ * 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.
+ */
+
+#define HAS_BEEP 0
+#define HAS_LED 1
+
+/* Crystal on the board */
+#define AO_LPC_CLKIN 12000000
+
+/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */
+#define AO_LPC_CLKOUT 48000000
+
+/* System clock frequency */
+#define AO_LPC_SYSCLK 24000000
+
+#define LED_PORT 0
+#define LED_PIN_RED 7
+
+#define AO_LED_RED (1 << LED_PIN_RED)
+
+#define LEDS_AVAILABLE AO_LED_RED
+
+#define HAS_USB 0
+
+#define PACKET_HAS_SLAVE 0
+
+/* USART */
+
+#define HAS_SERIAL 1
+#define SERIAL_0_18_19 1
+#define SERIAL_1_14_15 0
+#define SERIAL_1_17_18 0
+#define SERIAL_1_26_27 0