src/telemega-v3.0/telemega-v3.0-$(VERSION).ihx \
src/telemega-v4.0/telemega-v4.0-$(VERSION).ihx \
src/telemetrum-v2.0/telemetrum-v2.0-$(VERSION).ihx \
- src/telemetrum-v3.0/telemetrum-v3.0-$(VERSION).ihx
+ src/telemetrum-v3.0/telemetrum-v3.0-$(VERSION).ihx \
+ src/telelco-v2.0/telelco-v2.0-$(VERSION).ihx \
+ src/telefireeight-v1.0/telefireeight-v1.0-$(VERSION).ihx \
+ src/telefireeight-v2.0/telefireeight-v2.0-$(VERSION).ihx
keithp-fat: fat
ssh keithp.com mkdir -p public_html/altos-$(VERSION)
src/easymega-v2.0/flash-loader/*.elf \
src/easymini-v1.0/flash-loader/*.elf \
src/easymini-v2.0/flash-loader/{*.elf,*.bin,*.map} \
- src/easytimer-v1/flash-loader/{*.elf,*.bin,*.map} \
+ src/easytimer-v1/flash-loader/*.elf \
src/telebt-v3.0/flash-loader/*.elf \
src/telebt-v4.0/flash-loader/{*.elf,*.bin,*.map} \
src/teledongle-v3.0/flash-loader/*.elf \
boolean seen_boost;
int boost_tick;
+ boolean has_call;
boolean has_basic;
+ boolean has_accel;
+ boolean has_baro;
+ boolean has_pyro;
boolean has_radio;
boolean has_battery;
boolean has_flight_state;
- boolean has_advanced;
+ boolean has_3d_accel;
+ boolean has_imu;
boolean has_igniter;
boolean has_gps;
boolean has_gps_sat;
boolean has_companion;
+ boolean has_motor_pressure;
AltosFlightSeries series;
int[] indices;
*/
void write_general_header() {
- out.printf("version,serial,flight,call,time");
+ out.printf("version,serial,flight");
+ if (series.cal_data().callsign != null)
+ out.printf(",call");
+ out.printf(",time");
}
double time() {
}
void write_general() {
- out.printf("%s, %d, %d, %s, %8.2f",
+ out.printf("%s, %d, %d",
ALTOS_CSV_VERSION,
series.cal_data().serial,
- series.cal_data().flight,
- series.cal_data().callsign,
- time());
+ series.cal_data().flight);
+ if (series.cal_data().callsign != null)
+ out.printf(",%s", series.cal_data().callsign);
+ out.printf(", %8.2f", time());
}
void write_radio_header() {
}
void write_basic_header() {
- out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage");
+ if (has_accel)
+ out.printf("acceleration,");
+ if (has_baro)
+ out.printf("pressure,altitude,");
+ out.printf("height,speed");
+ if (has_baro)
+ out.printf(",temperature");
+ if (has_pyro)
+ out.printf(",drogue_voltage,main_voltage");
}
double acceleration() { return series.value(AltosFlightSeries.accel_name, indices); }
double main_voltage() { return series.value(AltosFlightSeries.main_voltage_name, indices); }
void write_basic() {
- out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f",
- acceleration(),
- pressure(),
- altitude(),
- height(),
- speed(),
- speed(),
- temperature(),
- apogee_voltage(),
- main_voltage());
+ if (has_accel)
+ out.printf("%8.2f,", acceleration());
+ if (has_baro)
+ out.printf("%10.2f,%8.2f,",
+ pressure(), altitude());
+ out.printf("%8.2f,%8.2f",
+ height(), speed());
+ if (has_baro)
+ out.printf(",%5.1f", temperature());
+ if (has_pyro)
+ out.printf(",%5.2f,%5.2f",
+ apogee_voltage(),
+ main_voltage());
}
void write_battery_header() {
out.printf("%5.2f", battery_voltage());
}
- void write_advanced_header() {
- out.printf("accel_x,accel_y,accel_z,gyro_roll,gyro_pitch,gyro_yaw,mag_x,mag_y,mag_z,tilt");
+ void write_motor_pressure_header() {
+ out.printf("motor_pressure");
+ }
+
+ double motor_pressure() { return series.value(AltosFlightSeries.motor_pressure_name, indices); }
+
+ void write_motor_pressure() {
+ out.printf("%10.1f", motor_pressure());
+ }
+
+ void write_3d_accel_header() {
+ out.printf("accel_x,accel_y,accel_z");
}
double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); }
double accel_across() { return series.value(AltosFlightSeries.accel_across_name, indices); }
double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); }
+ void write_3d_accel() {
+ out.printf("%7.2f,%7.2f,%7.2f",
+ accel_along(), accel_across(), accel_through());
+ }
+
+ void write_imu_header() {
+ out.printf("gyro_roll,gyro_pitch,gyro_yaw,mag_x,mag_y,mag_z,tilt");
+ }
+
double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); }
double gyro_pitch() { return series.value(AltosFlightSeries.gyro_pitch_name, indices); }
double gyro_yaw() { return series.value(AltosFlightSeries.gyro_yaw_name, indices); }
double tilt() { return series.value(AltosFlightSeries.orient_name, indices); }
- void write_advanced() {
- out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",
- accel_along(), accel_across(), accel_through(),
+ void write_imu() {
+ out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",
gyro_roll(), gyro_pitch(), gyro_yaw(),
mag_along(), mag_across(), mag_through(),
tilt());
out.printf(",");
write_battery_header();
}
- if (has_advanced) {
+ if (has_motor_pressure) {
out.printf(",");
- write_advanced_header();
+ write_motor_pressure_header();
+ }
+ if (has_3d_accel) {
+ out.printf(",");
+ write_3d_accel_header();
}
if (has_igniter) {
out.printf(",");
out.printf(",");
write_battery();
}
- if (has_advanced) {
+ if (has_motor_pressure) {
out.printf(",");
- write_advanced();
+ write_motor_pressure();
+ }
+ if (has_3d_accel) {
+ out.printf(",");
+ write_3d_accel();
+ }
+ if (has_imu) {
+ out.printf(",");
+ write_imu();
}
if (has_igniter) {
out.printf(",");
has_radio = false;
has_flight_state = false;
has_basic = false;
+ has_accel = false;
+ has_baro = false;
+ has_pyro = false;
has_battery = false;
- has_advanced = false;
+ has_motor_pressure = false;
+ has_3d_accel = false;
+ has_imu = false;
has_igniter = false;
has_gps = false;
has_gps_sat = false;
has_radio = true;
if (series.has_series(AltosFlightSeries.state_name))
has_flight_state = true;
- if (series.has_series(AltosFlightSeries.accel_name) || series.has_series(AltosFlightSeries.pressure_name))
+ if (series.has_series(AltosFlightSeries.accel_name)) {
+ has_basic = true;
+ has_accel = true;
+ }
+ if (series.has_series(AltosFlightSeries.pressure_name)) {
has_basic = true;
+ has_baro = true;
+ }
+ if (series.has_series(AltosFlightSeries.apogee_voltage_name))
+ has_pyro = true;
if (series.has_series(AltosFlightSeries.battery_voltage_name))
has_battery = true;
+ if (series.has_series(AltosFlightSeries.motor_pressure_name))
+ has_motor_pressure = true;
if (series.has_series(AltosFlightSeries.accel_across_name))
- has_advanced = true;
+ has_3d_accel = true;
+ if (series.has_series(AltosFlightSeries.gyro_roll_name))
+ has_imu = true;
if (series.has_series(AltosFlightSeries.pyro_voltage_name))
has_igniter = true;
this.ground_accel = ground_accel;
}
+ public double ground_motor_pressure = AltosLib.MISSING;
+
+ public void set_ground_motor_pressure(double ground_motor_pressure) {
+ if (ground_motor_pressure != AltosLib.MISSING)
+ this.ground_motor_pressure = ground_motor_pressure;
+ }
+
/* Raw acceleration value */
public double accel = AltosLib.MISSING;
return AltosIMU.convert_accel(counts - accel_zero_through, imu_type);
}
- public double gyro_zero_roll, gyro_zero_pitch, gyro_zero_yaw;
+ public double gyro_zero_roll = AltosLib.MISSING;
+ public double gyro_zero_pitch = AltosLib.MISSING;
+ public double gyro_zero_yaw = AltosLib.MISSING;
public void set_gyro_zero(double roll, double pitch, double yaw) {
if (roll != AltosLib.MISSING) {
return 3.3 * mega_adc(sensor) * (100.0 + 27.0) / 27.0;
}
- static double easy_mini_2_adc(int raw) {
+ static double easy_mini_2_adc(double raw) {
return raw / 4095.0;
}
- static double easy_mini_1_adc(int raw) {
+ static double easy_mini_1_adc(double raw) {
return raw / 32767.0;
}
return easy_mini_2_adc(sensor) * supply * 127/27;
}
+ static double motor_pressure(double voltage) {
+ double base = 0.5;
+ double max = 4.5;
+ double full_scale_pressure = psi_to_pa(1600);
+
+ if (voltage < base)
+ voltage = base;
+ if (voltage > max)
+ voltage = max;
+ return (voltage - base) / (max - base) * full_scale_pressure;
+ }
+
+ static double easy_motor_2_motor_pressure(int sensor, double ground_sensor) {
+ double supply = 3.3;
+ double ground_voltage = easy_mini_2_adc(ground_sensor) * supply * 15.6 / 10.0;
+ double voltage = easy_mini_2_adc(sensor) * supply * 15.6 / 10.0;
+
+ return motor_pressure(voltage) - motor_pressure(ground_voltage);
+ }
+
public static double radio_to_frequency(int freq, int setting, int cal, int channel) {
double f;
public abstract void set_igniter_voltage(double[] voltage);
public abstract void set_pyro_fired(int pyro_mask);
public abstract void set_companion(AltosCompanion companion);
+ public abstract void set_motor_pressure(double motor_pressure);
public AltosDataListener() {
}
public void set_companion(AltosCompanion companion) { }
public void set_kalman(double height, double speed, double acceleration) { }
public void set_orient(double new_orient) { }
+ public void set_motor_pressure(double motor_pressure) { }
public AltosEepromNameData(AltosCalData cal_data) {
super(cal_data);
--- /dev/null
+/*
+ * Copyright © 2020 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, 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.
+ */
+
+package org.altusmetrum.altoslib_14;
+
+public class AltosEepromRecordMotor extends AltosEepromRecord {
+ public static final int record_length = 16;
+
+ private int log_format;
+
+ /* AO_LOG_FLIGHT elements */
+ private int flight() { return data16(0); }
+ private int ground_accel() { return data16(2); }
+ private int ground_accel_along() { return data16(4); }
+ private int ground_accel_across() { return data16(6); }
+ private int ground_accel_through() { return data16(8); }
+ private int ground_motor_pressure() { return data16(10); }
+
+ /* AO_LOG_STATE elements */
+ private int state() { return data16(0); }
+ private int reason() { return data16(2); }
+
+ /* AO_LOG_SENSOR elements */
+ private int motor_pres() { return data16(0); }
+ private int v_batt() { return data16(2); }
+ private int accel() { return data16(4); }
+ private int accel_across() { return data16(6); }
+ private int accel_along() { return -data16(8); }
+ private int accel_through() { return data16(10); }
+
+ private int imu_type() {
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
+ return AltosIMU.imu_type_easymotor_v2;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
+
+ cal_data.set_imu_type(imu_type());
+
+ switch (cmd()) {
+ case AltosLib.AO_LOG_FLIGHT:
+ cal_data.set_flight(flight());
+ cal_data.set_ground_accel(ground_accel());
+ listener.set_accel_ground(cal_data.accel_along(ground_accel_along()),
+ cal_data.accel_across(ground_accel_across()),
+ cal_data.accel_through(ground_accel_through()));
+ cal_data.set_ground_motor_pressure(ground_motor_pressure());
+ break;
+ case AltosLib.AO_LOG_STATE:
+ listener.set_state(state());
+ break;
+ case AltosLib.AO_LOG_SENSOR:
+ AltosConfigData config_data = eeprom.config_data();
+
+ listener.set_battery_voltage(AltosConvert.easy_mini_2_voltage(v_batt()));
+ double pa = AltosConvert.easy_motor_2_motor_pressure(motor_pres(), cal_data.ground_motor_pressure);
+ listener.set_motor_pressure(pa);
+
+ int accel_along = accel_along();
+ int accel_across = accel_across();
+ int accel_through = accel_through();
+
+ listener.set_accel(cal_data.accel_along(accel_along),
+ cal_data.accel_across(accel_across),
+ cal_data.accel_through(accel_through));
+
+ listener.set_acceleration(cal_data.acceleration(accel()));
+ break;
+ }
+ }
+
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordMotor(eeprom, s);
+ }
+
+ public AltosEepromRecordMotor(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ log_format = eeprom.config_data().log_format;
+ }
+
+ public AltosEepromRecordMotor(AltosEeprom eeprom) {
+ this(eeprom, 0);
+ }
+}
case AltosLib.AO_LOG_FORMAT_MICROPEAK2:
record = new AltosEepromRecordMicroPeak2(eeprom);
break;
+ case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
+ record = new AltosEepromRecordMotor(eeprom);
+ break;
}
ordered = new TreeSet<AltosEepromRecord>();
}
private void compute_height() {
- double ground_altitude = cal_data().ground_altitude;
- if (height_series == null && ground_altitude != AltosLib.MISSING && altitude_series != null) {
- height_series = add_series(height_name, AltosConvert.height);
- for (AltosTimeValue alt : altitude_series)
- height_series.add(alt.time, alt.value - ground_altitude);
+ if (height_series == null) {
+ double ground_altitude = cal_data().ground_altitude;
+ if (ground_altitude != AltosLib.MISSING && altitude_series != null) {
+ height_series = add_series(height_name, AltosConvert.height);
+ for (AltosTimeValue alt : altitude_series)
+ height_series.add(alt.time, alt.value - ground_altitude);
+ } else if (speed_series != null) {
+ height_series = add_series(height_name, AltosConvert.height);
+ speed_series.integrate(height_series);
+ }
}
if (gps_height == null && cal_data().gps_pad != null && cal_data().gps_pad.alt != AltosLib.MISSING && gps_altitude != null) {
else
accel_series.integrate(temp_series);
+ AltosTimeSeries clip_series = make_series(speed_name, AltosConvert.speed);
+
+ temp_series.clip(clip_series, 0, Double.POSITIVE_INFINITY);
+
accel_speed_series = make_series(speed_name, AltosConvert.speed);
- temp_series.filter(accel_speed_series, 0.1);
+ clip_series.filter(accel_speed_series, 0.1);
}
if (alt_speed_series != null && accel_speed_series != null) {
if (cal_data.accel_zero_across == AltosLib.MISSING)
return;
+ if (cal_data.gyro_zero_roll == AltosLib.MISSING)
+ return;
+
AltosRotation rotation = new AltosRotation(accel_ground_across,
accel_ground_through,
accel_ground_along,
public void set_companion(AltosCompanion companion) {
}
+ public static final String motor_pressure_name = "Motor Pressure";
+
+ public AltosTimeSeries motor_pressure_series;
+
+ public void set_motor_pressure(double motor_pressure) {
+ if (motor_pressure_series == null)
+ motor_pressure_series = add_series(motor_pressure_name, AltosConvert.pressure);
+ motor_pressure_series.add(time(), motor_pressure);
+ }
+
public void finish() {
compute_orient();
if (speed_series == null) {
public static final double counts_per_g_mpu = 2048.0;
public static final double counts_per_g_bmx = 2048.0;
+ public static final double counts_per_g_adxl = 20.5;
private static double counts_per_g(int imu_type) {
switch (imu_type) {
case imu_type_telemega_v4:
case imu_type_easytimer_v1:
return counts_per_g_bmx;
+ case imu_type_easymotor_v2:
+ return counts_per_g_adxl;
default:
return AltosLib.MISSING;
}
public static final int imu_type_easytimer_v1 = 5; /* BMX160 */
+ public static final int imu_type_easymotor_v2 = 6; /* ADXL375 (accel only) */
+
private int accel_across(int imu_type) {
switch (imu_type) {
case imu_type_telemega_v1_v2:
case imu_type_telemega_v4:
case imu_type_easytimer_v1:
return -accel_y;
+ case imu_type_easymotor_v2:
+ return accel_y;
default:
return AltosLib.MISSING;
}
case imu_type_telemega_v4:
case imu_type_easytimer_v1:
return accel_x;
+ case imu_type_easymotor_v2:
+ return -accel_x;
default:
return AltosLib.MISSING;
}
cal_data.set_imu_type(imu_type);
if (imu != null) {
- listener.set_gyro(cal_data.gyro_roll(imu.gyro_roll(imu_type)),
- cal_data.gyro_pitch(imu.gyro_pitch(imu_type)),
- cal_data.gyro_yaw(imu.gyro_yaw(imu_type)));
+ if (imu.gyro_x != AltosLib.MISSING) {
+ listener.set_gyro(cal_data.gyro_roll(imu.gyro_roll(imu_type)),
+ cal_data.gyro_pitch(imu.gyro_pitch(imu_type)),
+ cal_data.gyro_yaw(imu.gyro_yaw(imu_type)));
+ }
listener.set_accel_ground(cal_data.accel_along(imu.accel_along(imu_type)),
cal_data.accel_across(imu.accel_across(imu_type)),
cal_data.accel_through(imu.accel_through(imu_type)));
public final static int product_usbtrng = 0x0029;
public final static int product_usbrelay = 0x002a;
public final static int product_mpusb = 0x002b;
+ public final static int product_easymotor = 0x002c;
public final static int product_altusmetrum_min = 0x000a;
public final static int product_altusmetrum_max = 0x002c;
new Product("telegps", product_telegps),
new Product("easymini", product_easymini),
new Product("telemini", product_telemini),
- new Product("easymega", product_easymega)
+ new Product("easymega", product_easymega),
+ new Product("easymotor", product_easymotor)
};
public static int name_to_product(String name) {
public static final int AO_LOG_FORMAT_TELESTATIC = 17;
public static final int AO_LOG_FORMAT_MICROPEAK2 = 18;
public static final int AO_LOG_FORMAT_TELEMEGA_4 = 19;
+ public static final int AO_LOG_FORMAT_EASYMOTOR = 20;
public static final int AO_LOG_FORMAT_NONE = 127;
public static boolean isspace(int c) {
case product_telegps: return "TeleGPS";
case product_easymini: return "EasyMini";
case product_telemini: return "TeleMini";
+ case product_easymotor: return "EasyMotor";
default: return "unknown";
}
}
public double value(double v, boolean imperial_units) {
if (imperial_units)
return AltosConvert.pa_to_psi(v);
- return v;
+ return v / 1000.0;
}
public double inverse(double v, boolean imperial_units) {
if (imperial_units)
return AltosConvert.psi_to_pa(v);
- return v;
+ return v * 1000.0;
}
public String show_units(boolean imperial_units) {
if (imperial_units)
return "psi";
- return "Pa";
+ return "kPa";
}
public String say_units(boolean imperial_units) {
if (imperial_units)
return "p s i";
- return "pascals";
+ return "kilopascals";
}
public int show_fraction(int width, boolean imperial_units) {
- return width / 9;
+ return width / 5;
}
}
public void set_igniter_voltage(double[] voltage) { state.set_igniter_voltage(voltage); }
public void set_pyro_fired(int pyro_mask) { state.set_pyro_fired(pyro_mask); }
public void set_companion(AltosCompanion companion) { state.set_companion(companion); }
+ public void set_motor_pressure(double motor_pressure) { state.set_motor_pressure(motor_pressure); }
public void run () {
/* Run the flight */
public int pyro_fired;
+ public double motor_pressure;
+
public void set_npad(int npad) {
this.npad = npad;
gps_waiting = MIN_PAD_SAMPLES - npad;
this.pyro_fired = fired;
}
+ public void set_motor_pressure(double motor_pressure) {
+ this.motor_pressure = motor_pressure;
+ }
+
public AltosState() {
init();
}
public void set_igniter_voltage(double[] voltage) { }
public void set_pyro_fired(int pyro_mask) { }
public void set_companion(AltosCompanion companion) { }
+ public void set_motor_pressure(double motor_pressure) { }
public boolean cal_data_complete() {
/* All telemetry packets */
}
public void provide_data(AltosDataListener listener) {
- super.provide_data(listener);
AltosCalData cal_data = listener.cal_data();
gps.pdop = pdop() / 10.0;
gps.hdop = hdop() / 10.0;
gps.vdop = vdop() / 10.0;
+ if (gps.connected)
+ super.provide_data(listener);
if (gps.locked) {
gps.lat = latitude() * 1.0e-7;
gps.course = course() * 2;
gps.climb_rate = climb_rate() * 1.0e-2;
}
- listener.set_gps(gps, true, false);
+ if (gps.connected)
+ listener.set_gps(gps, true, false);
}
}
return f;
}
+ public AltosTimeSeries clip(AltosTimeSeries clip, double min, double max) {
+ for (AltosTimeValue v: values) {
+ double value = v.value;
+ if (value < min) value = min;
+ if (value > max) value = max;
+ clip.add(v.time, value);
+ }
+ return clip;
+ }
+
public AltosTimeSeries(String label, AltosUnits units) {
this.label = label;
this.units = units;
AltosEepromRecordGps.java \
AltosEepromRecordFireTwo.java \
AltosEepromRecordMicroPeak2.java \
+ AltosEepromRecordMotor.java \
AltosEepromRecordSet.java \
AltosEepromChunk.java \
AltosEepromDownload.java \
FIRMWARE_TGPS_2_0=$(top_srcdir)/src/telegps-v2.0/telegps-v2.0-$(VERSION).ihx
FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) $(FIRMWARE_TGPS_2_0)
-FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) $(FIRMWARE_EMEGA) $(FIRMWARE_ETIMER)
+FIRMWARE_TLCO_2_0=$(top_srcdir)/src/telelco-v2.0/telelco-v2.0-$(VERSION).ihx
+FIRMWARE_TLCO=$(FIRMWARE_TLCO_2_0)
+
+FIRMWARE_TFIRE8_1_0=$(top_srcdir)/src/telefireeight-v1.0/telefireeight-v1.0-$(VERSION).ihx
+FIRMWARE_TFIRE8_2_0=$(top_srcdir)/src/telefireeight-v2.0/telefireeight-v2.0-$(VERSION).ihx
+FIRMWARE_TFIRE8=$(FIRMWARE_TFIRE8_1_0) $(FIRMWARE_TFIRE8_2_0)
+
+FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) $(FIRMWARE_EMEGA) $(FIRMWARE_ETIMER) $(FIRMWARE_TLCO) $(FIRMWARE_TFIRE8)
ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf
ALTOS_DOC=$(top_srcdir)/doc/altos.pdf
File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx"
File "../src/easymega-v2.0/easymega-v2.0-${VERSION}.ihx"
File "../src/easytimer-v1/easytimer-v1-${VERSION}.ihx"
+ File "../src/telelco-v2.0/telelco-v2.0-${VERSION}.ihx"
+ File "../src/telefireeight-v1.0/telefireeight-v1.0-${VERSION}.ihx"
+ File "../src/telefireeight-v2.0/telefireeight-v2.0-${VERSION}.ihx"
SectionEnd
static final private AltosUILineStyle mag_through_color = new AltosUILineStyle();
static final private AltosUILineStyle mag_total_color = new AltosUILineStyle();
+ static final private AltosUILineStyle motor_pressure_color = new AltosUILineStyle();
+
static AltosUnits dop_units = null;
static AltosUnits tick_units = null;
AltosUIAxis pressure_axis, thrust_axis;
AltosUIAxis gyro_axis, orient_axis, mag_axis;
AltosUIAxis course_axis, dop_axis, tick_axis;
+ AltosUIAxis motor_pressure_axis;
if (stats != null && stats.serial != AltosLib.MISSING && stats.product != null && stats.flight != AltosLib.MISSING)
setName(String.format("%s %d flight %d\n", stats.product, stats.serial, stats.flight));
course_axis = newAxis("Course", AltosConvert.orient, gps_course_color, 0);
dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0);
+ motor_pressure_axis = newAxis("Motor Pressure", AltosConvert.pressure, motor_pressure_color, 0);
+
flight_series.register_axis("default",
speed_color,
false,
voltage_axis);
}
+ flight_series.register_axis(AltosUIFlightSeries.motor_pressure_name,
+ motor_pressure_color,
+ true,
+ motor_pressure_axis);
+
flight_series.check_axes();
return flight_series.series(cal_data);
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.5)
+AC_INIT([altos], 1.9.6)
ANDROID_VERSION=27
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
endif
RELNOTES_INC=\
+ release-notes-1.9.6.inc \
release-notes-1.9.5.inc \
release-notes-1.9.4.inc \
release-notes-1.9.3.inc \
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.6.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.5.adoc[]
--- /dev/null
+= Release Notes for Version 1.9.6
+include::release-head.adoc[]
+:doctype: article
+
+ Version 1.9.6
+
+ == AltOS
+
+ * Fix EasyTimer bug where it might mis-detect boost (either
+ detect it early or not at all) due to small errors in
+ accelerometer calibration leading to large accumulated error
+ in speed.
+
+ * Adjust self-test of new 9-axis IMU (BMX-160) so that it
+ doesn't think the part has a failure when tested sitting
+ horizontally.
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.6.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.5.adoc[]
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.6.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.5.adoc[]
fat: all altos.dll altos64.dll
-altos.dll: $(WINDOWS_SRC) $(WINDOWS_H)
- $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
+#altos.dll: $(WINDOWS_SRC) $(WINDOWS_H)
+# $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
-altos64.dll: $(WINDOWS_SRC) $(WINDOWS_H)
- $(MINGCC64) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
+#altos64.dll: $(WINDOWS_SRC) $(WINDOWS_H)
+# $(MINGCC64) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
clean-local:
- -rm -rf libaltosJNI *.class *.java classlibaltos.stamp $(SWIG_FILE) libaltos_wrap.c altos.dll altos64.dll
+ -rm -rf libaltosJNI *.class *.java classlibaltos.stamp $(SWIG_FILE) libaltos_wrap.c
+# -rm -rf altos.dll altos64.dll
}
static struct {
- char *windows;
- char *real;
+ unsigned int vid, pid;
+ char *name;
} name_map[] = {
- { .windows = "AltusMetrum28", .real = "EasyMega" },
- { .windows = "AltusMetrum2c", .real = "EasyMotor" },
- { 0, 0 },
+ { .vid = 0xfffe, .pid = 0x0028, .name = "EasyMega" },
+ { .vid = 0xfffe, .pid = 0x002c, .name = "EasyMotor" },
+ { .name = NULL },
};
PUBLIC int
altos_set_last_windows_error();
continue;
}
- for (i = 0; name_map[i].windows; i++)
- if (!strcmp(name_map[i].windows, friendlyname)) {
- strcpy(friendlyname, name_map[i].real);
+
+ char *space = friendlyname;
+ while (*space) {
+ if (*space == ' ') {
+ *space = '\0';
break;
}
+ space++;
+ }
- char *space = strchr(friendlyname, ' ');
- if (space)
- *space = '\0';
+ for (i = 0; name_map[i].name; i++) {
+ if (name_map[i].vid == vid && name_map[i].pid == pid) {
+ strcpy(friendlyname, name_map[i].name);
+ break;
+ }
+ }
device->vendor = vid;
device->product = pid;
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx *.bin
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx *.bin $(PROGNAME)-*.map
rm -f ao_product.h
rm -f *.cab
#define MIN_LSB_G 18.4
#define MAX_LSB_G 22.6
-#define SELF_TEST_MIN_G 6.0
+#define SELF_TEST_MIN_G 5.0
#define SELF_TEST_MAX_G 6.8
#define MIN_SELF_TEST ((int32_t) (MIN_LSB_G * SELF_TEST_MIN_G * AO_ADXL375_SELF_TEST_SAMPLES + 0.5))
#define AO_ADXL375_FIFO_STATUS 0x39
+#define ADXL375_ACCEL_FULLSCALE 200
+
struct ao_adxl375_sample {
int16_t x;
int16_t y;
extern struct ao_adxl375_sample ao_adxl375_current;
+#define ao_adxl375_accel_to_sample(accel) ((accel_t) (accel) * (4095.0f / (ADXL375_ACCEL_FULLSCALE * GRAVITY)))
+
void
ao_adxl375_init(void);
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
--- /dev/null
+ao_product.h
+*.elf
--- /dev/null
+#
+# AltOS build
+#
+#
+
+include ../stmf0/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ ao_adxl375.h \
+ stm32f0.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_ignite.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_dma_stm.c \
+ ao_timer.c \
+ ao_exti_stm.c \
+ ao_spi_stm.c \
+ ao_adc_stm.c \
+ ao_usb_stm.c \
+ ao_m25.c \
+ ao_adxl375.c \
+ ao_beep_stm.c
+
+PRODUCT=EasyMotor-v2
+PRODUCT_DEF=-DEASYMOTOR_V_2
+IDPRODUCT=0x002c
+
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS)
+
+PROGNAME=easymotor-v2
+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 © 2020 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 © 2020 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 HAS_TASK_QUEUE 1
+#define IS_FLASH_LOADER 0
+
+/* 48MHz clock based on 32MHz reference */
+#define AO_HSE 32000000
+#define AO_RCC_CFGR_PLLMUL STM_RCC_CFGR_PLLMUL_3
+#define AO_RCC_CFGR2_PLLDIV STM_RCC_CFGR2_PREDIV_2
+#define AO_PLLMUL 3
+#define AO_PLLDIV 2
+
+/* HCLK = 48MHz */
+#define AO_AHB_PRESCALER 1
+#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1
+
+/* APB = 40MHz */
+#define AO_APB_PRESCALER 1
+#define AO_RCC_CFGR_PPRE_DIV STM_RCC_CFGR_PPRE_DIV_1
+
+#define HAS_SERIAL_1 0
+#define USE_SERIAL_1_STDIN 0
+#define SERIAL_1_PB6_PB7 0
+#define SERIAL_1_PA9_PA10 1
+
+#define HAS_SERIAL_2 0
+#define USE_SERIAL_2_STDIN 0
+#define SERIAL_2_PA2_PA3 0
+#define SERIAL_2_PD5_PD6 0
+
+#define HAS_SERIAL_3 0
+#define USE_SERIAL_3_STDIN 0
+#define SERIAL_3_PB10_PB11 1
+#define SERIAL_3_PC10_PC11 0
+#define SERIAL_3_PD8_PD9 0
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (512 * 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 HAS_USB 1
+#define AO_PA11_PA12_RMP 1
+#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
+#define HAS_PAD_REPORT 1
+#define BEEPER_CHANNEL 3
+#define BEEPER_TIMER 2
+#define BEEPER_PORT (&stm_gpioa)
+#define BEEPER_PIN 2
+#define BEEPER_AFR STM_AFR_AF2
+
+#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_ADC_PIN0_PORT (&stm_gpioa) /* pressure */
+#define AO_ADC_PIN0_PIN 0
+#define AO_ADC_PIN0_CH 0
+#define AO_ADC_PIN1_PORT (&stm_gpioa) /* v_batt */
+#define AO_ADC_PIN1_PIN 1
+#define AO_ADC_PIN1_CH 1
+
+#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_IOPAEN))
+
+#define AO_NUM_ADC 2
+
+#define AO_DATA_RING 64
+
+struct ao_adc {
+ int16_t motor_pressure;
+ int16_t v_batt;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5u motor_pressure: %5d batt: %5d\n", \
+ (p)->tick, \
+ (p)->adc.motor_pressure, \
+ (p)->adc.v_batt);
+
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 100 /* 100k */
+#define AO_BATTERY_DIV_MINUS 27 /* 27k */
+
+/*
+ * 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_1 1
+#define SPI_1_PA5_PA6_PA7 1 /* flash */
+#define SPI_1_PB3_PB4_PB5 1 /* adxl375 */
+#define SPI_1_OSPEEDR STM_OSPEEDR_MEDIUM
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS 1
+#define AO_M25_SPI_CS_PORT (&stm_gpioa)
+#define AO_M25_SPI_CS_MASK (1 << 4)
+#define AO_M25_SPI_BUS AO_SPI_1_PA5_PA6_PA7
+
+/* ADXL375 */
+
+#define HAS_ADXL375 1
+#define AO_ADXL375_SPI_INDEX (AO_SPI_1_PB3_PB4_PB5 | AO_SPI_MODE_3)
+#define AO_ADXL375_CS_PORT (&stm_gpiob)
+#define AO_ADXL375_CS_PIN 6
+
+#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-v2
+include $(TOPDIR)/stmf0/Makefile-flash.defs
--- /dev/null
+/*
+ * Copyright © 2020 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_stm_pins.h>
+
+/* pin 9 (PA3) on SOC to gnd for boot mode */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpioa
+#define AO_BOOT_APPLICATION_PIN 3
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+/* USB */
+#define HAS_USB 1
+#define AO_USB_DIRECTIO 0
+#define AO_PA11_PA12_RMP 1
+
+#endif /* _AO_PINS_H_ */
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
{
uint32_t result = 0;
uint8_t r = ao_cmd_lex_error;
+ bool negative = false;
ao_cmd_white();
+ if (ao_cmd_lex_c == '-') {
+ negative = true;
+ ao_cmd_lex();
+ }
for(;;) {
if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
result = result * 10 + (ao_cmd_lex_c - '0');
}
if (r != ao_cmd_success)
ao_cmd_status = r;
+ if (negative)
+ result = -result;
return result;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
+#ifndef AO_FLIGHT_TEST
#include <ao.h>
#include <ao_data.h>
+#endif
volatile struct ao_data ao_data_ring[AO_DATA_RING];
volatile uint8_t ao_data_head;
#endif
#define ao_data_accel_invert(accel) (-(accel))
+#if USE_ADXL375_IMU
+#define ao_data_along(packet) ((packet)->adxl375.AO_ADXL375_AXIS)
+#define ao_data_across(packet) ((packet)->adxl375.AO_ADXL375_ACROSS_AXIS)
+#define ao_data_through(packet) ((packet)->adxl375.z)
+#define ao_data_accel_to_sample(accel) ao_adxl375_accel_to_sample(accel)
+#endif
+
#endif /* HAS_ADXL375 */
#if !HAS_ACCEL && HAS_MPU6000
#define abs(a) ((a) < 0 ? -(a) : (a))
+#if !HAS_BARO
+// #define DEBUG_ACCEL_ONLY 1
+#endif
+
void
ao_flight(void)
{
#if HAS_ACCEL
if (ao_config.accel_plus_g == 0 ||
ao_config.accel_minus_g == 0 ||
- ao_ground_accel < ao_config.accel_plus_g - ACCEL_NOSE_UP ||
- ao_ground_accel > ao_config.accel_minus_g + ACCEL_NOSE_UP
+ ao_ground_accel < (accel_t) ao_config.accel_plus_g - ACCEL_NOSE_UP ||
+ ao_ground_accel > (accel_t) ao_config.accel_minus_g + ACCEL_NOSE_UP
#if HAS_BARO
|| ao_ground_height < -1000 ||
ao_ground_height > 7000
ao_wakeup(&ao_flight_state);
break;
+
+#if DEBUG_ACCEL_ONLY
+ case ao_flight_invalid:
+ case ao_flight_idle:
+ printf("+g %d ga %d sa %d accel %ld speed %ld\n",
+ ao_config.accel_plus_g, ao_ground_accel, ao_sample_accel, ao_accel, ao_speed);
+ break;
+#endif
+
case ao_flight_pad:
/* pad to boost:
*
*/
if (ao_height > AO_M_TO_HEIGHT(20)
#if HAS_ACCEL
- || (ao_accel > AO_MSS_TO_ACCEL(20) &&
- ao_speed > AO_MS_TO_SPEED(5))
+ || (ao_accel > AO_MSS_TO_ACCEL(20)
+ && ao_speed > AO_MS_TO_SPEED(5))
#endif
)
{
#endif /* else FORCE_ACCEL */
#endif /* HAS_ACCEL */
+#if !HAS_BARO
+static ao_k_t ao_k_height_prev;
+static ao_k_t ao_k_speed_prev;
+
+/*
+ * While in pad mode without a barometric sensor, remove accumulated
+ * speed and height values to reduce the effect of systematic sensor
+ * error
+ */
+void
+ao_kalman_reset_accumulate(void)
+{
+ ao_k_height -= ao_k_height_prev;
+ ao_k_speed -= ao_k_speed_prev;
+ ao_k_height_prev = ao_k_height;
+ ao_k_speed_prev = ao_k_speed;
+}
+#endif
+
void
ao_kalman(void)
{
#define AO_LOG_FORMAT_TELESTATIC 17 /* 32 byte typed telestatic records */
#define AO_LOG_FORMAT_MICROPEAK2 18 /* 2-byte baro values with header */
#define AO_LOG_FORMAT_TELEMEGA_4 19 /* 32 byte typed telemega records with 32 bit gyro cal and Bmx160 */
+#define AO_LOG_FORMAT_EASYMOTOR 20 /* ? byte typed easymotor records with pressure sensor and adxl375 */
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
/* Return the flight number from the given log slot, 0 if none, -slot on failure */
} u;
};
+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;
+};
+
#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_4
typedef struct ao_log_mega ao_log_type;
#endif
typedef struct ao_log_mini ao_log_type;
#endif
+#if AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMOTOR
+typedef struct ao_log_motor ao_log_type;
+#endif
+
#if AO_LOG_FORMAT == AO_LOG_FORMAT_TELEGPS
typedef struct ao_log_gps ao_log_type;
#endif
--- /dev/null
+/*
+ * Copyright © 2020 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_log.h>
+#include <ao_data.h>
+#include <ao_flight.h>
+
+#if HAS_FLIGHT
+static uint8_t ao_log_data_pos;
+
+/* a hack to make sure that ao_log_megas fill the eeprom block in even units */
+typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_mega))] ;
+
+#ifndef AO_SENSOR_INTERVAL_ASCENT
+#define AO_SENSOR_INTERVAL_ASCENT 1
+#define AO_SENSOR_INTERVAL_DESCENT 10
+#define AO_OTHER_INTERVAL 32
+#endif
+
+void
+ao_log(void)
+{
+ uint16_t next_sensor;
+
+ ao_storage_setup();
+
+ ao_log_scan();
+
+ while (!ao_log_running)
+ ao_sleep(&ao_log_running);
+
+ ao_log_data.type = AO_LOG_FLIGHT;
+ ao_log_data.tick = ao_sample_tick;
+ ao_log_data.u.flight.ground_accel = ao_ground_accel;
+ ao_log_data.u.flight.ground_accel_along = ao_ground_accel_along;
+ ao_log_data.u.flight.ground_accel_through = ao_ground_accel_through;
+ ao_log_data.u.flight.ground_motor_pressure = ao_ground_motor_pressure;
+ ao_log_data.u.flight.flight = ao_flight_number;
+ ao_log_write(&ao_log_data);
+
+ /* Write the whole contents of the ring to the log
+ * when starting up.
+ */
+ ao_log_data_pos = ao_data_ring_next(ao_data_head);
+ next_sensor = ao_data_ring[ao_log_data_pos].tick;
+ ao_log_state = ao_flight_startup;
+ for (;;) {
+ /* Write samples to EEPROM */
+ while (ao_log_data_pos != ao_data_head) {
+ ao_log_data.tick = ao_data_ring[ao_log_data_pos].tick;
+ if ((int16_t) (ao_log_data.tick - next_sensor) >= 0) {
+ ao_log_data.type = AO_LOG_SENSOR;
+ ao_log_data.u.sensor.pressure = ao_data_motor_pressure(&ao_data_ring[ao_log_data_pos]);
+ ao_log_data.u.sensor.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
+ ao_log_data.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
+ ao_log_data.u.sensor.accel_across = ao_data_across(&ao_data_ring[ao_log_data_pos]);
+ ao_log_data.u.sensor.accel_along = ao_data_along(&ao_data_ring[ao_log_data_pos]);
+ ao_log_data.u.sensor.accel_through = ao_data_through(&ao_data_ring[ao_log_data_pos]);
+ ao_log_write(&ao_log_data);
+ if (ao_log_state <= ao_flight_coast)
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_ASCENT;
+ else
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_DESCENT;
+ }
+ ao_log_data_pos = ao_data_ring_next(ao_log_data_pos);
+ }
+#if HAS_FLIGHT
+ /* Write state change to EEPROM */
+ if (ao_flight_state != ao_log_state) {
+ ao_log_state = ao_flight_state;
+ ao_log_data.type = AO_LOG_STATE;
+ ao_log_data.tick = ao_time();
+ ao_log_data.u.state.state = ao_log_state;
+ ao_log_data.u.state.reason = 0;
+ ao_log_write(&ao_log_data);
+
+ if (ao_log_state == ao_flight_landed)
+ ao_log_stop();
+ }
+#endif
+
+ ao_log_flush();
+
+ /* Wait for a while */
+ ao_delay(AO_MS_TO_TICKS(100));
+
+ /* Stop logging when told to */
+ while (!ao_log_running)
+ ao_sleep(&ao_log_running);
+ }
+}
+#endif /* HAS_FLIGHT */
+
while (c-- && ao_flight_state == ao_flight_pad)
pause(AO_MS_TO_TICKS(100));
}
+#endif
+#if HAS_PAD_REPORT
+ while (ao_flight_state == ao_flight_pad) {
+ uint8_t c;
+ ao_report_flight_state();
+ c = 50;
+ while (c-- && ao_flight_state == ao_flight_pad)
+ pause(AO_MS_TO_TICKS(100));
+ }
#endif
while (ao_report_state == ao_flight_state)
ao_sleep(&ao_flight_state);
#if HAS_ACCEL
accel_t ao_sample_accel;
#endif
-#if HAS_GYRO
+#if HAS_IMU
accel_t ao_sample_accel_along;
accel_t ao_sample_accel_across;
accel_t ao_sample_accel_through;
+#endif
+#if HAS_GYRO
gyro_t ao_sample_roll;
gyro_t ao_sample_pitch;
gyro_t ao_sample_yaw;
angle_t ao_sample_orients[AO_NUM_ORIENT];
uint8_t ao_sample_orient_pos;
#endif
+#ifdef HAS_MOTOR_PRESSURE
+motor_pressure_t ao_sample_motor_pressure;
+#endif
uint8_t ao_sample_data;
int32_t ao_accel_scale; /* sensor to m/s² conversion */
#endif
-#if HAS_GYRO
+#if HAS_IMU
accel_t ao_ground_accel_along;
accel_t ao_ground_accel_across;
accel_t ao_ground_accel_through;
+#endif
+
+#if HAS_GYRO
int32_t ao_ground_pitch;
int32_t ao_ground_yaw;
int32_t ao_ground_roll;
#endif
+#if HAS_MOTOR_PRESSURE
+motor_pressure_t ao_ground_motor_pressure;
+#endif
+
static uint8_t ao_preflight; /* in preflight mode */
static uint16_t nsamples;
#if HAS_ACCEL
int32_t ao_sample_accel_sum;
#endif
-#if HAS_GYRO
+#if HAS_IMU
int32_t ao_sample_accel_along_sum;
int32_t ao_sample_accel_across_sum;
int32_t ao_sample_accel_through_sum;
+#endif
+#if HAS_GYRO
int32_t ao_sample_pitch_sum;
int32_t ao_sample_yaw_sum;
int32_t ao_sample_roll_sum;
static struct ao_quaternion ao_rotation;
#endif
+#if HAS_MOTOR_PRESSURE
+int32_t ao_sample_motor_pressure_sum;
+#endif
#if HAS_FLIGHT_DEBUG
extern uint8_t ao_orient_test;
#if HAS_BARO
ao_sample_pres_sum += ao_sample_pres;
#endif
-#if HAS_GYRO
+#if HAS_IMU
ao_sample_accel_along_sum += ao_sample_accel_along;
ao_sample_accel_across_sum += ao_sample_accel_across;
ao_sample_accel_through_sum += ao_sample_accel_through;
+#endif
+#if HAS_GYRO
ao_sample_pitch_sum += ao_sample_pitch;
ao_sample_yaw_sum += ao_sample_yaw;
ao_sample_roll_sum += ao_sample_roll;
+#endif
+#if HAS_MOTOR_PRESSURE
+ ao_sample_motor_pressure_sum += ao_sample_motor_pressure;
#endif
++nsamples;
}
ao_ground_height = pres_to_altitude(ao_ground_pres);
ao_sample_pres_sum = 0;
#endif
-#if HAS_GYRO
+#if HAS_IMU
ao_ground_accel_along = ao_sample_accel_along_sum >> 9;
ao_ground_accel_across = ao_sample_accel_across_sum >> 9;
ao_ground_accel_through = ao_sample_accel_through_sum >> 9;
- ao_ground_pitch = ao_sample_pitch_sum;
- ao_ground_yaw = ao_sample_yaw_sum;
- ao_ground_roll = ao_sample_roll_sum;
ao_sample_accel_along_sum = 0;
ao_sample_accel_across_sum = 0;
ao_sample_accel_through_sum = 0;
+#endif
+#if HAS_MOTOR_PRESSURE
+ ao_ground_motor_pressure = ao_sample_motor_pressure_sum >> 9;
+ ao_sample_motor_pressure_sum = 0;
+#endif
+#if HAS_GYRO
+ ao_ground_pitch = ao_sample_pitch_sum;
+ ao_ground_yaw = ao_sample_yaw_sum;
+ ao_ground_roll = ao_sample_roll_sum;
ao_sample_pitch_sum = 0;
ao_sample_yaw_sum = 0;
ao_sample_roll_sum = 0;
(ao_ground_accel_across - ao_config.accel_zero_across),
(ao_ground_accel_through - ao_config.accel_zero_through),
(ao_ground_accel_along - ao_config.accel_zero_along));
-#endif
+#endif
ao_sample_compute_orient();
ao_sample_set_all_orients();
++nsamples;
else
ao_sample_preflight_set();
+#if !HAS_BARO
+ if ((nsamples & 0x3f) == 0)
+ ao_kalman_reset_accumulate();
+#endif
}
#if 0
#if HAS_ACCEL
ao_sample_accel = ao_data_accel(ao_data);
#endif
-#if HAS_GYRO
+#if HAS_IMU
ao_sample_accel_along = ao_data_along(ao_data);
ao_sample_accel_across = ao_data_across(ao_data);
ao_sample_accel_through = ao_data_through(ao_data);
+#endif
+#if HAS_GYRO
ao_sample_pitch = ao_data_pitch(ao_data);
ao_sample_yaw = ao_data_yaw(ao_data);
ao_sample_roll = ao_data_roll(ao_data);
#endif
+#if HAS_MOTOR_PRESSURE
+ ao_sample_motor_pressure = ao_data_motor_pressure(ao_data);
+#endif
if (ao_preflight)
ao_sample_preflight();
ao_sample_accel_sum = 0;
ao_sample_accel = 0;
#endif
-#if HAS_GYRO
+#if HAS_IMU
ao_sample_accel_along_sum = 0;
ao_sample_accel_across_sum = 0;
ao_sample_accel_through_sum = 0;
ao_sample_accel_along = 0;
ao_sample_accel_across = 0;
ao_sample_accel_through = 0;
+#endif
+#if HAS_GYRO
ao_sample_pitch_sum = 0;
ao_sample_yaw_sum = 0;
ao_sample_roll_sum = 0;
extern accel_t ao_accel_2g; /* factory accel calibration */
extern int32_t ao_accel_scale; /* sensor to m/s² conversion */
#endif
-#if HAS_GYRO
+#if HAS_IMU
extern accel_t ao_ground_accel_along;
extern accel_t ao_ground_accel_across;
extern accel_t ao_ground_accel_through;
-extern int32_t ao_ground_pitch; /* * 512 */
-extern int32_t ao_ground_yaw; /* * 512 */
-extern int32_t ao_ground_roll; /* * 512 */
extern accel_t ao_sample_accel_along;
extern accel_t ao_sample_accel_across;
extern accel_t ao_sample_accel_through;
+#endif
+#if HAS_GYRO
+#ifndef HAS_IMU
+#define HAS_IMU 1
+#endif
+extern int32_t ao_ground_pitch; /* * 512 */
+extern int32_t ao_ground_yaw; /* * 512 */
+extern int32_t ao_ground_roll; /* * 512 */
extern gyro_t ao_sample_roll;
extern gyro_t ao_sample_pitch;
extern gyro_t ao_sample_yaw;
extern angle_t ao_sample_orients[AO_NUM_ORIENT];
extern uint8_t ao_sample_orient_pos;
#endif
+#if HAS_MOTOR_PRESSURE
+extern motor_pressure_t ao_ground_motor_pressure;
+extern motor_pressure_t ao_sample_motor_pressure;
+#endif
void ao_sample_init(void);
void ao_kalman(void);
+#if !HAS_BARO
+void ao_kalman_reset_accumulate(void);
+#endif
+
#endif /* _AO_SAMPLE_H_ */
LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos-loader.ld
-PROGNAME=altos-flash
-PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
+PROGNAME=$(HARDWARE)-altos-flash
+PROG=$(PROGNAME)-$(VERSION).elf
$(PROG): Makefile $(OBJ) altos-loader.ld
$(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
distclean: clean
clean:
- rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o *.elf *.ihx $(SCRIPT)
+ rm -f *.o *.elf *.ihx $(SCRIPT) *.map
rm -f ao_product.h
publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT)
distclean: clean
clean:
- rm -f *.o *.elf *.ihx
+ rm -f *.o *.elf *.ihx *.map
rm -f ao_product.h
publish: $(PUBLISH_HEX)
distclean: clean
clean:
- rm -f *.o *.elf *.ihx $(SCRIPT)
+ rm -f *.o *.elf *.ihx *.map $(SCRIPT)
rm -f ao_product.h
publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT)
distclean: clean
clean:
- rm -f *.o *.elf *.ihx $(SCRIPT)
+ rm -f *.o *.elf *.ihx *.map $(SCRIPT)
rm -f ao_product.h
publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT)
LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stm -Taltos-loader.ld -n
-PROGNAME=altos-flash
-PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
+PROGNAME=$(HARDWARE)-altos-flash
+PROG=$(PROGNAME)-$(VERSION).elf
$(PROG): Makefile $(OBJ) altos-loader.ld
$(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
distclean: clean
clean:
- rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.map
rm -f ao_product.h
install:
LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm32f4 -Wl,-Taltos-loader.ld
-PROGNAME=altos-flash
-PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
-BIN=$(HARDWARE)-$(PROGNAME)-$(VERSION).bin
+PROGNAME=$(HARDWARE)-altos-flash
+PROG=$(PROGNAME)-$(VERSION).elf
+BIN=$(PROGNAME)-$(VERSION).bin
MAKEBIN=$(TOPDIR)/../ao-tools/ao-makebin/ao-makebin
FLASH_ADDR=0x08000000
distclean: clean
clean:
- rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf $(HARDWARE)-$(PROGNAME)-*.bin
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.bin $(PROGNAME)-*.map
rm -f ao_product.h
install:
LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm -Wl,-Taltos-loader.ld -n
-PROGNAME=altos-flash
-PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
+PROGNAME=$(HARDWARE)-altos-flash
+PROG=$(PROGNAME)-$(VERSION).elf
$(PROG): Makefile $(OBJ) altos-loader.ld
$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
distclean: clean
clean:
- rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.map
rm -f ao_product.h
install:
LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stmf0 -Taltos-loader.ld
-PROGNAME=altos-flash
-PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
-BIN=$(HARDWARE)-$(PROGNAME)-$(VERSION).bin
+PROGNAME=$(HARDWARE)-altos-flash
+PROG=$(PROGNAME)-$(VERSION).elf
+BIN=$(PROGNAME)-$(VERSION).bin
MAKEBIN=$(TOPDIR)/../ao-tools/ao-makebin/ao-makebin
FLASH_ADDR=0x08000000
distclean: clean
clean:
- rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf $(HARDWARE)-$(PROGNAME)-*.bin
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.bin $(PROGNAME)-*.map
rm -f ao_product.h
install:
#define AO_SPI_INDEX(id) ((id) & AO_SPI_INDEX_MASK)
#define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK)
+#define AO_SPI_PIN_CONFIG(id) ((id) & (AO_SPI_INDEX_MASK | AO_SPI_CONFIG_MASK))
+
+#define AO_SPI_CPOL_BIT 4
+#define AO_SPI_CPHA_BIT 5
+#define AO_SPI_CPOL(id) ((uint32_t) (((id) >> AO_SPI_CPOL_BIT) & 1))
+#define AO_SPI_CPHA(id) ((uint32_t) (((id) >> AO_SPI_CPHA_BIT) & 1))
+
+#define AO_SPI_MAKE_MODE(pol,pha) (((pol) << AO_SPI_CPOL_BIT) | ((pha) << AO_SPI_CPHA_BIT))
+#define AO_SPI_MODE_0 AO_SPI_MAKE_MODE(0,0)
+#define AO_SPI_MODE_1 AO_SPI_MAKE_MODE(0,1)
+#define AO_SPI_MODE_2 AO_SPI_MAKE_MODE(1,0)
+#define AO_SPI_MODE_3 AO_SPI_MAKE_MODE(1,1)
uint8_t
ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id);
};
static uint8_t ao_spi_mutex[STM_NUM_SPI];
-static uint8_t ao_spi_index[STM_NUM_SPI];
+static uint8_t ao_spi_pin_config[STM_NUM_SPI];
static const struct ao_spi_stm_info ao_spi_stm_info[STM_NUM_SPI] = {
{
}
static void
-ao_spi_disable_index(uint8_t spi_index)
+ao_spi_disable_pin_config(uint8_t spi_pin_config)
{
- /* Disable current config
+ /* disable config
*/
- switch (spi_index) {
+ switch (spi_pin_config) {
case AO_SPI_1_PA5_PA6_PA7:
stm_gpio_set(&stm_gpioa, 5, 1);
stm_moder_set(&stm_gpioa, 5, STM_MODER_OUTPUT);
}
static void
-ao_spi_enable_index(uint8_t spi_index)
+ao_spi_enable_pin_config(uint8_t spi_pin_config)
{
- switch (spi_index) {
+ /* Disable current config
+ */
+ switch (spi_pin_config) {
case AO_SPI_1_PA5_PA6_PA7:
stm_afr_set(&stm_gpioa, 5, STM_AFR_AF0);
stm_afr_set(&stm_gpioa, 6, STM_AFR_AF0);
static void
ao_spi_config(uint8_t spi_index, uint32_t speed)
{
+ uint8_t spi_pin_config = AO_SPI_PIN_CONFIG(spi_index);
uint8_t id = AO_SPI_INDEX(spi_index);
struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi;
break;
#endif
}
- if (spi_index != ao_spi_index[id]) {
+ if (spi_pin_config != ao_spi_pin_config[id]) {
/* Disable old config
*/
- ao_spi_disable_index(ao_spi_index[id]);
+ ao_spi_disable_pin_config(ao_spi_pin_config[id]);
/* Enable new config
*/
- ao_spi_enable_index(spi_index);
+ ao_spi_enable_pin_config(spi_pin_config);
/* Remember current config
*/
- ao_spi_index[id] = spi_index;
+ ao_spi_pin_config[id] = spi_pin_config;
}
stm_spi->cr2 = SPI_CR2;
stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */
(1 << STM_SPI_CR1_SPE) | /* Enable SPI unit */
(speed << STM_SPI_CR1_BR) | /* baud rate to pclk/4 */
(1 << STM_SPI_CR1_MSTR) |
- (0 << STM_SPI_CR1_CPOL) | /* Format 0 */
- (0 << STM_SPI_CR1_CPHA));
+ (AO_SPI_CPOL(spi_index) << STM_SPI_CR1_CPOL) | /* Format */
+ (AO_SPI_CPHA(spi_index) << STM_SPI_CR1_CPHA));
}
uint8_t
uint8_t id = AO_SPI_INDEX(spi_index);
struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi;
- ao_spi_disable_index(spi_index);
+ ao_spi_disable_pin_config(AO_SPI_PIN_CONFIG(spi_index));
stm_spi->cr1 = 0;
stm_spi->cr2 = SPI_CR2_SYNC;
stm_ospeedr_set(&stm_gpiob, 5, SPI_1_OSPEEDR);
# endif
stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN);
- ao_spi_index[0] = AO_SPI_CONFIG_NONE;
+ ao_spi_pin_config[0] = AO_SPI_CONFIG_NONE;
ao_spi_channel_init(STM_SPI_INDEX(1));
#endif
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME).map
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o ao_serial_stm.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o ao_serial_stm.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
rm -f ao_product.h
install:
ao_flight_test_noisy_accel
ao_flight_test_metrum
ao_flight_test_mini
+ao_flight_test_motor
ao_micropeak_test
ao_aes_test
ao_lisp_test
INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h ao_quaternion.h ao_eeprom_read.h
TEST_SRC=ao_flight_test.c
-TEST_SRC_ALL=ao_flight_test.c ao_eeprom_read.c ao_eeprom_read_old.c
+TEST_SRC_ALL=ao_flight_test.c ao_eeprom_read.c ao_eeprom_read_old.c ao_data.c
TEST_LIB=-ljson-c
KALMAN=make-kalman
ao_flight_test_mini: $(TEST_SRC_ALL) ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
cc -DEASYMINI=1 -DHAS_ACCEL=0 $(CFLAGS) -o $@ $(TEST_SRC) $(TEST_LIB) -lm
+ao_flight_test_motor: $(TEST_SRC_ALL) ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
+ cc -DEASYMOTOR_V_2=1 $(CFLAGS) -o $@ $(TEST_SRC) $(TEST_LIB) -lm
+
ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h
cc $(CFLAGS) -o $@ $<
#define _GNU_SOURCE
#include <stdint.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
int ao_gps_new;
-#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI)
+#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI) && !defined(EASYMOTOR_V_2)
#define TELEMETRUM_V1 1
#endif
#define HAS_MMA655X 1
#define HAS_HMC5883 1
#define HAS_BEEP 1
+#define HAS_BARO 1
#define AO_CONFIG_MAX_SIZE 1024
#define AO_MMA655X_INVERT 0
#define HAS_MMA655X 1
#define AO_MMA655X_INVERT 0
#define HAS_BEEP 1
+#define HAS_BARO 1
#define AO_CONFIG_MAX_SIZE 1024
struct ao_adc {
#define HAS_ACCEL 1
#define HAS_ACCEL_REF 0
#endif
+#define HAS_BARO 1
+
+#endif
+
+#if EASYMOTOR_V_2
+#define AO_ADC_NUM_SENSE 0
+#define HAS_ADXL375 1
+#define HAS_BEEP 1
+#define AO_CONFIG_MAX_SIZE 1024
+#define USE_ADXL375_IMU 1
+#define AO_ADXL375_INVERT 0
+#define HAS_IMU 1
+#define AO_ADXL375_AXIS x
+#define AO_ADXL375_ACROSS_AXIS y
+#define AO_ADXL375_THROUGH_AXIS z
+
+struct ao_adc {
+ int16_t pressure;
+ int16_t v_batt;
+};
#endif
extern uint16_t ao_sample_tick;
+#if HAS_BARO
extern alt_t ao_sample_height;
+#endif
extern accel_t ao_sample_accel;
extern int32_t ao_accel_scale;
+#if HAS_BARO
extern alt_t ao_ground_height;
extern alt_t ao_sample_alt;
+#endif
double ao_sample_qangle;
#include "ao_sqrt.c"
#include "ao_sample.c"
#include "ao_flight.c"
+#include "ao_data.c"
#if TELEMEGA
#define AO_PYRO_NUM 4
prev_tick = ao_data_static.tick;
time = (double) (ao_data_static.tick + tick_offset) / 100;
+ double height = 0;
+#if HAS_BARO
#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked);
- double height = ao_pa_to_altitude(ao_data_static.ms5607_cooked.pres) - ao_ground_height;
+ height = ao_pa_to_altitude(ao_data_static.ms5607_cooked.pres) - ao_ground_height;
/* Hack to skip baro spike at accidental drogue charge
* firing in 2015-09-26-serial-2093-flight-0012.eeprom
}
}
#else
- double height = ao_pres_to_altitude(ao_data_static.adc.pres_real) - ao_ground_height;
+ height = ao_pres_to_altitude(ao_data_static.adc.pres_real) - ao_ground_height;
+#endif
#endif
if (ao_test_max_height < height) {
#if TELEMETRUM_V1
ao_data_static.adc.accel = ao_flight_ground_accel;
#endif
+#if EASYMOTOR_V_2
+ ao_data_static.adxl375.AO_ADXL375_AXIS = ao_flight_ground_accel;
+#endif
ao_insert();
return;
}
if (eeprom) {
-#if TELEMEGA
+#if TELEMEGA || EASYMOTOR_V_2
struct ao_log_mega *log_mega;
#endif
+#if EASYMOTOR_V_2
+ struct ao_log_motor *log_motor;
+#endif
#if TELEMETRUM_V2
struct ao_log_metrum *log_metrum;
#endif
break;
}
break;
+#endif
+#if EASYMOTOR_V_2
+ case AO_LOG_FORMAT_TELEMEGA_3:
+ log_mega = (struct ao_log_mega *) &eeprom->data[eeprom_offset];
+ eeprom_offset += sizeof (*log_mega);
+ switch (log_mega->type) {
+ case AO_LOG_FLIGHT:
+ ao_flight_number = log_mega->u.flight.flight;
+ ao_flight_ground_accel = log_mega->u.flight.ground_accel;
+ ao_flight_started = 1;
+ break;
+ case AO_LOG_SENSOR:
+ ao_data_static.tick = log_mega->tick;
+ ao_data_static.adxl375.AO_ADXL375_AXIS = -log_mega->u.sensor.accel;
+ ao_records_read++;
+ ao_insert();
+ return;
+ }
+ break;
+ case AO_LOG_FORMAT_TELEMEGA_4:
+ log_mega = (struct ao_log_mega *) &eeprom->data[eeprom_offset];
+ eeprom_offset += sizeof (*log_mega);
+ switch (log_mega->type) {
+ case AO_LOG_FLIGHT:
+ ao_flight_number = log_mega->u.flight.flight;
+ ao_flight_ground_accel = log_mega->u.flight.ground_accel;
+ ao_flight_started = 1;
+ break;
+ case AO_LOG_SENSOR:
+ ao_data_static.tick = log_mega->tick;
+ ao_data_static.adxl375.AO_ADXL375_AXIS = log_mega->u.sensor.accel;
+ ao_records_read++;
+ ao_insert();
+ return;
+ }
+ break;
+ case AO_LOG_FORMAT_EASYMOTOR:
+ log_motor = (struct ao_log_motor *) &eeprom->data[eeprom_offset];
+ eeprom_offset += sizeof (*log_motor);
+ switch (log_motor->type) {
+ case AO_LOG_FLIGHT:
+ ao_flight_number = log_motor->u.flight.flight;
+ ao_flight_ground_accel = log_motor->u.flight.ground_accel;
+ ao_flight_started = 1;
+ break;
+ case AO_LOG_SENSOR:
+ ao_data_static.tick = log_motor->tick;
+ ao_data_static.adc.pressure = log_motor->u.sensor.pressure;
+ ao_data_static.adc.v_batt = log_motor->u.sensor.v_batt;
+ ao_data_static.adxl375.AO_ADXL375_AXIS = log_motor->u.sensor.accel_along;
+ ao_data_static.adxl375.AO_ADXL375_ACROSS_AXIS = log_motor->u.sensor.accel_across;
+ ao_data_static.adxl375.AO_ADXL375_THROUGH_AXIS = log_motor->u.sensor.accel_through;
+ ao_records_read++;
+ ao_insert();
+ return;
+ }
+ break;
#endif
default:
printf ("invalid log format %d\n", log_format);