- update the version and date in configure.ac if Bdale hasn't already
+ - update the ANDROID_VERSION in configure.ac if releasing AltosDroid
+
- follow instructions in doc/RELNOTES
- make sure there is a doc/release-notes-<version>.inc
- confirm doc/header.inc has correct copyright year
+
These are Bdale's notes on how to do a release.
- make sure Debian build environment is up to date
- ensure i386 build support is available, and we have tools to build
installers for Windows and Mac OS X
- sudo dpkg --add-architecture i386
sudo apt update
- sudo apt install gcc-multilib genisoimage nsis
- (need some mingw packages too, but not sure which offhand)
+ sudo apt install genisoimage nsis \
+ gcc-i686-linux-gnu gcc-aarch64-linux-gnu \
+ gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf
- make sure ~/web/altusmetrum has no pending pullable commits
- store a stable copy of ARM binaries for production use
cp src/chaoskey-v1.0/{*.elf,*.ihx,*.bin,*.map} \
- src/easymega-v1.0/{*.elf,*.ihx,*.map} \
- src/easymega-v2.0/{*.elf,*.ihx,*.map} \
- src/easymini-v1.0/{*.elf,*.ihx,*.map} \
- src/easymini-v2.0/{*.elf,*.ihx,*.map} \
+ src/easymega-v[1-2].0/{*.elf,*.ihx,*.map} \
+ src/easymini-v[1-2].0/{*.elf,*.ihx,*.map} \
src/easymotor-v2/{*.elf,*.ihx,*.map} \
src/easytimer-v1/{*.elf,*.ihx,*.map} \
- src/telebt-v3.0/{*.elf,*.ihx,*.map} \
- src/telebt-v4.0/{*.elf,*.ihx,*.map} \
+ src/telebt-v[3-4].0/{*.elf,*.ihx,*.map} \
src/teledongle-v3.0/{*.elf,*.ihx,*.map} \
- src/telegps-v1.0/{*.elf,*.ihx,*.map} \
- src/telegps-v2.0/{*.elf,*.ihx,*.map} \
+ src/telegps-v[1-2].0/{*.elf,*.ihx,*.map} \
src/telemega-v[1-5].0/{*.elf,*.ihx,*.map} \
- src/telemetrum-v2.0/{*.elf,*.ihx,*.map} \
- src/telemetrum-v3.0/{*.elf,*.ihx,*.map} \
+ src/telemetrum-v[2-3].0/{*.elf,*.ihx,*.map} \
src/telemini-v3.0/{*.elf,*.ihx,*.map} \
src/telelco-v2.0/{*.elf,*.ihx,*.map} \
- src/telefireeight-v1.0/{*.elf,*.ihx,*.map} \
- src/telefireeight-v2.0/{*.elf,*.ihx,*.map} \
+ src/telefireeight-v[1-2].0/{*.elf,*.ihx,*.map} \
~/altusmetrumllc/Binaries/
cp src/chaoskey-v1.0/flash-loader/{*.elf,*.bin,*.map} \
- src/easymega-v1.0/flash-loader/*.elf \
- src/easymega-v2.0/flash-loader/*.elf \
- src/easymini-v1.0/flash-loader/*.elf \
- src/easymini-v2.0/flash-loader/{*.elf,*.bin,*.map} \
+ src/easymega-v[1-2].0/flash-loader/*.elf \
+ src/easymini-v[1-2].0/flash-loader/*.elf \
src/easymotor-v2/flash-loader/*.elf \
src/easytimer-v1/flash-loader/*.elf \
- src/telebt-v3.0/flash-loader/*.elf \
- src/telebt-v4.0/flash-loader/{*.elf,*.bin,*.map} \
+ src/telebt-v[3-4].0/flash-loader/*.elf \
src/teledongle-v3.0/flash-loader/*.elf \
- src/telegps-v1.0/flash-loader/*.elf \
- src/telegps-v2.0/flash-loader/{*.elf,*.bin,*.map} \
+ src/telegps-v[1-2].0/flash-loader/*.elf \
src/telemega-v[1-5].0/flash-loader/*.elf \
- src/telemetrum-v2.0/flash-loader/*.elf \
- src/telemetrum-v3.0/flash-loader/*.elf \
+ src/telemetrum-v[2-3].0/flash-loader/*.elf \
src/telemini-v3.0/flash-loader/{*.elf,*.bin,*.map} \
src/telelco-v2.0/flash-loader/*.elf \
- src/telefireeight-v1.0/flash-loader/*.elf \
- src/telefireeight-v2.0/flash-loader/*.elf \
+ src/telefireeight-v[1-2].0/flash-loader/*.elf \
~/altusmetrumllc/Binaries/loaders/
(cd ~/altusmetrumllc ; git add Binaries ; git commit -a)
- remove previous versions (only keep latest release)
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
record = new AltosEepromRecordMega(eeprom);
break;
case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
#!/bin/sh
-VERSION=4.0
+VERSION=5.0
PRODUCT=TeleMega
BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
echo "$PRODUCT-v$VERSION Test Program"
-echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo "Copyright 2021 by Bdale Garbee. Released under GPL v3"
echo
echo "Expectations:"
echo "\t$PRODUCT v$VERSION powered from USB"
--- /dev/null
+#!/bin/sh
+
+VERSION=4.0
+PRODUCT=TeleMega
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo
+
+ret=1
+ao-list | while read product serial dev; do
+ case "$product" in
+ "$PRODUCT-v$VERSION")
+
+ echo "Testing $product $serial $dev"
+
+ ./test-igniters $dev --rplus=100 --rminus=27 --adcmax=4095 main drogue 3 0 1 2
+ echo""
+
+ echo "Testing baro sensor"
+ ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ FLASHSIZE=8388608
+
+ echo "Testing flash"
+ ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ echo "Testing GPS"
+ ../ao-tools/ao-test-gps/ao-test-gps --tty="$dev"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+ echo "\007"
+ ret=0
+ ;;
+ esac
+done
exit 1
fi
-VERSION=4.0
+VERSION=5.0
REPO=~/altusmetrumllc/Binaries
PRODUCT=TeleMega
echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo "Copyright 2021 by Bdale Garbee. Released under GPL v3"
echo
echo "Expectations:"
echo "\t$PRODUCT v$VERSION powered from USB"
--- /dev/null
+#!/bin/sh
+
+if [ -x /usr/bin/ao-flash-stm ]; then
+ FLASH_STM=/usr/bin/ao-flash-stm
+else
+ echo "Can't find ao-flash-stm! Aborting."
+ exit 1
+fi
+
+if [ -x /usr/bin/ao-usbload ]; then
+ USBLOAD=/usr/bin/ao-usbload
+else
+ echo "Can't find ao-usbload! Aborting."
+ exit 1
+fi
+
+VERSION=4.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleMega
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo "\t\twith ST-Link-V2 cabled to debug header"
+echo "\t\twith coax from UHF to frequency counter"
+echo
+
+case $# in
+ 1)
+ SERIAL="$1"
+ echo "$PRODUCT-$VERSION serial number: $SERIAL"
+ ;;
+ 0)
+ echo -n "$PRODUCT-$VERSION serial number: "
+ read SERIAL
+ ;;
+ *)
+ echo "Usage: $0 <serial-number>" 1>&2
+ exit 1;
+ ;;
+esac
+
+echo $FLASH_STM
+
+$FLASH_STM $REPO/loaders/telemega-v$VERSION*.elf
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL --force $REPO/telemega-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/TeleMega-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+ echo "TeleMega found on $dev"
+ ;;
+*)
+ echo 'No TeleMega-v'"$VERSION"' found'
+ exit 1
+ ;;
+esac
+
+echo 'E 0' > $dev
+
+SERIAL=$SERIAL ./cal-freq $dev
+
+failed=1
+while [ $failed = 1 ]; do
+ ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+ failed=$?
+done
+
+echo 'E 1' > $dev
+
+./test-telemega
+
+exit $?
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.8)
-ANDROID_VERSION=29
+AC_INIT([altos], 1.9.9)
+ANDROID_VERSION=31
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2021-09-20
+RELEASE_DATE=2021-10-06
AC_SUBST(RELEASE_DATE)
DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
endif
RELNOTES_INC=\
+ release-notes-1.9.9.inc \
release-notes-1.9.8.inc \
release-notes-1.9.7.inc \
release-notes-1.9.6.inc \
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.9.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.8.adoc[]
--- /dev/null
+= Release Notes for Version 1.9.9
+include::release-head.adoc[]
+:doctype: article
+
+ Version 1.9.9
+
+ This release contains a critical bug fix for a problem
+ introduced in version 1.9.8 for TeleMega and EasyMega
+ boards. This problem occurs when using the stored
+ configuration from 1.9.7 or earlier.
+
+ If you are running 1.9.8 or are upgrading from 1.9.8 on any
+ version of TeleMega or EasyMega, you must reconfigure all pyro
+ channels, recalibrate accelerometers, reset the APRS interval,
+ adjust the beep tone and reset the pyro time.
+
+ == AltOS
+
+ * Fix EasyMega and TeleMega upgrade process from 1.9.7 or
+ earlier. 1.9.8 introduced larger delay values, which
+ required modifying the configuration in-place, and the 1.9.8
+ version had a flaw which broke the pyro channel config and
+ all of the config values beyond that in memory, including
+ APRS interval, IMU accel calibation, beep tone and pyro
+ time.
+
+ * Fix TeleMega v5.0 mag sensor driver. This driver was quite
+ broken due to developing it in the presence of the magnetic
+ beeper on the board. Because of that beeper, the values this
+ sensor records are not accurate. Fortunately, they are not
+ used for controlling the flight.
+
+ == AltosUI
+
+ * Parse TeleMega v5.0 log files. A missing check in the code
+ meant that the TeleMega v5.0 log files would cause an error
+ when attempting to load them. Logs saved with AltosUI
+ 1.9.8 were not affected, only the presentation of the data
+ was broken.
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.9.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.8.adoc[]
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.9.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.8.adoc[]
#if HAS_MMC5983
+#define DEBUG_MMC5983 0
+
struct ao_mmc5983_sample ao_mmc5983_current;
+static struct ao_mmc5983_sample ao_mmc5983_offset;
static uint8_t ao_mmc5983_configured;
}
static void
-ao_mmc5983_sample(struct ao_mmc5983_sample *sample)
+ao_mmc5983_raw(struct ao_mmc5983_raw *raw)
{
- struct ao_mmc5983_raw raw;
-
ao_i2c_bit_start(MMC5983_I2C_ADDR);
- raw.addr = MMC5983_X_OUT_0;
- ao_i2c_bit_send(&raw.addr, 1);
+ raw->addr = MMC5983_X_OUT_0;
+ ao_i2c_bit_send(&(raw->addr), 1);
ao_i2c_bit_restart(MMC5983_I2C_ADDR | 1);
- ao_i2c_bit_recv(&raw.x0, 7);
+ ao_i2c_bit_recv(&(raw->x0), sizeof(*raw) - 1);
ao_i2c_bit_stop();
-
- sample->x = raw.x0 << 10 | raw.x1 << 2 | ((raw.xyz2 >> 6) & 3);
- sample->y = raw.y0 << 10 | raw.y1 << 2 | ((raw.xyz2 >> 4) & 3);
- sample->z = raw.z0 << 10 | raw.z1 << 2 | ((raw.xyz2 >> 2) & 3);
}
#else
}
static void
-ao_mmc5983_sample(struct ao_mmc5983_sample *sample)
+ao_mmc5983_raw(struct ao_mmc5983_raw *raw)
{
- struct ao_mmc5983_raw raw;
+ raw->addr = MMC5983_X_OUT_0 | MMC5983_READ;
+ ao_mmc5983_duplex((uint8_t *) raw, sizeof (*raw));
+}
+#endif
- raw.addr = MMC5983_X_OUT_0 | MMC5983_READ;
- ao_mmc5983_duplex((uint8_t *) &raw, sizeof (raw));
+/* Saturating subtraction. Keep the result within range
+ * of an int16_t
+ */
+static int16_t
+sat_sub(int16_t a, int16_t b)
+{
+ int32_t v = (int32_t) a - (int32_t) b;
+ if (v < -32768)
+ v = -32768;
+ if (v > 32767)
+ v = 32767;
+ return v;
+}
- sample->x = raw.x0 << 10 | raw.x1 << 2 | ((raw.xyz2 >> 6) & 3);
- sample->y = raw.y0 << 10 | raw.y1 << 2 | ((raw.xyz2 >> 4) & 3);
- sample->z = raw.z0 << 10 | raw.z1 << 2 | ((raw.xyz2 >> 2) & 3);
+/* Wait for a synchronous sample to finish */
+static void
+ao_mmc5983_wait(void)
+{
+ for (;;) {
+ uint8_t status = ao_mmc5983_reg_read(MMC5983_STATUS);
+ if ((status & (1 << MMC5983_STATUS_MEAS_M_DONE)) != 0)
+ break;
+ ao_delay(0);
+ }
}
-#endif
-static uint8_t product_id;
+static void
+ao_mmc5983_set(void)
+{
+ ao_mmc5983_reg_write(MMC5983_CONTROL_0,
+ (1 << MMC5983_CONTROL_0_SET));
+}
-static uint8_t
-ao_mmc5983_setup(void)
+static void
+ao_mmc5983_reset(void)
{
+ ao_mmc5983_reg_write(MMC5983_CONTROL_0,
+ (1 << MMC5983_CONTROL_0_RESET));
+}
- if (ao_mmc5983_configured)
- return 1;
+static struct ao_mmc5983_raw raw;
- /* Delay for power up time (10ms) */
- ao_delay(AO_MS_TO_TICKS(10));
+/* Read the sensor values and convert to a sample struct */
+static void
+ao_mmc5983_sample(struct ao_mmc5983_sample *s)
+{
+ ao_mmc5983_raw(&raw);
+
+ /* Bias by 32768 to convert from uint16_t to int16_t */
+ s->x = (int32_t) (((uint16_t) raw.x0 << 8) | raw.x1) - 32768;
+ s->y = (int32_t) (((uint16_t) raw.y0 << 8) | raw.y1) - 32768;
+ s->z = (int32_t) (((uint16_t) raw.z0 << 8) | raw.z1) - 32768;;
+}
+
+/* Synchronously sample the sensors */
+static void
+ao_mmc5983_sync_sample(struct ao_mmc5983_sample *v)
+{
+ ao_mmc5983_reg_write(MMC5983_CONTROL_0,
+ (1 << MMC5983_CONTROL_0_TM_M));
+ ao_mmc5983_wait();
+ ao_mmc5983_sample(v);
+}
+
+static struct ao_mmc5983_sample set, reset;
+
+/* Calibrate the device by finding the zero point */
+static void
+ao_mmc5983_cal(void)
+{
+ /* Compute offset */
+
+ ao_delay(AO_MS_TO_TICKS(100));
+
+ /* Measure in 'SET' mode */
+ ao_mmc5983_set();
+ ao_delay(AO_MS_TO_TICKS(100));
+ ao_mmc5983_sync_sample(&set);
+
+ ao_delay(AO_MS_TO_TICKS(100));
+
+ /* Measure in 'RESET' mode */
+ ao_mmc5983_reset();
+ ao_delay(AO_MS_TO_TICKS(100));
+ ao_mmc5983_sync_sample(&reset);
+
+ /* The zero point is the average of SET and RESET values */
+ ao_mmc5983_offset.x = ((int32_t) set.x + (int32_t) reset.x) / 2;
+ ao_mmc5983_offset.y = ((int32_t) set.y + (int32_t) reset.y) / 2;
+ ao_mmc5983_offset.z = ((int32_t) set.z + (int32_t) reset.z) / 2;
+}
+
+/* Configure the device to automatically sample at 200Hz */
+static void
+ao_mmc5983_run(void)
+{
+ /* Set bandwidth to 200Hz */
+ ao_mmc5983_reg_write(MMC5983_CONTROL_1,
+ MMC5983_CONTROL_1_BW_200 << MMC5983_CONTROL_1_BW);
+
+ /* Measure at 200Hz so we get recent samples by just reading
+ * the registers
+ */
+ ao_mmc5983_reg_write(MMC5983_CONTROL_2,
+ (1 << MMC5983_CONTROL_2_CMM_EN) |
+ (MMC5983_CONTROL_2_CM_FREQ_200HZ << MMC5983_CONTROL_2_CM_FREQ) |
+ (0 << MMC5983_CONTROL_2_EN_PRD_SET) |
+ (MMC5983_CONTROL_2_PRD_SET_1000));
+ ao_mmc5983_configured = 1;
+}
+
+/* Reboot the device by setting the SW_RST bit and waiting 10ms */
+static void
+ao_mmc5983_reboot(void)
+{
+ ao_mmc5983_configured = 0;
ao_mmc5983_reg_write(MMC5983_CONTROL_1,
1 << MMC5983_CONTROL_1_SW_RST);
/* Delay for power up time (10ms) */
ao_delay(AO_MS_TO_TICKS(10));
+}
+
+/* Configure the device for operation */
+static uint8_t
+ao_mmc5983_setup(void)
+{
+ uint8_t product_id;
+
+ /* Reboot the device */
+ ao_mmc5983_reboot();
/* Check product ID */
product_id = ao_mmc5983_reg_read(MMC5983_PRODUCT_ID);
AO_SENSOR_ERROR(AO_DATA_MMC5983);
}
- /* Set bandwidth to 200Hz */
- ao_mmc5983_reg_write(MMC5983_CONTROL_1,
- MMC5983_CONTROL_1_BW_200 << MMC5983_CONTROL_1_BW);
+ /* Calibrate */
+ ao_mmc5983_cal();
- /* Measure at 200Hz so we get recent samples by just reading
- * the registers
- */
- ao_mmc5983_reg_write(MMC5983_CONTROL_2,
- (1 << MMC5983_CONTROL_2_CMM_EN) |
- (MMC5983_CONTROL_2_CM_FREQ_200HZ << MMC5983_CONTROL_2_CM_FREQ));
+ /* Start automatic sampling */
+ ao_mmc5983_run();
- ao_mmc5983_configured = 1;
return 1;
}
struct ao_mmc5983_sample sample;
ao_mmc5983_setup();
for (;;) {
- ao_mmc5983_sample(&sample);
+ if (ao_mmc5983_configured)
+ ao_mmc5983_sample(&sample);
+ sample.x = sat_sub(sample.x, ao_mmc5983_offset.x);
+ sample.y = sat_sub(sample.y, ao_mmc5983_offset.y);
+ sample.z = sat_sub(sample.z, ao_mmc5983_offset.z);
ao_arch_block_interrupts();
ao_mmc5983_current = sample;
AO_DATA_PRESENT(AO_DATA_MMC5983);
static void
ao_mmc5983_show(void)
{
+#if DEBUG_MMC5983
+ printf ("x0 %02x x1 %02x y0 %02x y1 %02x z0 %02x z1 %02x\n",
+ raw.x0, raw.x1, raw.y0, raw.y1, raw.z0, raw.z1);
+
+ printf ("set.x %d set.y %d set.z %d\n",
+ set.x, set.y, set.z);
+
+ printf ("reset.x %d reset.y %d reset.z %d\n",
+ reset.x, reset.y, reset.z);
+
+ printf ("offset.x %d offset.y %d offset.z %d\n",
+ ao_mmc5983_offset.x,
+ ao_mmc5983_offset.y,
+ ao_mmc5983_offset.z);
+#endif
printf ("MMC5983: %d %d %d\n",
ao_mmc5983_along(&ao_mmc5983_current),
ao_mmc5983_across(&ao_mmc5983_current),
ao_mmc5983_through(&ao_mmc5983_current));
}
+#if DEBUG_MMC5983
+static void
+ao_mmc5983_recal(void)
+{
+ printf("recal\n"); fflush(stdout);
+ ao_mmc5983_reboot();
+ printf("reboot\n"); fflush(stdout);
+ ao_mmc5983_cal();
+ printf("cal\n"); fflush(stdout);
+ ao_mmc5983_show();
+ printf("show\n"); fflush(stdout);
+ ao_mmc5983_run();
+ printf("run\n"); fflush(stdout);
+}
+#endif
+
static const struct ao_cmds ao_mmc5983_cmds[] = {
{ ao_mmc5983_show, "M\0Show MMC5983 status" },
+#if DEBUG_MMC5983
+ { ao_mmc5983_recal, "m\0Recalibrate MMC5983" },
+#endif
{ 0, NULL }
};
uint8_t y1;
uint8_t z0;
uint8_t z1;
- uint8_t xyz2;
};
extern struct ao_mmc5983_sample ao_mmc5983_current;
#endif
};
+struct ao_config_1_24 {
+ uint8_t major;
+ uint8_t minor;
+ uint16_t main_deploy;
+ int16_t accel_plus_g; /* changed for minor version 2 */
+ uint8_t _legacy_radio_channel;
+ char callsign[AO_MAX_CALLSIGN + 1];
+ uint8_t apogee_delay; /* minor version 1 */
+ int16_t accel_minus_g; /* minor version 2 */
+ uint32_t radio_cal; /* minor version 3 */
+ uint32_t flight_log_max; /* minor version 4 */
+ uint8_t ignite_mode; /* minor version 5 */
+ uint8_t pad_orientation; /* minor version 6 */
+ uint32_t radio_setting; /* minor version 7 */
+ uint8_t radio_enable; /* minor version 8 */
+ uint8_t aes_key[AO_AES_LEN]; /* minor version 9 */
+ uint32_t frequency; /* minor version 10 */
+ uint16_t apogee_lockout; /* minor version 11 */
+#if AO_PYRO_NUM
+ struct ao_pyro_1_24 pyro[AO_PYRO_NUM]; /* minor version 12 */
+#endif
+ uint16_t aprs_interval; /* minor version 13 */
+#if HAS_RADIO_POWER
+ uint8_t radio_power; /* minor version 14 */
+#endif
+#if HAS_RADIO_AMP
+ uint8_t radio_amp; /* minor version 14 */
+#endif
+#if HAS_IMU
+ int16_t accel_zero_along; /* minor version 15 */
+ int16_t accel_zero_across; /* minor version 15 */
+ int16_t accel_zero_through; /* minor version 15 */
+#endif
+#if HAS_BEEP
+ uint8_t mid_beep; /* minor version 16 */
+#endif
+#if HAS_TRACKER
+ uint16_t tracker_motion; /* minor version 17 */
+ uint8_t tracker_interval; /* minor version 17 */
+#endif
+#if AO_PYRO_NUM
+ uint16_t pyro_time; /* minor version 18 */
+#endif
+#if HAS_APRS
+ uint8_t aprs_ssid; /* minor version 19 */
+#endif
+#if HAS_RADIO_RATE
+ uint8_t radio_rate; /* minor version 20 */
+#endif
+#if HAS_RADIO_FORWARD
+ uint32_t send_frequency; /* minor version 21 */
+#endif
+#if HAS_APRS
+ uint8_t aprs_format; /* minor version 22 */
+#endif
+#if HAS_FIXED_PAD_BOX
+ uint8_t pad_box; /* minor version 22 */
+ uint8_t pad_idle; /* minor version 23 */
+#endif
+#if HAS_APRS
+ uint8_t aprs_offset; /* minor version 24 */
+#endif
+};
+
#define AO_APRS_FORMAT_COMPRESSED 0
#define AO_APRS_FORMAT_UNCOMPRESSED 1
#define AO_CONFIG_DEFAULT_APRS_FORMAT AO_APRS_FORMAT_COMPRESSED
/* First, move all of the config bits that follow the pyro data */
- char *pyro_base = (void *) &ao_config.pyro;
- char *after_pyro_new = pyro_base + AO_PYRO_NUM * sizeof (struct ao_pyro);
- char *after_pyro_1_24 = pyro_base + AO_PYRO_NUM * sizeof (struct ao_pyro_1_24);
- char *config_end = (void *) (&ao_config + 1);
- size_t to_move = config_end - after_pyro_new;
+ struct ao_config_1_24 *ao_config_1_24 = (void *) &ao_config;
+ struct ao_pyro *pyro_1_25 = &ao_config.pyro[0];
+ struct ao_pyro_1_24 *pyro_1_24 = &(ao_config_1_24->pyro)[0];
- memmove(after_pyro_new, after_pyro_1_24, to_move);
- /* Now, adjust all of the pyro entries */
+ char *pyro_base_1_25 = (void *) pyro_1_25;
+ char *pyro_base_1_24 = (void *) pyro_1_24;
+ char *after_pyro_1_25 = pyro_base_1_25 + AO_PYRO_NUM * sizeof (struct ao_pyro);
+ char *after_pyro_1_24 = pyro_base_1_24 + AO_PYRO_NUM * sizeof (struct ao_pyro_1_24);
+
+ char *config_end_1_25 = (void *) (&ao_config + 1);
+ size_t to_move = config_end_1_25 - after_pyro_1_25;
- struct ao_pyro *pyro_new = ao_config.pyro;
- struct ao_pyro_1_24 *pyro_old = (void *) ao_config.pyro;
+ memmove(after_pyro_1_25, after_pyro_1_24, to_move);
+
+ /* Now, adjust all of the pyro entries */
int p = AO_PYRO_NUM;
struct ao_pyro tmp;
memset(&tmp, '\0', sizeof(tmp));
- tmp.flags = pyro_old[p].flags;
+ tmp.flags = pyro_1_24[p].flags;
for (v = 0; v < NUM_PYRO_VALUES; v++)
{
- value = ao_pyro_get_1_24(&pyro_old[v], ao_pyro_values[v].flag);
+ value = ao_pyro_get_1_24(&pyro_1_24[p], ao_pyro_values[v].flag);
ao_pyro_put(&tmp, ao_pyro_values[v].offset,
ao_pyro_size(ao_pyro_values[v].flag), value);
}
- memcpy(&pyro_new[p], &tmp, sizeof(tmp));
+ memcpy(&pyro_1_25[p], &tmp, sizeof(tmp));
}
}
}