return true;
if (product.startsWith("EasyMotor-v2"))
return true;
+ if (product.startsWith("EasyMotor-v3"))
+ return true;
}
throw new AltosUnknownProduct(product);
}
return AltosAdxl375.X_AXIS;
if (product.startsWith("EasyMotor-v2"))
return AltosAdxl375.X_AXIS;
+ if (product.startsWith("EasyMotor-v3"))
+ return AltosAdxl375.X_AXIS;
}
throw new AltosUnknownProduct(product);
break;
case AO_LOG_FORMAT_TELEMEGA_4:
len = 32;
- break;
max_adc= 4095;
adc_ref = 3.3;
batt_r1 = 5600;
break;
}
break;
+ case AO_LOG_FORMAT_EASYMOTOR:
+ log_motor = (struct ao_log_motor *) &eeprom->data[pos];
+ switch (log_motor->type) {
+ case AO_LOG_FLIGHT:
+ printf(" serial %5u flight %5u ground_accel %6d",
+ eeprom->serial_number,
+ log_motor->u.flight.flight,
+ log_motor->u.flight.ground_accel);
+ printf(" along %6d aross %6d through %6d",
+ log_motor->u.flight.ground_accel_along,
+ log_motor->u.flight.ground_accel_across,
+ log_motor->u.flight.ground_accel_through);
+ ao_volts("ground pressure",
+ log_motor->u.flight.ground_motor_pressure,
+ max_adc, adc_ref,
+ sense_r1, sense_r2);
+ break;
+ case AO_LOG_STATE:
+ ao_state(log_motor->u.state.state,
+ log_motor->u.state.reason);
+ break;
+ case AO_LOG_SENSOR:
+ ao_volts("pressure",
+ log_motor->u.sensor.pressure,
+ max_adc, adc_ref,
+ sense_r1, sense_r2);
+ ao_volts("v_batt",
+ log_motor->u.sensor.v_batt,
+ max_adc,
+ adc_ref, batt_r1, batt_r2);
+ printf(" accel %6d",
+ log_motor->u.sensor.accel);
+ printf(" along %6d aross %6d through %6d",
+ log_motor->u.sensor.accel_along,
+ log_motor->u.sensor.accel_across,
+ log_motor->u.sensor.accel_through);
+ break;
+ }
+ break;
case AO_LOG_FORMAT_DETHERM:
break;
case AO_LOG_FORMAT_EASYMOTOR:
} u; /* 16 */
}; /* 16 */
+struct ao_log_motor {
+ char type; /* 0 */
+ uint8_t csum; /* 1 */
+ uint16_t tick; /* 2 */
+ union { /* 4 */
+ /* AO_LOG_FLIGHT */
+ struct {
+ uint16_t flight; /* 4 */
+ int16_t ground_accel; /* 6 */
+ int16_t ground_accel_along; /* 8 */
+ int16_t ground_accel_across; /* 10 */
+ int16_t ground_accel_through; /* 12 */
+ int16_t ground_motor_pressure; /* 14 */
+ } flight; /* 16 */
+ /* AO_LOG_STATE */
+ struct {
+ uint16_t state; /* 4 */
+ uint16_t reason; /* 6 */
+ } state;
+ /* AO_LOG_SENSOR */
+ struct {
+ uint16_t pressure; /* 4 */
+ uint16_t v_batt; /* 6 */
+ int16_t accel; /* 8 */
+ int16_t accel_across; /* 10 */
+ int16_t accel_along; /* 12 */
+ int16_t accel_through; /* 14 */
+ } sensor; /* 16 */
+ } u;
+};
+
#define ao_log_pack24(dst,value) do { \
(dst)[0] = (value); \
(dst)[1] = (value) >> 8; \
easymega-v1.0 easymega-v1.0/flash-loader \
easymega-v2.0 easymega-v2.0/flash-loader \
easymotor-v2 easymotor-v2/flash-loader \
+ easymotor-v3 easymotor-v3/flash-loader \
easytimer-v1 easytimer-v1/flash-loader \
telemega-v0.1 telemega-v0.1/flash-loader \
telemega-v1.0 telemega-v1.0/flash-loader \
#define DEBUG 0
#if DEBUG
-#define PRINTD(l, ...) do { if (DEBUG & (l)) { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } } while(0)
+#define PRINTD(l, ...) do { if (DEBUG & (l)) { printf ("\r%5lu %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } } while(0)
#else
#define PRINTD(l,...)
#endif
ao_spi_duplex(d, d, 2, AO_ADXL375_SPI_INDEX);
ao_adxl375_stop();
- PRINTD(DEBUG_LOW, "read %x = %x\n", addr, d);
+ PRINTD(DEBUG_LOW, "read %x = %x\n", addr, d[1]);
return d[1];
}
ao_adxl375_stop();
#if DEBUG & DEBUG_LOW
- d[0] = addr | AO_ADXL375_READ
+ d[0] = addr | AO_ADXL375_READ;
d[1] = 0;
ao_adxl375_start();
ao_spi_duplex(d, d, 2, AO_ADXL375_SPI_INDEX);
#define AO_ADXL375_DATA_FORMAT_SETTINGS(self_test) ( \
AO_ADXL375_DATA_FORMAT_FIXED | \
(self_test << AO_ADXL375_DATA_FORMAT_SELF_TEST) | \
- (AO_ADXL375_DATA_FORMAT_SPI_4_WIRE << AO_ADXL375_DATA_FORMAT_SPI_4_WIRE) | \
+ (AO_ADXL375_DATA_FORMAT_SPI_4_WIRE << AO_ADXL375_DATA_FORMAT_SPI) | \
(0 << AO_ADXL375_DATA_FORMAT_INT_INVERT) | \
(0 << AO_ADXL375_DATA_FORMAT_JUSTIFY))
# define AO_ADXL375_DATA_FORMAT_FIXED 0x0b /* these bits must be set to 1 */
# define AO_ADXL375_DATA_FORMAT_SELF_TEST 7
# define AO_ADXL375_DATA_FORMAT_SPI 6
-# define AO_ADXL375_DATA_FORMAT_SPI_3_WIRE 0
-# define AO_ADXL375_DATA_FORMAT_SPI_4_WIRE 1
+# define AO_ADXL375_DATA_FORMAT_SPI_3_WIRE 1
+# define AO_ADXL375_DATA_FORMAT_SPI_4_WIRE 0
# define AO_ADXL375_DATA_FORMAT_INT_INVERT 5
# define AO_ADXL375_DATA_FORMAT_JUSTIFY 2
#define AO_ADXL375_DATAX0 0x32
/* System clock frequency */
#define AO_LPC_SYSCLK 24000000
+/* Beeper is on pio0_14 ct32b1_mat1 */
+#define BEEPER_PORT 0
+#define BEEPER_PIN 14
+#define BEEPER_TIMER 1
+#define BEEPER_OUTPUT 1
+
#define HAS_USB 1
#define HAS_USB_CONNECT 0
--- /dev/null
+#
+# AltOS build
+#
+#
+
+include ../lpc/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ ao_adxl375.h \
+ lpc.h
+
+#
+# Common AltOS sources
+#
+
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_boot_chain.c \
+ ao_romconfig.c \
+ ao_product.c \
+ ao_mutex.c \
+ ao_panic.c \
+ ao_stdio.c \
+ ao_storage.c \
+ ao_report.c \
+ ao_flight.c \
+ ao_kalman.c \
+ ao_sample.c \
+ ao_data.c \
+ ao_convert_volt.c \
+ ao_task.c \
+ ao_log.c \
+ ao_log_motor.c \
+ ao_cmd.c \
+ ao_config.c \
+ ao_timer_lpc.c \
+ ao_exti_lpc.c \
+ ao_spi_lpc.c \
+ ao_adc_lpc.c \
+ ao_usb_lpc.c \
+ ao_m25.c \
+ ao_adxl375.c \
+ ao_beep_lpc.c
+
+PRODUCT=EasyMotor-v3
+PRODUCT_DEF=-DEASYMOTOR_V_3
+IDPRODUCT=0x002c
+
+CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS)
+
+PROGNAME=easymotor-v3
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_easymotor.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(OBJ): $(INC)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+
+int
+main(void)
+{
+ ao_clock_init();
+ ao_task_init();
+ ao_timer_init();
+
+// ao_dma_init();
+ ao_spi_init();
+ ao_exti_init();
+
+ ao_adc_init();
+ ao_beep_init();
+ ao_cmd_init();
+ ao_usb_init();
+
+ ao_adxl375_init();
+
+ ao_storage_init();
+ ao_flight_init();
+ ao_log_init();
+ ao_report_init();
+ ao_config_init();
+
+ ao_start_scheduler();
+}
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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_PINS_H_
+#define _AO_PINS_H_
+
+#define AO_STACK_SIZE 352
+#define SLEEP_HASH_SIZE 3
+#define AO_NUM_TASKS 6
+
+#define HAS_TASK_QUEUE 1
+#define IS_FLASH_LOADER 0
+
+/* 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 HAS_USB 1
+#define HAS_USB_CONNECT 0
+#define HAS_USB_VBUS 0
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 20
+
+#define PACKET_HAS_SLAVE 0
+
+#define HAS_SERIAL 0
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1984 * 1024)
+#define AO_CONFIG_MAX_SIZE 1024
+#define LOG_ERASE_MARK 0x55
+#define LOG_MAX_ERASE 128
+#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMOTOR
+
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 0
+#define USE_EEPROM_CONFIG 0
+#define USE_STORAGE_CONFIG 1
+#define AO_PA11_PA12_RMP 1
+#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
+#define HAS_PAD_REPORT 1
+
+/* Beeper is on pio0_1 ct32b0_mat2 */
+#define BEEPER_PORT 0
+#define BEEPER_PIN 1
+#define BEEPER_TIMER 0
+#define BEEPER_OUTPUT 2
+
+#define HAS_RADIO 0
+#define HAS_TELEMETRY 0
+#define HAS_APRS 0
+#define HAS_COMPANION 0
+
+#define LOW_LEVEL_DEBUG 0
+
+#define HAS_GPS 0
+#define HAS_FLIGHT 1
+#define HAS_LOG 1
+
+/*
+ * ADC
+ */
+#define HAS_ADC 1
+
+#define AO_NUM_ADC 2
+
+#define AO_ADC_0 1
+#define AO_ADC_1 1
+
+#define AO_DATA_RING 32
+
+struct ao_adc {
+ int16_t v_batt;
+ int16_t motor_pressure;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5lu batt: %5d motor_pressure: %5d\n", \
+ (p)->tick, \
+ (p)->adc.v_batt, \
+ (p)->adc.motor_pressure);
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */
+#define AO_BATTERY_DIV_MINUS 100 /* 10k */
+
+/*
+ * Voltage divider on pressure sensor input
+ */
+#define AO_PRESSURE_DIV_PLUS 56 /* 5.6k 0.1% */
+#define AO_PRESSURE_DIV_MINUS 100 /* 10k 0.1% */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
+/* SPI */
+
+#define HAS_SPI_0 1
+#define SPI_0_MODE ((0 << LPC_SSP_CR0_CPOL) | (0 << LPC_SSP_CR0_CPHA))
+#define SPI_SCK0_P0_6 1
+#define HAS_SPI_1 1
+#define SPI_SCK1_P1_15 1
+#define SPI_MISO1_P0_22 1
+#define SPI_MOSI1_P0_21 1
+#define SPI_1_MODE ((1 << LPC_SSP_CR0_CPOL) | (1 << LPC_SSP_CR0_CPHA))
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS 1
+#define AO_M25_SPI_CS_PORT 0
+#define AO_M25_SPI_CS_MASK (1 << 3)
+#define AO_M25_SPI_BUS 0
+
+/* ADXL375 */
+
+#define HAS_ADXL375 1
+#define AO_ADXL375_SPI_INDEX 1
+#define AO_ADXL375_CS_PORT 0
+#define AO_ADXL375_CS_PIN 19
+
+#define AO_ADXL375_AXIS x
+#define AO_ADXL375_ACROSS_AXIS y
+#define AO_ADXL375_THROUGH_AXIS z
+#define AO_ADXL375_INVERT 0
+#define HAS_IMU 1
+#define USE_ADXL375_IMU 1
+
+/* Motor pressure */
+#define HAS_MOTOR_PRESSURE 1
+#define ao_data_motor_pressure(packet) ((packet)->adc.motor_pressure)
+
+typedef int16_t motor_pressure_t;
+
+#endif /* _AO_PINS_H_ */
--- /dev/null
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=easymotor-v3
+include $(TOPDIR)/lpc/Makefile-flash.defs
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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_PINS_H_
+#define _AO_PINS_H_
+
+#include <ao_flash_lpc_pins.h>
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO 0
+#define AO_BOOT_APPLICATION_PIN 2
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 20
+
+#endif /* _AO_PINS_H_ */
CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS)
-LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos-loader.ld
+LDFLAGS=-Wl,--undefined=force_no_isp -nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos-loader.ld
PROGNAME=$(HARDWARE)-altos-flash
PROG=$(PROGNAME)-$(VERSION).elf
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-__flash = 0x0;
-__flash_size = 4K;
+__flash = 0x300;
+__flash_size = 4K - 0x300;
__ram = 0x10000000;
__ram_size = 4k;
__stack_size = 128;
INCLUDE registers.ld
-INCLUDE picolibc.ld
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright © 2019 Keith Packard
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ENTRY(_start)
+
+/*
+ * These values should be provided by the application. We'll include
+ * some phony values here to make things link for testing
+ */
+
+MEMORY
+{
+ low (rxai!w) : ORIGIN = 0x0, LENGTH = 0x2fc
+ no_isp (rxai!w): ORIGIN = 0x2fc, LENGTH = 4
+ flash (rxai!w) : ORIGIN = DEFINED(__flash) ? __flash : 0x10000000, LENGTH = DEFINED(__flash_size) ? __flash_size : 0x10000
+ ram (wxa!ri) : ORIGIN = DEFINED(__ram ) ? __ram : 0x20000000, LENGTH = DEFINED(__ram_size ) ? __ram_size : 0x08000
+}
+
+PHDRS
+{
+ text PT_LOAD;
+ ram PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+}
+
+SECTIONS
+{
+ PROVIDE(__stack = ORIGIN(ram) + LENGTH(ram));
+
+ .init : {
+ KEEP (*(.text.init.enter))
+ KEEP (*(.data.init.enter))
+ KEEP (*(SORT_BY_NAME(.init) SORT_BY_NAME(.init.*)))
+ } >low AT>low :text
+
+ .text.low : {
+ ao_boot_chain.o(.text .text.*)
+ ao_boot_pin.o(.text .text.*)
+ ao_flash_loader_lpc.o(.text .text.*)
+ ao_notask.o(*.text .text.*)
+ ao_product.o(.rodata .rodata.*)
+ } >low AT>low :text
+
+ .no_isp : {
+ *(.no_isp)
+ } > no_isp AT>no_isp :text
+
+ .text : {
+
+ /* code */
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ KEEP (*(.fini .fini.*))
+ __text_end = .;
+
+ PROVIDE (__etext = __text_end);
+ PROVIDE (_etext = __text_end);
+ PROVIDE (etext = __text_end);
+
+ /* read-only data */
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ *(.data.rel.ro .data.rel.ro.*)
+ *(.got .got.*)
+
+ /* Need to pre-align so that the symbols come after padding */
+ . = ALIGN(8);
+
+ /* lists of constructors and destructors */
+ PROVIDE_HIDDEN ( __preinit_array_start = . );
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN ( __preinit_array_end = . );
+
+ PROVIDE_HIDDEN ( __init_array_start = . );
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array .ctors))
+ PROVIDE_HIDDEN ( __init_array_end = . );
+
+ PROVIDE_HIDDEN ( __fini_array_start = . );
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array .dtors))
+ PROVIDE_HIDDEN ( __fini_array_end = . );
+ } >flash AT>flash :text
+
+ /* additional sections when compiling with C++ exception support */
+ /*
+ .except_ordered : {
+ *(.gcc_except_table *.gcc_except_table.*)
+ KEEP (*(.eh_frame .eh_frame.*))
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } >flash AT>flash :text
+
+ .except_unordered : {
+ . = ALIGN(8);
+
+ PROVIDE(__exidx_start = .);
+ *(.ARM.exidx*)
+ PROVIDE(__exidx_end = .);
+ } >flash AT>flash :text
+ */
+
+ /*
+ * Data values which are preserved across reset
+ */
+ .preserve (NOLOAD) : {
+ PROVIDE(__preserve_start__ = .);
+ KEEP(*(SORT_BY_NAME(.preserve.*)))
+ KEEP(*(.preserve))
+ PROVIDE(__preserve_end__ = .);
+ } >ram AT>ram :ram
+
+ .data : ALIGN_WITH_INPUT {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+
+ /* Need to pre-align so that the symbols come after padding */
+ . = ALIGN(8);
+
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>flash :ram_init
+ PROVIDE(__data_start = ADDR(.data));
+ PROVIDE(__data_source = LOADADDR(.data));
+
+ /* Thread local initialized data. This gets
+ * space allocated as it is expected to be placed
+ * in ram to be used as a template for TLS data blocks
+ * allocated at runtime. We're slightly abusing that
+ * by placing the data in flash where it will be copied
+ * into the allocate ram addresses by the existing
+ * data initialization code in crt0
+ */
+ .tdata : ALIGN_WITH_INPUT {
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ PROVIDE(__data_end = .);
+ PROVIDE(__tdata_end = .);
+ } >ram AT>flash :tls :ram_init
+ PROVIDE( __tls_base = ADDR(.tdata));
+ PROVIDE( __tdata_start = ADDR(.tdata));
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( __edata = __data_end );
+ PROVIDE( _edata = __data_end );
+ PROVIDE( edata = __data_end );
+ PROVIDE( __data_size = __data_end - __data_start );
+
+ .tbss (NOLOAD) : {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon)
+ PROVIDE( __tls_end = . );
+ PROVIDE( __tbss_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __bss_start = ADDR(.tbss));
+ PROVIDE( __tbss_start = ADDR(.tbss));
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ /*
+ * The linker special cases .tbss segments which are
+ * identified as segments which are not loaded and are
+ * thread_local.
+ *
+ * For these segments, the linker does not advance 'dot'
+ * across them. We actually need memory allocated for tbss,
+ * so we create a special segment here just to make room
+ */
+ .tbss_space (NOLOAD) : {
+ . = . + SIZEOF(.tbss);
+ } >ram AT>ram :ram
+
+ .bss (NOLOAD) : {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+
+ /* Align the heap */
+ . = ALIGN(8);
+ __bss_end = .;
+ } >ram AT>ram :ram
+ PROVIDE( __end = __bss_end );
+ PROVIDE( _end = __bss_end );
+ PROVIDE( end = __bss_end );
+ PROVIDE( __bss_size = __bss_end - __bss_start );
+
+ /* Make the rest of memory available for heap storage */
+ PROVIDE (__heap_start = __end);
+ PROVIDE (__heap_end = __stack - (DEFINED(__stack_size) ? __stack_size : 0x800));
+ PROVIDE (__heap_size = __heap_end - __heap_start);
+
+ /* Define a stack region to make sure it fits in memory */
+ .stack (NOLOAD) : {
+ . += (DEFINED(__stack_size) ? __stack_size : 0x800);
+ } >ram :ram
+
+ /* Throw away C++ exception handling information */
+
+
+
+ /DISCARD/ : {
+ *(.note .note.*)
+ *(.eh_frame .eh_frame.*)
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ *(.ARM.exidx*)
+ }
+
+
+}
}
void
-ao_beep_for(uint8_t beep, AO_TICK_TYPE ticks)
+ao_beep_for(uint8_t beep, AO_TICK_TYPE ticks)
{
ao_beep(beep);
ao_delay(ticks);
__attribute__ ((section(".init.0")))
const void *const __interrupt_pad[0x10];
+#if IS_FLASH_LOADER
+/* Flash loader needs a magic value at 0x2fc to be 0x4E69 7370 */
+__attribute__ ((section(".no_isp")))
+const uint32_t force_no_isp = 0x4E697370;
+#endif
+
void main(void) __attribute__((__noreturn__));
void *__interrupt_ram[sizeof(__interrupt_vector)/sizeof(__interrupt_vector[0])] __attribute((section(".preserve.1")));
}
static void
-ao_spi_channel_init(uint8_t id)
+ao_spi_channel_init(uint8_t id, uint8_t mode)
{
struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id];
uint8_t d;
lpc_ssp->cr0 = ((LPC_SSP_CR0_DSS_8 << LPC_SSP_CR0_DSS) |
(LPC_SSP_CR0_FRF_SPI << LPC_SSP_CR0_FRF) |
- (0 << LPC_SSP_CR0_CPOL) |
- (0 << LPC_SSP_CR0_CPHA) |
+ mode |
(0 << LPC_SSP_CR0_SCR));
/* Enable the device */
ao_spi_init(void)
{
#if HAS_SPI_0
+#ifndef SPI_0_MODE
+#define SPI_0_MODE 0
+#endif
/* Configure pins */
#if SPI_SCK0_P0_6
lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_6_SCK0);
/* Reset the device */
lpc_scb.presetctrl &= ~(1UL << LPC_SCB_PRESETCTRL_SSP0_RST_N);
lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP0_RST_N);
- ao_spi_channel_init(0);
+ ao_spi_channel_init(0, SPI_0_MODE);
#endif
#if HAS_SPI_1
+#ifndef SPI_1_MODE
+#define SPI_1_MODE 0
+#endif
#if SPI_SCK1_P1_15
lpc_ioconf.pio1_15 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_15_SCK1);
/* Reset the device */
lpc_scb.presetctrl &= ~(1UL << LPC_SCB_PRESETCTRL_SSP1_RST_N);
lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP1_RST_N);
- ao_spi_channel_init(1);
+ ao_spi_channel_init(1, SPI_1_MODE);
#endif /* HAS_SPI_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_PIO0_1_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
+#define LPC_IOCONF_FUNC_PIO0_2_CT16B0_CAP0 2
/* PIO0_3 */
#define LPC_IOCONF_FUNC_PIO0_3 0
/* PIO0_8 */
#define LPC_IOCONF_FUNC_PIO0_8 0
#define LPC_IOCONF_FUNC_MISO0 1
-#define LPC_IOCONF_FUNC_CT16B0_MAT0 2
+#define LPC_IOCONF_FUNC_PIO0_8_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
+#define LPC_IOCONF_FUNC_PIO0_9_CT16B0_MAT1 2
/* PIO0_10 */
#define LPC_IOCONF_FUNC_SWCLK 0
#define LPC_IOCONF_FUNC_PIO0_10 1
#define LPC_IOCONF_FUNC_PIO0_10_SCK0 2
-#define LPC_IOCONF_FUNC_CT16B0_MAT2 3
+#define LPC_IOCONF_FUNC_PIO0_10_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
+#define LPC_IOCONF_FUNC_PIO0_11_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
+#define LPC_IOCONF_FUNC_PIO0_12_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
+#define LPC_IOCONF_FUNC_PIO0_13_CT32B1_MAT0 3
/* PIO0_14 */
#define LPC_IOCONF_FUNC_TRST 0
#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
+#define LPC_IOCONF_FUNC_PIO0_15_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
+#define LPC_IOCONF_FUNC_PIO0_16_CT32B1_MAT3 2
/* PIO0_17 */
#define LPC_IOCONF_FUNC_PIO0_17 0
/* PIO0_20 */
#define LPC_IOCONF_FUNC_PIO0_20 0
-#define LPC_IOCONF_FUNC_CT16B1_CAP0 1
+#define LPC_IOCONF_FUNC_PIO0_20_CT16B1_CAP0 1
/* PIO0_21 */
#define LPC_IOCONF_FUNC_PIO0_21 0
-#define LPC_IOCONF_FUNC_CT16B1_MAT0 1
+#define LPC_IOCONF_FUNC_PIO0_21_CT16B1_MAT0 1
#define LPC_IOCONF_FUNC_PIO0_21_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_PIO0_22_CT16B1_MAT1 2
#define LPC_IOCONF_FUNC_PIO0_22_MISO1 3
/* PIO0_23 */
/* PIO1_0 */
#define LPC_IOCONF_FUNC_PIO1_0 0
-#define LPC_IOCONF_FUNC_CT32B1_MAT1 1
+#define LPC_IOCONF_FUNC_PIO1_0_CT32B1_MAT1 1
/* PIO1_1 */
#define LPC_IOCONF_FUNC_PIO1_1 0
-#define LPC_IOCONF_FUNC_CT32B1_MAT1 1
+#define LPC_IOCONF_FUNC_PIO1_1_CT32B1_MAT1 1
/* PIO1_2 */
#define LPC_IOCONF_FUNC_PIO1_2 0
/* PIO1_5 */
#define LPC_IOCONF_FUNC_PIO1_5 0
-#define LPC_IOCONF_FUNC_CT32B1_CAP1 1
+#define LPC_IOCONF_FUNC_PIO1_5_CT32B1_CAP1 1
/* PIO1_6 */
#define LPC_IOCONF_FUNC_PIO1_6 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_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_14_CT16B0_MAT1 2
#define LPC_IOCONF_FUNC_PIO1_13_RXD 3
/* PIO1_15 */
/* PIO1_16 */
#define LPC_IOCONF_FUNC_PIO1_16 0
#define LPC_IOCONF_FUNC_RI 1
-#define LPC_IOCONF_FUNC_CT16B0_CAP0 2
+#define LPC_IOCONF_FUNC_PIO1_16_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_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_CT16B1_CAP1 1
#define LPC_IOCONF_FUNC_PIO1_18_TXD 2
/* PIO1_19 */