From: Keith Packard Date: Sat, 17 Aug 2013 14:03:26 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/master' X-Git-Tag: 1.2.9.4~133^2~7 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=4ff54bb96f6c00c0c2c7dd32f81403bac331621a;hp=01f8df088759ee7e6bc3900a013e0ea4fafaf984 Merge remote-tracking branch 'origin/master' --- diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 0236b537..940ad792 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -36,11 +36,13 @@ import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import android.os.Looper; import android.util.Log; import android.widget.Toast; import android.location.Location; import android.location.LocationManager; import android.location.LocationListener; +import android.location.Criteria; import org.altusmetrum.altoslib_1.*; @@ -280,8 +282,8 @@ public class TelemetryService extends Service implements LocationListener { // Listen for GPS and Network position updates LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); - locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this); +// locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); } @Override diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index a42b36c4..8cd478e2 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -242,6 +242,10 @@ public class AltosConvert { return meters * (100 / (2.54 * 12)); } + public static double feet_to_meters(double feet) { + return feet * 12 * 2.54 / 100.0; + } + public static double meters_to_miles(double meters) { return meters_to_feet(meters) / 5280; } diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index ed590812..96f5722b 100644 --- a/altoslib/AltosHeight.java +++ b/altoslib/AltosHeight.java @@ -25,6 +25,13 @@ public class AltosHeight extends AltosUnits { return v; } + public double parse(String s) throws NumberFormatException { + double v = Double.parseDouble(s); + if (AltosConvert.imperial_units) + v = AltosConvert.feet_to_meters(v); + return v; + } + public String show_units() { if (AltosConvert.imperial_units) return "ft"; diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index a629260b..d60ef492 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -92,8 +92,10 @@ public class AltosLib { public final static int product_telemega = 0x0023; public final static int product_megadongle = 0x0024; public final static int product_telegps = 0x0025; + public final static int product_easymini = 0x0026; + public final static int product_telemini = 0x0027; public final static int product_altusmetrum_min = 0x000a; - public final static int product_altusmetrum_max = 0x0025; + public final static int product_altusmetrum_max = 0x002c; public final static int product_any = 0x10000; public final static int product_basestation = 0x10000 + 1; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 825306be..e0d9bb1f 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -40,6 +40,7 @@ public class AltosState { public double ground_altitude; public double altitude; public double height; + public double pressure; public double acceleration; public double battery; public double temperature; @@ -125,6 +126,7 @@ public class AltosState { drogue_sense = data.drogue_voltage(); main_sense = data.main_voltage(); battery = data.battery_voltage(); + pressure = data.pressure(); tick = data.tick; state = data.state; diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 11f40593..9723e660 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -26,7 +26,7 @@ import org.altusmetrum.altosuilib_1.*; public class AltosConfigUI extends AltosUIDialog - implements ActionListener, ItemListener, DocumentListener, AltosConfigValues + implements ActionListener, ItemListener, DocumentListener, AltosConfigValues, AltosUnitsListener { Container pane; @@ -75,11 +75,16 @@ public class AltosConfigUI ActionListener listener; - static String[] main_deploy_values = { + static String[] main_deploy_values_m = { "100", "150", "200", "250", "300", "350", "400", "450", "500" }; + static String[] main_deploy_values_ft = { + "250", "500", "750", "1000", "1250", "1500", + "1750", "2000" + }; + static String[] apogee_delay_values = { "0", "1", "2", "3", "4", "5" }; @@ -280,7 +285,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = il; c.ipady = 5; - main_deploy_label = new JLabel("Main Deploy Altitude(m):"); + main_deploy_label = new JLabel(get_main_deploy_label()); pane.add(main_deploy_label, c); c = new GridBagConstraints(); @@ -291,7 +296,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - main_deploy_value = new JComboBox(main_deploy_values); + main_deploy_value = new JComboBox(main_deploy_values()); main_deploy_value.setEditable(true); main_deploy_value.addItemListener(this); pane.add(main_deploy_value, c); @@ -616,6 +621,7 @@ public class AltosConfigUI close.setActionCommand("Close"); addWindowListener(new ConfigListener(this)); + AltosPreferences.register_units_listener(this); } /* Once the initial values are set, the config code will show the dialog */ @@ -654,6 +660,10 @@ public class AltosConfigUI AltosConfigPyroUI pyro_ui; + public void dispose() { + AltosPreferences.unregister_units_listener(this); + } + /* Listen for events from our buttons */ public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); @@ -718,12 +728,38 @@ public class AltosConfigUI } public void set_main_deploy(int new_main_deploy) { - main_deploy_value.setSelectedItem(Integer.toString(new_main_deploy)); + main_deploy_value.setSelectedItem(AltosConvert.height.say(new_main_deploy)); main_deploy_value.setEnabled(new_main_deploy >= 0); } public int main_deploy() { - return Integer.parseInt(main_deploy_value.getSelectedItem().toString()); + return (int) (AltosConvert.height.parse(main_deploy_value.getSelectedItem().toString()) + 0.5); + } + + String get_main_deploy_label() { + return String.format("Main Deploy Altitude(%s):", AltosConvert.height.show_units()); + } + + String[] main_deploy_values() { + if (AltosConvert.imperial_units) + return main_deploy_values_ft; + else + return main_deploy_values_m; + } + + void set_main_deploy_values() { + String[] v = main_deploy_values(); + while (main_deploy_value.getItemCount() > 0) + main_deploy_value.removeItemAt(0); + for (int i = 0; i < v.length; i++) + main_deploy_value.addItem(v[i]); + main_deploy_value.setMaximumRowCount(v.length); + } + + public void units_changed(boolean imperial_units) { + main_deploy_label.setText(get_main_deploy_label()); + set_main_deploy_values(); + listener.actionPerformed(new ActionEvent(this, 0, "Reset")); } public void set_apogee_delay(int new_apogee_delay) { diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index defe69a0..40604ce3 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -73,18 +73,18 @@ class AltosNsat extends AltosUnits { } } -class AltosDbm extends AltosUnits { +class AltosPressure extends AltosUnits { - public double value(double v) { - return v; + public double value(double p) { + return p; } public String show_units() { - return "dBm"; + return "Pa"; } public String say_units() { - return "d b m"; + return "pascals"; } public int show_fraction(int width) { @@ -96,6 +96,7 @@ public class AltosGraph extends AltosUIGraph { static final private Color height_color = new Color(194,31,31); static final private Color gps_height_color = new Color(150,31,31); + static final private Color pressure_color = new Color (225,31,31); static final private Color range_color = new Color(100, 31, 31); static final private Color distance_color = new Color(100, 31, 194); static final private Color speed_color = new Color(31,194,31); @@ -112,16 +113,18 @@ public class AltosGraph extends AltosUIGraph { static final private Color state_color = new Color(0,0,0); static AltosVoltage voltage_units = new AltosVoltage(); + static AltosPressure pressure_units = new AltosPressure(); static AltosNsat nsat_units = new AltosNsat(); static AltosDbm dbm_units = new AltosDbm(); AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; - AltosUIAxis distance_axis; + AltosUIAxis distance_axis, pressure_axis; public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) { super(enable); height_axis = newAxis("Height", AltosConvert.height, height_color); + pressure_axis = newAxis("Pressure", pressure_units, pressure_color, 0); speed_axis = newAxis("Speed", AltosConvert.speed, speed_color); accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color); voltage_axis = newAxis("Voltage", voltage_units, voltage_color); @@ -138,6 +141,12 @@ public class AltosGraph extends AltosUIGraph { height_color, true, height_axis); + addSeries("Pressure", + AltosGraphDataPoint.data_pressure, + pressure_units, + pressure_color, + false, + pressure_axis); addSeries("Speed", AltosGraphDataPoint.data_speed, AltosConvert.speed, diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 8e6d6923..7454f447 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -39,6 +39,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public static final int data_temperature = 12; public static final int data_range = 13; public static final int data_distance = 14; + public static final int data_pressure = 15; public double x() throws AltosUIDataMissing { if (state.data.time < -2) @@ -94,6 +95,9 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { if (state.from_pad != null) y = state.from_pad.distance; break; + case data_pressure: + y = state.pressure; + break; } if (y == AltosRecord.MISSING) throw new AltosUIDataMissing(index); diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java index a06b6869..005a3e49 100644 --- a/altosuilib/AltosUSBDevice.java +++ b/altosuilib/AltosUSBDevice.java @@ -77,7 +77,9 @@ public class AltosUSBDevice extends altos_device implements AltosDevice { if (want_product == AltosUILib.product_altimeter) return matchProduct(AltosUILib.product_telemetrum) || matchProduct(AltosUILib.product_telemega) || - matchProduct(AltosUILib.product_telegps); + matchProduct(AltosUILib.product_telegps) || + matchProduct(AltosUILib.product_easymini) || + matchProduct(AltosUILib.product_telemini); int have_product = getProduct(); diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 79223176..cb1c68cb 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -231,6 +231,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene fileMenu.add(exitAction); exitAction.addActionListener(this); + JButton downloadButton = new JButton ("Download"); + downloadButton.addActionListener(this); + menuBar.add(downloadButton); + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { @Override diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index 88b8f686..190647ce 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -374,7 +374,7 @@ ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant } #if NEED_RADIO_RSSI else - ao_radio_rssi = AO_RSSI_FROM_RADIO(((uint8_t *)packet)[size - 1]); + ao_radio_rssi = AO_RSSI_FROM_RADIO(((uint8_t *)packet)[size - 2]); #endif ao_radio_put(); return ao_radio_dma_done; diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 782e2274..1322195b 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -117,7 +117,7 @@ ao_flight(void) { /* Set pad mode - we can fly! */ ao_flight_state = ao_flight_pad; -#if HAS_USB && HAS_RADIO && !HAS_FLIGHT_DEBUG && !HAS_SAMPLE_PROFILE +#if HAS_USB && !HAS_FLIGHT_DEBUG && !HAS_SAMPLE_PROFILE /* Disable the USB controller in flight mode * to save power */ diff --git a/src/core/ao_log.c b/src/core/ao_log.c index 7884ec3c..8bcb7707 100644 --- a/src/core/ao_log.c +++ b/src/core/ao_log.c @@ -278,6 +278,11 @@ ao_log_init(void) ao_cmd_register(&ao_log_cmds[0]); +#ifndef HAS_ADC +#error Define HAS_ADC for ao_log.c +#endif +#if HAS_ADC /* Create a task to log events to eeprom */ ao_add_task(&ao_log_task, ao_log, "log"); +#endif } diff --git a/src/core/ao_log_mega.c b/src/core/ao_log_mega.c index ee12b907..768947d5 100644 --- a/src/core/ao_log_mega.c +++ b/src/core/ao_log_mega.c @@ -65,6 +65,7 @@ ao_log_dump_check_data(void) return 1; } +#if HAS_ADC static __data uint8_t ao_log_data_pos; /* a hack to make sure that ao_log_megas fill the eeprom block in even units */ @@ -182,6 +183,7 @@ ao_log(void) ao_sleep(&ao_log_running); } } +#endif uint16_t ao_log_flight(uint8_t slot) diff --git a/src/drivers/ao_m25.c b/src/drivers/ao_m25.c index 9b768012..e6c7bb4d 100644 --- a/src/drivers/ao_m25.c +++ b/src/drivers/ao_m25.c @@ -86,7 +86,7 @@ static ao_port_t ao_m25_pin[M25_MAX_CHIPS]; /* chip select pin for each chip */ static uint8_t ao_m25_numchips; /* number of chips detected */ #endif static uint8_t ao_m25_total; /* total sectors available */ -static uint8_t ao_m25_wip; /* write in progress */ +static ao_port_t ao_m25_wip; /* write in progress */ static __xdata uint8_t ao_m25_mutex; @@ -250,7 +250,6 @@ ao_storage_erase(uint32_t pos) __reentrant cs = ao_m25_set_address(pos); - ao_m25_wait_wip(cs); ao_m25_write_enable(cs); ao_m25_instruction[0] = M25_SE; diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index e205f99b..62ae68e9 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -27,6 +27,7 @@ static __pdata uint8_t ao_pad_armed; static __pdata uint16_t ao_pad_arm_time; static __pdata uint8_t ao_pad_box; static __xdata uint8_t ao_pad_disabled; +static __pdata uint16_t ao_pad_packet_time; #define DEBUG 1 @@ -135,6 +136,12 @@ ao_pad_monitor(void) query.arm_status = AO_PAD_ARM_STATUS_UNKNOWN; arm_beep_time = 0; } + if ((ao_time() - ao_pad_packet_time) > AO_SEC_TO_TICKS(2)) + cur |= AO_LED_RED; + else if (ao_radio_cmac_rssi < -90) + cur |= AO_LED_AMBER; + else + cur |= AO_LED_GREEN; for (c = 0; c < AO_PAD_NUM; c++) { int16_t sense = packet->adc.sense[c]; @@ -171,9 +178,10 @@ ao_pad_monitor(void) query.igniter_status[c] = status; } if (cur != prev) { - PRINTD("change leds from %02x to %02x mask %02x\n", - prev, cur, AO_LED_CONTINUITY_MASK|AO_LED_ARMED); - ao_led_set_mask(cur, AO_LED_CONTINUITY_MASK | AO_LED_ARMED); + PRINTD("change leds from %02x to %02x\n", + prev, cur); + FLUSHD(); + ao_led_set(cur); prev = cur; } @@ -238,15 +246,15 @@ ao_pad(void) ao_pad_box = 0; ao_led_set(0); - ao_led_on(AO_LED_POWER); for (;;) { FLUSHD(); while (ao_pad_disabled) ao_sleep(&ao_pad_disabled); ret = ao_radio_cmac_recv(&command, sizeof (command), 0); - PRINTD ("cmac_recv %d\n", ret); + PRINTD ("cmac_recv %d %d\n", ret, ao_radio_cmac_rssi); if (ret != AO_RADIO_CMAC_OK) continue; + ao_pad_packet_time = ao_time(); ao_pad_box = ao_pad_read_box(); diff --git a/src/drivers/ao_pca9922.c b/src/drivers/ao_pca9922.c index 6d8d18d8..fe070b88 100644 --- a/src/drivers/ao_pca9922.c +++ b/src/drivers/ao_pca9922.c @@ -30,9 +30,12 @@ ao_led_apply(void) /* Don't try the SPI bus during initialization */ if (!ao_cur_task) return; - ao_spi_get_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS, AO_SPI_SPEED_FAST); + ao_mutex_get(&ao_spi_mutex); + ao_spi_set_speed(AO_SPI_SPEED_FAST); + AO_PCA9922_CS = 1; ao_spi_send(&ao_led_state, 1, AO_PCA9922_SPI_BUS); - ao_spi_put_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS); + AO_PCA9922_CS = 0; + ao_mutex_put(&ao_spi_mutex); } void diff --git a/src/easymini-v0.1/Makefile b/src/easymini-v0.1/Makefile index 612cc472..9847656c 100644 --- a/src/easymini-v0.1/Makefile +++ b/src/easymini-v0.1/Makefile @@ -18,6 +18,7 @@ INC = \ # ALTOS_SRC = \ ao_interrupt.c \ + ao_boot_chain.c \ ao_romconfig.c \ ao_product.c \ ao_mutex.c \ @@ -39,7 +40,6 @@ ALTOS_SRC = \ ao_config.c \ ao_timer_lpc.c \ ao_exti_lpc.c \ - ao_serial_lpc.c \ ao_usb_lpc.c \ ao_spi_lpc.c \ ao_adc_lpc.c \ @@ -49,7 +49,7 @@ ALTOS_SRC = \ PRODUCT=EasyMini-v0.1 PRODUCT_DEF=-DEASYMINI_V_0_1 -IDPRODUCT=0x000a +IDPRODUCT=0x0026 CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os @@ -63,7 +63,7 @@ all: $(PROG) LDFLAGS=-L../lpc -Wl,-Taltos.ld -$(PROG): Makefile $(OBJ) +$(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc ao_product.h: ao-make-product.5c ../Version diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index d4fbe7a1..6f102dbe 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -18,6 +18,8 @@ #define HAS_BEEP 1 #define HAS_LED 1 +#define IS_FLASH_LOADER 0 + /* Crystal on the board */ #define AO_LPC_CLKIN 12000000 @@ -38,12 +40,15 @@ #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 /* USART */ -#define HAS_SERIAL 1 +#define HAS_SERIAL 0 #define USE_SERIAL_0_STDIN 1 #define SERIAL_0_18_19 1 #define SERIAL_0_14_15 0 diff --git a/src/easymini-v0.1/flash-loader/Makefile b/src/easymini-v0.1/flash-loader/Makefile new file mode 100644 index 00000000..ab828b22 --- /dev/null +++ b/src/easymini-v0.1/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easymini-v0.1 +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/easymini-v0.1/flash-loader/ao_pins.h b/src/easymini-v0.1/flash-loader/ao_pins.h new file mode 100644 index 00000000..4330151d --- /dev/null +++ b/src/easymini-v0.1/flash-loader/ao_pins.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_PINS_H_ +#define _AO_PINS_H_ + +#include + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 19 +#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_ */ diff --git a/src/lpc/altos-loader.ld b/src/lpc/altos-loader.ld new file mode 100644 index 00000000..4f78f552 --- /dev/null +++ b/src/lpc/altos-loader.ld @@ -0,0 +1,80 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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 : ORIGIN = 0x00000000, LENGTH = 4K + ram : ORIGIN = 0x10000000, LENGTH = 4k - 128 - 32 + usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 + stack (!w) : ORIGIN = 0x10000000 + 4K - 128 - 32, LENGTH = 128 +} + +INCLUDE registers.ld + +EXTERN (lpc_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .interrupt : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + } > rom + + .text ORIGIN(rom) + 0x100 : { + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + + *(.text*) /* Executable code */ + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + *(.rodata*) /* Constants */ + __text_end__ = .; + } > rom + + /* Boot data which must live at the start of ram so that + * the application and bootloader share the same addresses. + * This must be all uninitialized data + */ + .boot ORIGIN(ram) + SIZEOF(.interrupt) (NOLOAD) : { + __boot_start__ = .; + *(.boot) + __boot_end__ = .; + } >ram + + /* Data -- relocated to RAM, but written to ROM + */ + .data : { + __data_start__ = .; + *(.data) /* initialized data */ + __data_end__ = .; + } >ram AT>rom + + + .bss : { + __bss_start__ = .; + *(.bss) + *(COMMON) + __bss_end__ = .; + } >ram + + PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); + PROVIDE(end = .); +} + +ENTRY(start); diff --git a/src/lpc/altos-standalone.ld b/src/lpc/altos-standalone.ld new file mode 100644 index 00000000..032406f8 --- /dev/null +++ b/src/lpc/altos-standalone.ld @@ -0,0 +1,85 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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 - 128 - 32 + usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 + stack (!w) : ORIGIN = 0x10000000 + 4K - 128 - 32, LENGTH = 128 +} + +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 + + /* Boot data which must live at the start of ram so that + * the application and bootloader share the same addresses. + * This must be all uninitialized data + */ + .boot (NOLOAD) : { + __boot_start__ = .; + *(.boot) + . = ALIGN(4); + __boot_end__ = .; + } >ram + + /* 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(end = .); + + PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); +} + +ENTRY(start); + + diff --git a/src/lpc/altos.ld b/src/lpc/altos.ld index 4d6f35a8..00d4f18a 100644 --- a/src/lpc/altos.ld +++ b/src/lpc/altos.ld @@ -16,7 +16,7 @@ */ MEMORY { - rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K + rom (rx) : ORIGIN = 0x00001000, LENGTH = 28K ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 128 usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 stack (!w) : ORIGIN = 0x10000000 + 4K - 128, LENGTH = 128 @@ -31,11 +31,15 @@ SECTIONS { * Rom contents */ - .text ORIGIN(rom) : { - __text_start__ = .; + .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) { + __interrupt_start__ = .; + __interrupt_rom__ = ORIGIN(rom); *(.interrupt) /* Interrupt vectors */ + __interrupt_end__ = .; + } > ram - . = ORIGIN(rom) + 0x100; + .text ORIGIN(rom) + 0x100 : { + __text_start__ = .; ao_romconfig.o(.romconfig*) ao_product.o(.romconfig*) @@ -50,9 +54,20 @@ SECTIONS { __text_end__ = .; } > rom + /* Boot data which must live at the start of ram so that + * the application and bootloader share the same addresses. + * This must be all uninitialized data + */ + .boot : { + __boot_start__ = .; + *(.boot) + . = ALIGN(4); + __boot_end__ = .; + } >ram + /* Data -- relocated to RAM, but written to ROM */ - .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + .data : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { __data_start__ = .; *(.data) /* initialized data */ __data_end__ = .; @@ -60,6 +75,7 @@ SECTIONS { } >ram .bss : { + __bss_start__ = .; *(.bss) *(COMMON) __bss_end__ = .; diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c index 9ecc7c13..874d2d29 100644 --- a/src/lpc/ao_adc_lpc.c +++ b/src/lpc/ao_adc_lpc.c @@ -82,42 +82,56 @@ # endif #endif -static uint8_t ao_adc_ready; +#define AO_ADC_MASK ((AO_ADC_0 << 0) | \ + (AO_ADC_1 << 1) | \ + (AO_ADC_2 << 2) | \ + (AO_ADC_3 << 3) | \ + (AO_ADC_4 << 4) | \ + (AO_ADC_5 << 5) | \ + (AO_ADC_6 << 6) | \ + (AO_ADC_7 << 7)) + +#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 4500000) + +static uint8_t ao_adc_ready; + +#define sample(id) (*out++ = lpc_adc.dr[id] >> 1) void lpc_adc_isr(void) { uint32_t stat = lpc_adc.stat; - uint16_t *out = (uint16_t *) &ao_data_ring[ao_data_head].adc; - vuint32_t *in = &lpc_adc.dr[0]; + uint16_t *out; + /* Turn off burst mode */ lpc_adc.cr = 0; lpc_adc.stat = 0; /* Store converted values in packet */ + out = (uint16_t *) &ao_data_ring[ao_data_head].adc; #if AO_ADC_0 - *out++ = lpc_adc.dr[0] >> 1; + sample(0); #endif #if AO_ADC_1 - *out++ = lpc_adc.dr[1] >> 1; + sample(1); #endif #if AO_ADC_2 - *out++ = lpc_adc.dr[2] >> 1; + sample(2); #endif #if AO_ADC_3 - *out++ = lpc_adc.dr[3] >> 1; + sample(3); #endif #if AO_ADC_4 - *out++ = lpc_adc.dr[4] >> 1; + sample(4); #endif #if AO_ADC_5 - *out++ = lpc_adc.dr[5] >> 1; + sample(5); #endif #if AO_ADC_6 - *out++ = lpc_adc.dr[6] >> 1; + sample(6); #endif #if AO_ADC_7 - *out++ = lpc_adc.dr[7] >> 1; + sample(7); #endif AO_DATA_PRESENT(AO_DATA_ADC); @@ -141,16 +155,6 @@ void lpc_adc_isr(void) ao_adc_ready = 1; } -#define AO_ADC_MASK ((AO_ADC_0 << 0) | \ - (AO_ADC_1 << 1) | \ - (AO_ADC_2 << 2) | \ - (AO_ADC_3 << 3) | \ - (AO_ADC_4 << 4) | \ - (AO_ADC_5 << 5) | \ - (AO_ADC_6 << 6) | \ - (AO_ADC_7 << 7)) - -#define AO_ADC_CLKDIV (AO_LPC_CLKOUT / 4500000) /* * Start the ADC sequence using the DMA engine @@ -204,29 +208,35 @@ ao_adc_init(void) lpc_nvic_set_enable(LPC_ISR_ADC_POS); lpc_nvic_set_priority(LPC_ISR_ADC_POS, AO_LPC_NVIC_CLOCK_PRIORITY); #if AO_ADC_0 - ao_enable_analog(0, 11); + ao_enable_analog(0, 11, 0); #endif #if AO_ADC_1 - ao_enable_analog(0, 12); + ao_enable_analog(0, 12, 1); #endif #if AO_ADC_2 - ao_enable_analog(0, 13); + ao_enable_analog(0, 13, 2); #endif #if AO_ADC_3 - ao_enable_analog(0, 14); + ao_enable_analog(0, 14, 3); #endif #if AO_ADC_4 - ao_enable_analog(0, 14); + ao_enable_analog(0, 15, 4); #endif #if AO_ADC_5 - ao_enable_analog(0, 14); + ao_enable_analog(0, 16, 5); #endif #if AO_ADC_6 - ao_enable_analog(0, 14); + ao_enable_analog(0, 22, 6); #endif #if AO_ADC_7 - ao_enable_analog(0, 14); + ao_enable_analog(0, 23, 7); #endif + + lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | + (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | + (0 << LPC_ADC_CR_BURST) | + (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); + ao_cmd_register(&ao_adc_cmds[0]); ao_adc_ready = 1; diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index f605e3d2..a8d3cfc4 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -137,4 +137,8 @@ ao_serial_init(void); #define AO_SPI_SPEED_FAST AO_SPI_SPEED_12MHz +#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x00001000) +#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x00000000) +#define HAS_BOOT_LOADER 1 + #endif /* _AO_ARCH_H_ */ diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 204d1227..9a3219a2 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -22,12 +22,13 @@ #define ao_spi_put_bit(reg,bit,pin,bus) ao_spi_put_mask(reg,(1< + * + * 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_BOOT_H_ +#define _AO_BOOT_H_ + +void +ao_boot_chain(uint32_t *base); + +void +ao_boot_check_pin(void); + +/* Return true to switch to application (if present) */ +int +ao_boot_check_chain(void); + +void +ao_boot_reboot(uint32_t *base); + +static inline void +ao_boot_loader(void) { + ao_boot_reboot(AO_BOOT_LOADER_BASE); +} + +#endif /* _AO_BOOT_H_ */ diff --git a/src/lpc/ao_boot_chain.c b/src/lpc/ao_boot_chain.c new file mode 100644 index 00000000..a08d1f2c --- /dev/null +++ b/src/lpc/ao_boot_chain.c @@ -0,0 +1,67 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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 +#include + +void +ao_boot_chain(uint32_t *base) +{ + uint32_t sp; + uint32_t pc; + + sp = base[0]; + pc = base[1]; + if (0x00000100 <= pc && pc <= 0x00008000 && (pc & 1) == 1) { + asm ("mov sp, %0" : : "r" (sp)); + asm ("mov lr, %0" : : "r" (pc)); + asm ("bx lr"); + } +} + +#define AO_BOOT_SIGNAL 0x5a5aa5a5 +#define AO_BOOT_CHECK 0xc3c33c3c + +struct ao_boot { + uint32_t *base; + uint32_t signal; + uint32_t check; +}; + +static struct ao_boot __attribute__ ((section(".boot"))) ao_boot; + +int +ao_boot_check_chain(void) +{ + if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) { + ao_boot.signal = 0; + ao_boot.check = 0; + if (ao_boot.base == 0) + return 0; + ao_boot_chain(ao_boot.base); + } + return 1; +} + +void +ao_boot_reboot(uint32_t *base) +{ + ao_boot.base = base; + ao_boot.signal = AO_BOOT_SIGNAL; + ao_boot.check = AO_BOOT_CHECK; + ao_arch_reboot(); +} diff --git a/src/lpc/ao_boot_pin.c b/src/lpc/ao_boot_pin.c new file mode 100644 index 00000000..51ecc0a9 --- /dev/null +++ b/src/lpc/ao_boot_pin.c @@ -0,0 +1,46 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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 +#include +#include + +void +ao_boot_check_pin(void) +{ + uint16_t v; + + /* Enable power interface clock */ +// stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); + + /* Enable the input pin */ + ao_enable_input(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, + AO_BOOT_APPLICATION_MODE); + + for (v = 0; v < 100; v++) + ao_arch_nop(); + + /* Read the value */ + v = ao_gpio_get(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, AO_BOOT_APPLICATION); + + /* Reset the chip to turn off the port and the power interface clock */ + ao_gpio_set_mode(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0); + ao_disable_port(AO_BOOT_APPLICATION_GPIO); +// stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN); + if (v == AO_BOOT_APPLICATION_VALUE) + ao_boot_chain(AO_BOOT_APPLICATION_BASE); +} diff --git a/src/lpc/ao_flash.h b/src/lpc/ao_flash.h new file mode 100644 index 00000000..aaf66b39 --- /dev/null +++ b/src/lpc/ao_flash.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FLASH_H_ +#define _AO_FLASH_H_ + +uint32_t +ao_flash_erase_page(uint8_t *page); + +uint32_t +ao_flash_page(uint8_t *page, uint8_t *src); + +uint32_t +ao_lpc_read_part_id(void); + +#endif /* _AO_FLASH_H_ */ diff --git a/src/lpc/ao_flash_loader_lpc.c b/src/lpc/ao_flash_loader_lpc.c new file mode 100644 index 00000000..2ab548cf --- /dev/null +++ b/src/lpc/ao_flash_loader_lpc.c @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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 +#include +#include + +int +main(void) +{ + ao_clock_init(); + + ao_usb_init(); + + ao_flash_task(); + return 0; +} diff --git a/src/lpc/ao_flash_lpc_pins.h b/src/lpc/ao_flash_lpc_pins.h new file mode 100644 index 00000000..e2243d5c --- /dev/null +++ b/src/lpc/ao_flash_lpc_pins.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FLASH_LPC_PINS_H_ +#define _AO_FLASH_LPC_PINS_H_ + +#include + +/* 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 + +#endif /* _AO_FLASH_STM_PINS_H_ */ diff --git a/src/lpc/ao_interrupt.c b/src/lpc/ao_interrupt.c index b5e67007..c4dc7867 100644 --- a/src/lpc/ao_interrupt.c +++ b/src/lpc/ao_interrupt.c @@ -17,12 +17,25 @@ #include #include +#include + +#ifndef IS_FLASH_LOADER +#error Should define IS_FLASH_LOADER +#define IS_FLASH_LOADER 0 +#endif + +#if !IS_FLASH_LOADER +#define RELOCATE_INTERRUPT 1 +#endif 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__; +#if RELOCATE_INTERRUPT +extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__; +#endif /* Interrupt functions */ @@ -35,10 +48,18 @@ void lpc_ignore_isr(void) { } -int x; - void start(void) { - x = 0; +#ifdef AO_BOOT_CHAIN + if (ao_boot_check_chain()) { +#ifdef AO_BOOT_PIN + ao_boot_check_pin(); +#endif + } +#endif +#if RELOCATE_INTERRUPT + memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__); + lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP; +#endif memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__); memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__); main(); diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index c3587698..a889137c 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -42,7 +42,7 @@ static uint8_t spi_dev_null; /* recv a byte */ \ get lpc_ssp->dr; \ } \ - } while (0); + } while (0) void ao_spi_send(void *block, uint16_t len, uint8_t id) diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index 51835baa..44fb410e 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -100,18 +100,33 @@ ao_clock_init(void) (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO) | (1 << LPC_SCB_SYSAHBCLKCTRL_IOCON)); + /* Enable the brown-out detection at the highest voltage to + * make sure the flash part remains happy + */ + + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_BOD_PD); + lpc_scb.bodctrl = ((LPC_SCB_BOD_BODRSTLEV_2_63 << LPC_SCB_BOD_BODRSTLEV) | + (LPC_SCB_BOD_BODINTVAL_RESERVED << LPC_SCB_BOD_BODINTVAL) | + (1 << LPC_SCB_BOD_BODRSTENA)); + /* Turn the IRC clock back on */ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_IRC_PD); ao_clock_delay(); /* Switch to the IRC clock */ lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL; - lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA); lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA))) ; + /* Switch USB to the main clock */ + 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); + while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_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) @@ -177,4 +192,22 @@ ao_clock_init(void) lpc_scb.ssp1clkdiv = 0; lpc_scb.usbclkdiv = 0; lpc_scb.clkoutdiv = 0; + + /* Switch USB PLL source to system osc so we can power down the IRC */ + lpc_scb.usbpllclksel = (LPC_SCB_USBPLLCLKSEL_SEL_SYSOSC << LPC_SCB_USBPLLCLKSEL_SEL); + lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA); + lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); + while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA))) + ; + + /* Power down everything we don't need */ + lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) | + (1 << LPC_SCB_PDRUNCFG_IRC_PD) | + (0 << LPC_SCB_PDRUNCFG_BOD_PD) | + (1 << LPC_SCB_PDRUNCFG_ADC_PD) | + (1 << LPC_SCB_PDRUNCFG_WDTOSC_PD) | + (1 << LPC_SCB_PDRUNCFG_USBPLL_PD) | + (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) | + (1 << 11) | + (7 << 13)); } diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index aac0df04..144d1075 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -19,6 +19,16 @@ #include "ao_usb.h" #include "ao_product.h" +#ifndef USE_USB_STDIO +#define USE_USB_STDIO 1 +#endif + +#if USE_USB_STDIO +#define AO_USB_OUT_SLEEP_ADDR (&ao_stdin_ready) +#else +#define AO_USB_OUT_SLEEP_ADDR (&ao_usb_out_avail) +#endif + #define USB_DEBUG 0 #define USB_DEBUG_DATA 0 #define USB_ECHO 0 @@ -35,8 +45,6 @@ #define debug_data(format, args...) #endif -struct ao_task ao_usb_task; - struct ao_usb_setup { uint8_t dir_type_recip; uint8_t request; @@ -654,7 +662,7 @@ lpc_usb_irq_isr(void) _rx_dbg1("RX ISR", *ao_usb_epn_out(AO_USB_OUT_EP)); ao_usb_out_avail = 1; _rx_dbg0("out avail set"); - ao_wakeup(&ao_stdin_ready); + ao_wakeup(AO_USB_OUT_SLEEP_ADDR) _rx_dbg0("stdin awoken"); } @@ -813,7 +821,7 @@ ao_usb_getchar(void) ao_arch_block_interrupts(); while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN) - ao_sleep(&ao_stdin_ready); + ao_sleep(AO_USB_OUT_SLEEP_ADDR); ao_arch_release_interrupts(); return c; } @@ -823,6 +831,9 @@ ao_usb_disable(void) { ao_arch_block_interrupts(); +#if HAS_USB_PULLUP + ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0); +#endif /* Disable interrupts */ lpc_usb.inten = 0; @@ -834,8 +845,9 @@ ao_usb_disable(void) /* Turn off USB clock */ lpc_scb.usbclkdiv = 0; - /* Disable USB PHY */ - lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_USBPAD_PD); + /* Disable USB PHY and PLL */ + lpc_scb.pdruncfg |= ((1 << LPC_SCB_PDRUNCFG_USBPAD_PD) | + (1 << LPC_SCB_PDRUNCFG_USBPLL_PD)); /* Disable USB registers and RAM */ lpc_scb.sysahbclkctrl &= ~((1 << LPC_SCB_SYSAHBCLKCTRL_USB) | @@ -877,7 +889,6 @@ ao_usb_enable(void) lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD); lpc_scb.usbpllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL); - lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA); lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA))) @@ -887,6 +898,10 @@ ao_usb_enable(void) ; lpc_scb.usbclksel = 0; + lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA); + lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA); + while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA))) + ; /* Turn on USB clock, use 48MHz clock unchanged */ lpc_scb.usbclkdiv = 1; @@ -921,6 +936,10 @@ ao_usb_enable(void) for (t = 0; t < 1000; t++) ao_arch_nop(); +#if HAS_USB_PULLUP + ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 1); +#endif + ao_usb_set_ep0(); } @@ -957,6 +976,10 @@ __code struct ao_cmds ao_usb_cmds[] = { void ao_usb_init(void) { +#if HAS_USB_PULLUP + ao_enable_output(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0); +#endif + ao_usb_enable(); debug ("ao_usb_init\n"); @@ -966,7 +989,7 @@ ao_usb_init(void) #if USB_DEBUG ao_cmd_register(&ao_usb_cmds[0]); #endif -#if !USB_ECHO +#if USE_USB_STDIO ao_add_stdio(_ao_usb_pollchar, ao_usb_putchar, ao_usb_flush); #endif } diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 49034c1c..3300c86f 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -486,6 +486,11 @@ struct lpc_scb { extern struct lpc_scb lpc_scb; +#define LPC_SCB_SYSMEMREMAP_MAP 0 +# define LPC_SCB_SYSMEMREMAP_MAP_BOOT_LOADER 0 +# define LPC_SCB_SYSMEMREMAP_MAP_RAM 1 +# define LPC_SCB_SYSMEMREMAP_MAP_FLASH 2 + #define LPC_SCB_PRESETCTRL_SSP0_RST_N 0 #define LPC_SCB_PRESETCTRL_I2C_RST_N 1 #define LPC_SCB_PRESETCTRL_SSP1_RST_N 2 @@ -609,6 +614,18 @@ extern struct lpc_scb lpc_scb; #define LPC_SCB_CLKOUTUEN_ENA 0 +#define LPC_SCB_BOD_BODRSTLEV 0 +# define LPC_SCB_BOD_BODRSTLEV_1_46 0 +# define LPC_SCB_BOD_BODRSTLEV_2_06 1 +# define LPC_SCB_BOD_BODRSTLEV_2_35 2 +# define LPC_SCB_BOD_BODRSTLEV_2_63 3 +#define LPC_SCB_BOD_BODINTVAL 2 +# define LPC_SCB_BOD_BODINTVAL_RESERVED 0 +# define LPC_SCB_BOD_BODINTVAL_2_22 1 +# define LPC_SCB_BOD_BODINTVAL_2_52 2 +# define LPC_SCB_BOD_BODINTVAL_2_80 3 +#define LPC_SCB_BOD_BODRSTENA 4 + #define LPC_SCB_PDRUNCFG_IRCOUT_PD 0 #define LPC_SCB_PDRUNCFG_IRC_PD 1 #define LPC_SCB_PDRUNCFG_FLASH_PD 2 @@ -1002,12 +1019,12 @@ extern struct lpc_nvic lpc_nvic; static inline void lpc_nvic_set_enable(int irq) { - lpc_nvic.iser |= (1 << irq); + lpc_nvic.iser = (1 << irq); } static inline void lpc_nvic_clear_enable(int irq) { - lpc_nvic.icer |= (1 << irq); + lpc_nvic.icer = (1 << irq); } static inline int @@ -1169,6 +1186,13 @@ extern struct lpc_adc lpc_adc; #define LPC_ADC_CR_CLKS_6 5 #define LPC_ADC_CR_CLKS_5 6 #define LPC_ADC_CR_CLKS_4 7 +#define LPC_ADC_CR_START 24 +#define LPC_ADC_CR_START_NONE 0 +#define LPC_ADC_CR_START_NOW 1 + +#define LPC_ADC_GDR_CHN 24 +#define LPC_ADC_GDR_OVERRUN 30 +#define LPC_ADC_GDR_DONE 31 #define LPC_ADC_INTEN_ADINTEN 0 #define LPC_ADC_INTEN_ADGINTEN 8 diff --git a/src/product/ao_flash_pins.h b/src/product/ao_flash_pins.h index b774df6d..439ba75c 100644 --- a/src/product/ao_flash_pins.h +++ b/src/product/ao_flash_pins.h @@ -37,4 +37,6 @@ #define AO_BOOT_CHAIN 1 #define AO_BOOT_PIN 1 +#define IS_FLASH_LOADER 1 + #endif /* _AO_FLASH_PINS_H_ */ diff --git a/src/product/ao_flash_task.c b/src/product/ao_flash_task.c index fdc4d0aa..4cfbf75f 100644 --- a/src/product/ao_flash_task.c +++ b/src/product/ao_flash_task.c @@ -73,7 +73,7 @@ static void ao_block_erase(void) { uint32_t addr = ao_get_hex32(); - uint32_t *p = (uint32_t *) addr; + void *p = (void *) addr; ao_flash_erase_page(p); } @@ -82,11 +82,8 @@ static void ao_block_write(void) { uint32_t addr = ao_get_hex32(); - uint32_t *p = (uint32_t *) addr; - union { - uint8_t data8[256]; - uint32_t data32[64]; - } u; + void *p = (void *) addr; + uint8_t data[256]; uint16_t i; if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) { @@ -94,8 +91,8 @@ ao_block_write(void) return; } for (i = 0; i < 256; i++) - u.data8[i] = ao_usb_getchar(); - ao_flash_page(p, u.data32); + data[i] = ao_usb_getchar(); + ao_flash_page(p, (void *) data); } static void diff --git a/src/telefire-v0.1/ao_pins.h b/src/telefire-v0.1/ao_pins.h index 774d59f4..f7a3ff2c 100644 --- a/src/telefire-v0.1/ao_pins.h +++ b/src/telefire-v0.1/ao_pins.h @@ -40,13 +40,10 @@ #define AO_LED_CONTINUITY(c) (1 << ((c) + 2)) #define AO_LED_CONTINUITY_MASK (0xc) -#define AO_LED_RX 0x10 -#define AO_LED_TX 0x20 -#define AO_LED_ARMED 0x40 -#define AO_LED_POWER 0x80 - -#define AO_LED_RED AO_LED_TX -#define AO_LED_GREEN AO_LED_RX +#define AO_LED_ARMED 0x10 +#define AO_LED_RED 0x20 +#define AO_LED_AMBER 0x40 +#define AO_LED_GREEN 0x80 #define LEDS_AVAILABLE (0xff) #define HAS_EXTERNAL_TEMP 0 diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index f4050722..96e6b066 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -40,13 +40,10 @@ #define AO_LED_CONTINUITY(c) (1 << (c)) #define AO_LED_CONTINUITY_MASK (0xf) -#define AO_LED_RX 0x10 -#define AO_LED_TX 0x20 -#define AO_LED_ARMED 0x40 -#define AO_LED_POWER 0x80 - -#define AO_LED_RED AO_LED_TX -#define AO_LED_GREEN AO_LED_RX +#define AO_LED_ARMED 0x10 +#define AO_LED_RED 0x20 +#define AO_LED_AMBER 0x40 +#define AO_LED_GREEN 0x80 #define LEDS_AVAILABLE (0xff) #define HAS_EXTERNAL_TEMP 0 diff --git a/src/test/Makefile b/src/test/Makefile index 3c9ac9c6..75b1f848 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -69,7 +69,7 @@ ao_micropeak_test: ao_micropeak_test.c ao_microflight.c ao_kalman.h cc $(CFLAGS) -o $@ ao_micropeak_test.c -lm ao_fat_test: ao_fat_test.c ao_fat.c ao_bufio.c - cc $(CFLAGS) -o $@ ao_fat_test.c -lssl + cc $(CFLAGS) -o $@ ao_fat_test.c -lssl -lcrypto ao_aes_test: ao_aes_test.c ao_aes.c ao_aes_tables.c cc $(CFLAGS) -o $@ ao_aes_test.c