From d69b6738040bf751d024b4daceace7aedee6f7c7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Jan 2024 17:03:30 -0800 Subject: [PATCH] altos/easytimer-v2: Add logging bits 32-byte records with all data in a single record instead of separate volt/sensor bits. Signed-off-by: Keith Packard --- src/easytimer-v2/Makefile | 93 +++++++++++++++++ src/easytimer-v2/ao_pins.h | 15 ++- src/easytimer-v2/flash-loader/Makefile | 8 ++ src/kernel/ao_log.h | 46 +++++++++ src/kernel/ao_log_timer.c | 134 +++++++++++++++++++++++++ 5 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 src/easytimer-v2/Makefile create mode 100644 src/easytimer-v2/flash-loader/Makefile create mode 100644 src/kernel/ao_log_timer.c diff --git a/src/easytimer-v2/Makefile b/src/easytimer-v2/Makefile new file mode 100644 index 00000000..66c31e0b --- /dev/null +++ b/src/easytimer-v2/Makefile @@ -0,0 +1,93 @@ +# +# AltOS build +# +# + +include ../samd21/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_companion.h \ + ao_data.h \ + ao_sample.h \ + ao_pins.h \ + altitude-pa.h \ + ao_kalman.h \ + ao_product.h \ + ao_task.h \ + ao_whiten.h \ + samd21.h \ + Makefile + +SAMD21_ROM=128 +SAMD21_RAM=16 + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_stdio.c \ + ao_storage.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_freq.c \ + ao_dma_samd21.c \ + ao_spi_samd21.c \ + ao_data.c \ + ao_bmi088.c \ + ao_mmc5983.c \ + ao_m25.c \ + ao_adc_samd21.c \ + ao_beep_samd21.c \ + ao_usb_samd21.c \ + ao_exti_samd21.c \ + ao_convert_volt.c \ + ao_report.c \ + ao_sample.c \ + ao_kalman.c \ + ao_pyro.c \ + ao_flight.c \ + ao_ignite.c \ + ao_log.c \ + ao_log_timer.c \ + $(PROFILE) \ + $(SAMPLE_PROFILE) \ + $(STACK_GUARD) + +PRODUCT=EasyTimer-2 +PRODUCT_DEF=-DEASYTIMER_V_2 +IDPRODUCT=0x000d + +CFLAGS = $(PRODUCT_DEF) $(SAMD21_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) + +PROGNAME=easytimer-v2 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_easytimer.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 $(PROGNAME)-*.map + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/easytimer-v2/ao_pins.h b/src/easytimer-v2/ao_pins.h index e00d9093..a9bdb34c 100644 --- a/src/easytimer-v2/ao_pins.h +++ b/src/easytimer-v2/ao_pins.h @@ -29,7 +29,7 @@ #define AO_CONFIG_MAX_SIZE 1024 -#define HAS_EEPROM 0 +#define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 0 #define USE_EEPROM_CONFIG 0 #define USE_STORAGE_CONFIG 1 @@ -56,7 +56,7 @@ #define HAS_FLIGHT 1 #define HAS_ADC 1 #define HAS_ADC_TEMP 1 -#define HAS_LOG 0 +#define HAS_LOG 1 /* * Igniter @@ -229,4 +229,15 @@ struct ao_adc { #define AO_MONITOR_LED 0 #define HAS_RSSI 0 +/* + * Logging + */ + +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) +#define AO_CONFIG_MAX_SIZE 1024 +#define LOG_ERASE_MARK 0x55 +#define LOG_MAX_ERASE 128 +#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYTIMER_2 +#define AO_LOG_NORMALIZED 1 + #endif /* _AO_PINS_H_ */ diff --git a/src/easytimer-v2/flash-loader/Makefile b/src/easytimer-v2/flash-loader/Makefile new file mode 100644 index 00000000..bf0094bd --- /dev/null +++ b/src/easytimer-v2/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easytimer-v2 +include $(TOPDIR)/samd21/Makefile-flash.defs diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 9df34b4e..de1156e1 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -62,6 +62,7 @@ extern enum ao_flight_state ao_log_state; #define AO_LOG_FORMAT_EASYMOTOR 20 /* 16 byte typed easymotor records with pressure sensor and adxl375 */ #define AO_LOG_FORMAT_TELEMEGA_5 21 /* 32 byte typed telemega records with 32 bit gyro cal, mpu6000 and mmc5983 */ #define AO_LOG_FORMAT_TELEMEGA_6 22 /* 32 byte typed telemega records with 32 bit gyro cal, bmi088 and mmc5983 */ +#define AO_LOG_FORMAT_EASYTIMER_2 23 /* 32 byte typed easytimer records with 32 bit gyro cal, bmi088 and mmc5983 */ #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 */ @@ -550,6 +551,47 @@ struct ao_log_motor { } u; }; +struct ao_log_timer { + 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 pad_14; /* 14 */ + int32_t ground_roll; /* 16 */ + int32_t ground_pitch; /* 20 */ + int32_t ground_yaw; /* 24 */ + } flight; /* 32 */ + /* AO_LOG_STATE */ + struct { + uint16_t state; /* 4 */ + uint16_t reason; /* 6 */ + } state; + /* AO_LOG_SENSOR */ + struct { + int16_t accel_along; /* 4 */ + int16_t accel_across; /* 6 */ + int16_t accel_through; /* 8 */ + int16_t gyro_roll; /* 10 */ + int16_t gyro_pitch; /* 12 */ + int16_t gyro_yaw; /* 14 */ + int16_t mag_along; /* 16 */ + int16_t mag_across; /* 18 */ + int16_t mag_through; /* 20 */ + int16_t v_batt; /* 22 */ + int16_t v_pbatt; /* 24 */ + int16_t sense[2]; /* 26 */ + uint16_t pyro; /* 30 */ + } sensor; /* 32 */ + } 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 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6 typedef struct ao_log_mega ao_log_type; #endif @@ -594,6 +636,10 @@ typedef struct ao_log_record ao_log_type; #define AO_LOG_UNCOMMON 1 #endif +#if AO_LOG_FORMAT == AO_LOG_FORMAT_EASYTIMER_2 +typedef struct ao_log_timer ao_log_type; +#endif + #ifndef AO_LOG_UNCOMMON extern ao_log_type ao_log_data; diff --git a/src/kernel/ao_log_timer.c b/src/kernel/ao_log_timer.c new file mode 100644 index 00000000..42b9b85a --- /dev/null +++ b/src/kernel/ao_log_timer.c @@ -0,0 +1,134 @@ +/* + * Copyright © 2024 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; 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 +#include +#include + +#if HAS_FLIGHT +static uint8_t ao_log_data_pos; + +/* a hack to make sure that ao_log_timers fill the eeprom block in even units */ +typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_timer))] ; + +#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) +{ + AO_TICK_TYPE next_sensor; + uint8_t i; + + ao_storage_setup(); + + ao_log_scan(); + + while (!ao_log_running) + ao_sleep(&ao_log_running); + +#if HAS_FLIGHT + ao_log_data.type = AO_LOG_FLIGHT; + ao_log_data.tick = (uint16_t) ao_sample_tick; +#if HAS_ACCEL + ao_log_data.u.flight.ground_accel = ao_ground_accel; +#endif +#if HAS_GYRO + ao_log_data.u.flight.ground_accel_along = ao_ground_accel_along; + ao_log_data.u.flight.ground_accel_across = ao_ground_accel_across; + ao_log_data.u.flight.ground_accel_through = ao_ground_accel_through; + ao_log_data.u.flight.ground_roll = ao_ground_roll; + ao_log_data.u.flight.ground_pitch = ao_ground_pitch; + ao_log_data.u.flight.ground_yaw = ao_ground_yaw; +#endif + ao_log_data.u.flight.flight = ao_flight_number; + ao_log_write(&ao_log_data); +#endif + + /* 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_TICK_TYPE tick = ao_data_ring[ao_log_data_pos].tick; + ao_log_data.tick = (uint16_t) tick; + volatile struct ao_data *d = &ao_data_ring[ao_log_data_pos]; + if ((AO_TICK_SIGNED) (tick - next_sensor) >= 0) { + ao_log_data.type = AO_LOG_SENSOR; + +#if HAS_IMU + ao_log_data.u.sensor.accel_along = ao_data_along(d); + ao_log_data.u.sensor.accel_across = ao_data_across(d); + ao_log_data.u.sensor.accel_through = ao_data_through(d); + ao_log_data.u.sensor.gyro_roll = ao_data_roll(d); + ao_log_data.u.sensor.gyro_pitch = ao_data_pitch(d); + ao_log_data.u.sensor.gyro_yaw = ao_data_yaw(d); +#endif +#if HAS_MAG + ao_log_data.u.sensor.mag_along = ao_data_mag_along(d); + ao_log_data.u.sensor.mag_across = ao_data_mag_across(d); + ao_log_data.u.sensor.mag_through = ao_data_mag_through(d); +#endif + ao_log_data.u.sensor.v_batt = d->adc.v_batt; + for (i = 0; i < AO_ADC_NUM_SENSE; i++) + ao_log_data.u.sensor.sense[i] = d->adc.sense[i]; + ao_log_data.u.sensor.pyro = ao_pyro_fired; + + ao_log_write(&ao_log_data); + if (ao_log_state <= ao_flight_coast) + next_sensor = tick + AO_SENSOR_INTERVAL_ASCENT; + else + next_sensor = 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 = (uint16_t) 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 */ + -- 2.30.2