Merge branch 'easymotor-v3'
authorKeith Packard <keithp@keithp.com>
Fri, 28 Oct 2022 02:16:39 +0000 (19:16 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 28 Oct 2022 02:16:39 +0000 (19:16 -0700)
18 files changed:
altoslib/AltosConfigData.java
ao-tools/ao-eeprom/ao-eeprom.c
ao-tools/lib/ao-eeprom-read.h
src/Makefile
src/drivers/ao_adxl375.c
src/drivers/ao_adxl375.h
src/easymini-v1.0/ao_pins.h
src/easymotor-v3/Makefile [new file with mode: 0644]
src/easymotor-v3/ao_easymotor.c [new file with mode: 0644]
src/easymotor-v3/ao_pins.h [new file with mode: 0644]
src/easymotor-v3/flash-loader/Makefile [new file with mode: 0644]
src/easymotor-v3/flash-loader/ao_pins.h [new file with mode: 0644]
src/lpc/Makefile-flash.defs
src/lpc/altos-loader.ld
src/lpc/ao_beep_lpc.c
src/lpc/ao_interrupt.c
src/lpc/ao_spi_lpc.c
src/lpc/lpc.h

index cd649113b1a6b8293b3766f05a74f97ae6f79d0b..da6e7bfc6d8199b228e0b8918219c3fafb6038b2 100644 (file)
@@ -662,6 +662,8 @@ public class AltosConfigData {
                                return true;
                        if (product.startsWith("EasyMotor-v2"))
                                return true;
+                       if (product.startsWith("EasyMotor-v3"))
+                               return true;
                }
                throw new AltosUnknownProduct(product);
        }
@@ -676,6 +678,8 @@ public class AltosConfigData {
                                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);
index f63676300ebd76817b3cb6ac462d0d22c69f1af0..1f367d9332265be4f4f9941afbe4b3e76ee87def 100644 (file)
@@ -355,7 +355,6 @@ main (int argc, char **argv)
                        break;
                case AO_LOG_FORMAT_TELEMEGA_4:
                        len = 32;
-                       break;
                        max_adc= 4095;
                        adc_ref = 3.3;
                        batt_r1 = 5600;
@@ -695,6 +694,45 @@ main (int argc, char **argv)
                                                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:
index 11e4f91d92e0fe6f9daa13b1ff9828ac55de91a9..9e60a5af9acdd0750b30e9934a190d47f1ab071d 100644 (file)
@@ -466,6 +466,37 @@ struct ao_log_mini {
        } 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;        \
index f698d15d75f125fe6e525260c908a720cd8fdf41..5215ca70aadecc8fb47a96d4c5b8ab562006e35b 100644 (file)
@@ -20,6 +20,7 @@ ARMM3DIRS=\
        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 \
index c95bf9e32bc02776c31b25aa2eec055d79080230..9e5666cc5d6dcb83ea11697e676ba3b544555f01 100644 (file)
@@ -21,7 +21,7 @@
 #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
@@ -55,7 +55,7 @@ ao_adxl375_reg_read(uint8_t addr)
        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];
 }
@@ -73,7 +73,7 @@ ao_adxl375_reg_write(uint8_t addr, uint8_t value)
        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);
@@ -129,7 +129,7 @@ ao_adxl375_total_value(struct ao_adxl375_total *total, int samples)
 #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))
 
index fe448fd0e27857d06592188d5aa38548ca5b6348..32fe0fac30247948e710c3d9b8fcaaf080ea64d9 100644 (file)
@@ -72,8 +72,8 @@
 # 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
index eb805c76bd34ff71c187c9cdd3a279427cbde503..940d0d98c26a7ac62e292a3c4b262a9a78fb5862 100644 (file)
 /* 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
diff --git a/src/easymotor-v3/Makefile b/src/easymotor-v3/Makefile
new file mode 100644 (file)
index 0000000..b33572a
--- /dev/null
@@ -0,0 +1,78 @@
+#
+# 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:
diff --git a/src/easymotor-v3/ao_easymotor.c b/src/easymotor-v3/ao_easymotor.c
new file mode 100644 (file)
index 0000000..154c4c0
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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();
+}
diff --git a/src/easymotor-v3/ao_pins.h b/src/easymotor-v3/ao_pins.h
new file mode 100644 (file)
index 0000000..c54c7f0
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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_ */
diff --git a/src/easymotor-v3/flash-loader/Makefile b/src/easymotor-v3/flash-loader/Makefile
new file mode 100644 (file)
index 0000000..8db9825
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=easymotor-v3
+include $(TOPDIR)/lpc/Makefile-flash.defs
diff --git a/src/easymotor-v3/flash-loader/ao_pins.h b/src/easymotor-v3/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..0837bc1
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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_ */
index 3965919515eeddc6d4f78a62eecf82bcb4f33cb7..cbe1d8731927b3a8ae258bf9b08b3399131358a5 100644 (file)
@@ -35,7 +35,7 @@ IDPRODUCT=0x000a
 
 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
index 75b527fb24bf9fc79a3d9addc5f53d179e44ad66..d8bcfb44b3c0db7d408694e1177d286da335a84a 100644 (file)
  * 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*)
+       }
+
+       
+}
index 8cbd3ed2f8fadb407dd909471ee3ecbf8976716d..32e108cd8a974a730f0c8a3c102abafe1b872b91 100644 (file)
@@ -81,7 +81,7 @@ ao_beep(uint8_t beep)
 }
 
 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);
index bc2848c3bffa364ba6298d3a32c9439a817dc57c..25413abb04964676c1367d968118bd7d200a6a18 100644 (file)
@@ -162,6 +162,12 @@ const void *const __interrupt_vector[0x30] = {
 __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")));
index ec48e95c386eeec40a1f90b936606aa22193fede..010feb63ec3ebc5e2c4c74b165e20dc38a83ad50 100644 (file)
@@ -90,7 +90,7 @@ ao_spi_put(uint8_t id)
 }
 
 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;
@@ -102,8 +102,7 @@ ao_spi_channel_init(uint8_t id)
 
        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 */
@@ -121,6 +120,9 @@ void
 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);
@@ -149,10 +151,13 @@ ao_spi_init(void)
        /* 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);
@@ -199,6 +204,6 @@ ao_spi_init(void)
        /* 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 */
 }
index fbf529c941d494d6ed4499ac896b75cebecf7148..be0dc021d7a7cf6e12629349b8398d0543161ef4 100644 (file)
@@ -110,13 +110,13 @@ extern struct lpc_ioconf lpc_ioconf;
 /* 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
@@ -142,36 +142,36 @@ extern struct lpc_ioconf lpc_ioconf;
 /* 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
@@ -183,12 +183,12 @@ extern struct lpc_ioconf lpc_ioconf;
 #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
@@ -208,17 +208,17 @@ extern struct lpc_ioconf lpc_ioconf;
 
 /* 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 */
@@ -227,11 +227,11 @@ extern struct lpc_ioconf lpc_ioconf;
 
 /* 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
@@ -247,7 +247,7 @@ extern struct lpc_ioconf lpc_ioconf;
 
 /* 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
@@ -273,13 +273,13 @@ extern struct lpc_ioconf lpc_ioconf;
 /* 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 */
@@ -291,16 +291,16 @@ extern struct lpc_ioconf lpc_ioconf;
 /* 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 */