X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fkernel%2Fao_telemetry.c;h=d567f9c2a3604c0a3a073432b869bd7204d8f92e;hb=63c089e2e110a7fe501dd097bd7d26ce4feeb935;hp=2292d229d673a02b6b8ef1ebd87d45720f0fc9dc;hpb=08550425fca3da73d8f16de567a2c956b85d676e;p=fw%2Faltos diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 2292d229..d567f9c2 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -1,9 +1,10 @@ /* - * Copyright © 2011 Keith Packard + * Copyright © 2011 Keth Packard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * 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 @@ -19,19 +20,36 @@ #include "ao_log.h" #include "ao_product.h" -#ifndef HAS_RDF -#define HAS_RDF 1 +static uint16_t ao_telemetry_interval; + +#if HAS_RADIO_RATE +static uint16_t ao_telemetry_desired_interval; +#endif + +/* TeleMetrum v1.0 just doesn't have enough space to + * manage the more complicated telemetry scheduling, so + * it loses the ability to disable telem/rdf separately + */ + +#if defined(TELEMETRUM_V_1_0) +#define SIMPLIFY #endif -static __pdata uint16_t ao_telemetry_interval; +#ifdef SIMPLIFY +#define ao_telemetry_time time +#define RDF_SPACE +#else +#define RDF_SPACE +static AO_TICK_TYPE ao_telemetry_time; +#endif #if HAS_RDF -static __pdata uint8_t ao_rdf = 0; -static __pdata uint16_t ao_rdf_time; +static RDF_SPACE uint8_t ao_rdf = 0; +static RDF_SPACE AO_TICK_TYPE ao_rdf_time; #endif #if HAS_APRS -static __pdata uint16_t ao_aprs_time; +static AO_TICK_TYPE ao_aprs_time; #include #endif @@ -40,7 +58,7 @@ static __pdata uint16_t ao_aprs_time; #define AO_SEND_MEGA 1 #endif -#if defined (TELEMETRUM_V_2_0) +#if defined (TELEMETRUM_V_2_0) || defined (TELEMETRUM_V_3_0) #define AO_SEND_METRUM 1 #endif @@ -56,15 +74,22 @@ static __pdata uint16_t ao_aprs_time; #define AO_TELEMETRY_SENSOR AO_TELEMETRY_SENSOR_TELENANO #endif -static __xdata union ao_telemetry_all telemetry; +static union ao_telemetry_all telemetry; + +static void +ao_telemetry_send(void) +{ + ao_radio_send(&telemetry, sizeof (telemetry)); + ao_delay(1); +} #if defined AO_TELEMETRY_SENSOR /* Send sensor packet */ static void ao_send_sensor(void) { - __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; - + struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + telemetry.generic.tick = packet->tick; telemetry.generic.type = AO_TELEMETRY_SENSOR; @@ -100,22 +125,65 @@ ao_send_sensor(void) telemetry.sensor.accel_minus_g = 0; #endif - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } #endif #ifdef AO_SEND_MEGA + /* Send mega sensor packet */ static void ao_send_mega_sensor(void) { - __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; - - telemetry.generic.tick = packet->tick; - telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR; + struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; - telemetry.mega_sensor.orient = ao_sample_orient; + telemetry.generic.tick = (uint16_t) packet->tick; +#if AO_LOG_NORMALIZED +#if AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5 + telemetry.generic.type = AO_TELEMETRY_MEGA_NORM_MPU6000_MMC5983; +#else +#error unknown normalized log type +#endif + +#if HAS_GYRO + telemetry.mega_norm.orient = (uint8_t) ao_sample_orient; +#endif + telemetry.mega_norm.accel = ao_data_accel(packet); + telemetry.mega_norm.pres = ao_data_pres(packet); + telemetry.mega_norm.temp = ao_data_temp(packet); + +#if HAS_MPU6000 + telemetry.mega_norm.accel_along = ao_data_along(packet); + telemetry.mega_norm.accel_across = ao_data_across(packet); + telemetry.mega_norm.accel_through = ao_data_through(packet); + + telemetry.mega_norm.gyro_roll = ao_data_roll(packet); + telemetry.mega_norm.gyro_pitch = ao_data_pitch(packet); + telemetry.mega_norm.gyro_yaw = ao_data_yaw(packet); +#endif + +#if HAS_MMC5983 + telemetry.mega_norm.mag_along = ao_data_mag_along(packet); + telemetry.mega_norm.mag_across = ao_data_mag_across(packet); + telemetry.mega_norm.mag_through = ao_data_mag_through(packet); +#endif + +#else + +#if HAS_BMX160 + telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR_BMX160; +#else +#if HAS_MPU6000 || HAS_MPU9250 + telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR_MPU; +#else +#error unknown IMU +#endif +#endif + +#if HAS_GYRO + telemetry.mega_sensor.orient = (uint8_t) ao_sample_orient; +#endif telemetry.mega_sensor.accel = ao_data_accel(packet); telemetry.mega_sensor.pres = ao_data_pres(packet); telemetry.mega_sensor.temp = ao_data_temp(packet); @@ -132,25 +200,53 @@ ao_send_mega_sensor(void) #if HAS_HMC5883 telemetry.mega_sensor.mag_x = packet->hmc5883.x; - telemetry.mega_sensor.mag_y = packet->hmc5883.y; telemetry.mega_sensor.mag_z = packet->hmc5883.z; + telemetry.mega_sensor.mag_y = packet->hmc5883.y; #endif - ao_radio_send(&telemetry, sizeof (telemetry)); +#if HAS_MPU9250 + telemetry.mega_sensor.accel_x = packet->mpu9250.accel_x; + telemetry.mega_sensor.accel_y = packet->mpu9250.accel_y; + telemetry.mega_sensor.accel_z = packet->mpu9250.accel_z; + + telemetry.mega_sensor.gyro_x = packet->mpu9250.gyro_x; + telemetry.mega_sensor.gyro_y = packet->mpu9250.gyro_y; + telemetry.mega_sensor.gyro_z = packet->mpu9250.gyro_z; + + telemetry.mega_sensor.mag_x = packet->mpu9250.mag_x; + telemetry.mega_sensor.mag_z = packet->mpu9250.mag_z; + telemetry.mega_sensor.mag_y = packet->mpu9250.mag_y; +#endif + +#if HAS_BMX160 + telemetry.mega_sensor.accel_x = packet->bmx160.acc_x; + telemetry.mega_sensor.accel_y = packet->bmx160.acc_y; + telemetry.mega_sensor.accel_z = packet->bmx160.acc_z; + + telemetry.mega_sensor.gyro_x = packet->bmx160.gyr_x; + telemetry.mega_sensor.gyro_y = packet->bmx160.gyr_y; + telemetry.mega_sensor.gyro_z = packet->bmx160.gyr_z; + + telemetry.mega_sensor.mag_x = packet->bmx160.mag_x; + telemetry.mega_sensor.mag_z = packet->bmx160.mag_z; + telemetry.mega_sensor.mag_y = packet->bmx160.mag_y; +#endif +#endif + ao_telemetry_send(); } -static __pdata int8_t ao_telemetry_mega_data_max; -static __pdata int8_t ao_telemetry_mega_data_cur; +static int16_t ao_telemetry_mega_data_max; +static int16_t ao_telemetry_mega_data_cur; /* Send mega data packet */ static void ao_send_mega_data(void) { if (--ao_telemetry_mega_data_cur <= 0) { - __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; uint8_t i; - telemetry.generic.tick = packet->tick; + telemetry.generic.tick = (uint16_t) packet->tick; telemetry.generic.type = AO_TELEMETRY_MEGA_DATA; telemetry.mega_data.state = ao_flight_state; @@ -159,19 +255,19 @@ ao_send_mega_data(void) /* ADC range is 0-4095, so shift by four to save the high 8 bits */ for (i = 0; i < AO_ADC_NUM_SENSE; i++) - telemetry.mega_data.sense[i] = packet->adc.sense[i] >> 4; + telemetry.mega_data.sense[i] = (int8_t) (packet->adc.sense[i] >> 4); telemetry.mega_data.ground_pres = ao_ground_pres; telemetry.mega_data.ground_accel = ao_ground_accel; telemetry.mega_data.accel_plus_g = ao_config.accel_plus_g; telemetry.mega_data.accel_minus_g = ao_config.accel_minus_g; - telemetry.mega_data.acceleration = ao_accel; - telemetry.mega_data.speed = ao_speed; - telemetry.mega_data.height = ao_height; + telemetry.mega_data.acceleration = (int16_t) ao_accel; + telemetry.mega_data.speed = (int16_t) ao_speed; + telemetry.mega_data.height = (int16_t) ao_height; - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_mega_data_cur = ao_telemetry_mega_data_max; + ao_telemetry_send(); } } #endif /* AO_SEND_MEGA */ @@ -181,9 +277,9 @@ ao_send_mega_data(void) static void ao_send_metrum_sensor(void) { - __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; - telemetry.generic.tick = packet->tick; + telemetry.generic.tick = (uint16_t) packet->tick; telemetry.generic.type = AO_TELEMETRY_METRUM_SENSOR; telemetry.metrum_sensor.state = ao_flight_state; @@ -193,28 +289,28 @@ ao_send_metrum_sensor(void) telemetry.metrum_sensor.pres = ao_data_pres(packet); telemetry.metrum_sensor.temp = ao_data_temp(packet); - telemetry.metrum_sensor.acceleration = ao_accel; - telemetry.metrum_sensor.speed = ao_speed; - telemetry.metrum_sensor.height = ao_height; + telemetry.metrum_sensor.acceleration = (int16_t) ao_accel; + telemetry.metrum_sensor.speed = (int16_t) ao_speed; + telemetry.metrum_sensor.height = (int16_t) ao_height; telemetry.metrum_sensor.v_batt = packet->adc.v_batt; telemetry.metrum_sensor.sense_a = packet->adc.sense_a; telemetry.metrum_sensor.sense_m = packet->adc.sense_m; - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } -static __pdata int8_t ao_telemetry_metrum_data_max; -static __pdata int8_t ao_telemetry_metrum_data_cur; +static int16_t ao_telemetry_metrum_data_max; +static int16_t ao_telemetry_metrum_data_cur; /* Send telemetrum data packet */ static void ao_send_metrum_data(void) { if (--ao_telemetry_metrum_data_cur <= 0) { - __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; - telemetry.generic.tick = packet->tick; + telemetry.generic.tick = (uint16_t) packet->tick; telemetry.generic.type = AO_TELEMETRY_METRUM_DATA; telemetry.metrum_data.ground_pres = ao_ground_pres; @@ -228,8 +324,8 @@ ao_send_metrum_data(void) telemetry.metrum_data.accel_minus_g = 2; #endif - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max; + ao_telemetry_send(); } } #endif /* AO_SEND_METRUM */ @@ -239,10 +335,10 @@ ao_send_metrum_data(void) static void ao_send_mini(void) { - __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; - - telemetry.generic.tick = packet->tick; - telemetry.generic.type = AO_TELEMETRY_MINI; + struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + + telemetry.generic.tick = (uint16_t) packet->tick; + telemetry.generic.type = AO_SEND_MINI; telemetry.mini.state = ao_flight_state; @@ -253,44 +349,25 @@ ao_send_mini(void) telemetry.mini.pres = ao_data_pres(packet); telemetry.mini.temp = ao_data_temp(packet); - telemetry.mini.acceleration = ao_accel; - telemetry.mini.speed = ao_speed; - telemetry.mini.height = ao_height; + telemetry.mini.acceleration = (int16_t) ao_accel; + telemetry.mini.speed = (int16_t) ao_speed; + telemetry.mini.height = (int16_t) ao_height; telemetry.mini.ground_pres = ao_ground_pres; - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } #endif /* AO_SEND_MINI */ -#ifdef AO_SEND_ALL_BARO -static uint8_t ao_baro_sample; - -static void -ao_send_baro(void) -{ - uint8_t sample = ao_sample_data; - uint8_t samples = (sample - ao_baro_sample) & (AO_DATA_RING - 1); +static int16_t ao_telemetry_config_max; +static int16_t ao_telemetry_config_cur; +static uint16_t ao_telemetry_flight_number; - if (samples > 12) { - ao_baro_sample = (ao_baro_sample + (samples - 12)) & (AO_DATA_RING - 1); - samples = 12; - } - telemetry.generic.tick = ao_data_ring[sample].tick; - telemetry.generic.type = AO_TELEMETRY_BARO; - telemetry.baro.samples = samples; - for (sample = 0; sample < samples; sample++) { - telemetry.baro.baro[sample] = ao_data_ring[ao_baro_sample].adc.pres; - ao_baro_sample = ao_data_ring_next(ao_baro_sample); - } - ao_radio_send(&telemetry, sizeof (telemetry)); -} +#ifndef ao_telemetry_battery_convert +#define ao_telemetry_battery_convert(a) (a) #endif -static __pdata int8_t ao_telemetry_config_max; -static __pdata int8_t ao_telemetry_config_cur; - static void ao_send_configuration(void) { @@ -298,31 +375,46 @@ ao_send_configuration(void) { telemetry.generic.type = AO_TELEMETRY_CONFIGURATION; telemetry.configuration.device = AO_idProduct_NUMBER; -#if HAS_LOG - telemetry.configuration.flight = ao_log_full() ? 0 : ao_flight_number; -#else - telemetry.configuration.flight = ao_flight_number; -#endif + telemetry.configuration.flight = ao_telemetry_flight_number; telemetry.configuration.config_major = AO_CONFIG_MAJOR; telemetry.configuration.config_minor = AO_CONFIG_MINOR; +#if AO_idProduct_NUMBER == 0x25 && HAS_ADC + /* TeleGPS gets battery voltage instead of apogee delay */ + telemetry.configuration.apogee_delay = (uint16_t) ao_telemetry_battery_convert(ao_data_ring[ao_data_ring_prev(ao_data_head)].adc.v_batt); +#else telemetry.configuration.apogee_delay = ao_config.apogee_delay; telemetry.configuration.main_deploy = ao_config.main_deploy; - telemetry.configuration.flight_log_max = ao_config.flight_log_max >> 10; - ao_xmemcpy (telemetry.configuration.callsign, - ao_config.callsign, - AO_MAX_CALLSIGN); - ao_xmemcpy (telemetry.configuration.version, - CODE_TO_XDATA(ao_version), - AO_MAX_VERSION); - ao_radio_send(&telemetry, sizeof (telemetry)); +#endif + + telemetry.configuration.flight_log_max = (uint16_t) (ao_config.flight_log_max >> 10); + memcpy (telemetry.configuration.callsign, + ao_config.callsign, + AO_MAX_CALLSIGN); + memcpy (telemetry.configuration.version, + ao_version, + AO_MAX_VERSION); ao_telemetry_config_cur = ao_telemetry_config_max; + ao_telemetry_send(); } } #if HAS_GPS -static __pdata int8_t ao_telemetry_loc_cur; -static __pdata int8_t ao_telemetry_sat_cur; +static int16_t ao_telemetry_gps_max; +static int16_t ao_telemetry_loc_cur; +static int16_t ao_telemetry_sat_cur; + +static inline void * +telemetry_bits(struct ao_telemetry_location *l) +{ + return ((uint8_t *) l) + offsetof(struct ao_telemetry_location, flags); +} + +static inline size_t +telemetry_size(void) +{ + return sizeof(struct ao_telemetry_location) - offsetof(struct ao_telemetry_location, flags); +} static void ao_send_location(void) @@ -331,16 +423,13 @@ ao_send_location(void) { telemetry.generic.type = AO_TELEMETRY_LOCATION; ao_mutex_get(&ao_gps_mutex); - ao_xmemcpy(&telemetry.location.flags, - &ao_gps_data.flags, - 26); -#if HAS_TRACKER - telemetry.location.state = ao_flight_state | AO_GPS_STATE_VALID; -#endif - telemetry.location.tick = ao_gps_tick; + memcpy(telemetry_bits(&telemetry.location), + telemetry_bits(&ao_gps_data), + telemetry_size()); + telemetry.location.tick = (uint16_t) ao_gps_tick; ao_mutex_put(&ao_gps_mutex); - ao_radio_send(&telemetry, sizeof (telemetry)); - ao_telemetry_loc_cur = ao_telemetry_config_max; + ao_telemetry_loc_cur = ao_telemetry_gps_max; + ao_telemetry_send(); } } @@ -352,45 +441,67 @@ ao_send_satellite(void) telemetry.generic.type = AO_TELEMETRY_SATELLITE; ao_mutex_get(&ao_gps_mutex); telemetry.satellite.channels = ao_gps_tracking_data.channels; - ao_xmemcpy(&telemetry.satellite.sats, + memcpy(&telemetry.satellite.sats, &ao_gps_tracking_data.sats, AO_MAX_GPS_TRACKING * sizeof (struct ao_telemetry_satellite_info)); ao_mutex_put(&ao_gps_mutex); - ao_radio_send(&telemetry, sizeof (telemetry)); - ao_telemetry_sat_cur = ao_telemetry_config_max; + ao_telemetry_sat_cur = ao_telemetry_gps_max; + ao_telemetry_send(); } } #endif #if HAS_COMPANION -static __pdata int8_t ao_telemetry_companion_max; -static __pdata int8_t ao_telemetry_companion_cur; +static int16_t ao_telemetry_companion_max; +static int16_t ao_telemetry_companion_cur; static void ao_send_companion(void) { if (--ao_telemetry_companion_cur <= 0) { telemetry.generic.type = AO_TELEMETRY_COMPANION; - telemetry.companion.board_id = ao_companion_setup.board_id; + telemetry.companion.board_id = (uint8_t) ao_companion_setup.board_id; telemetry.companion.update_period = ao_companion_setup.update_period; telemetry.companion.channels = ao_companion_setup.channels; ao_mutex_get(&ao_companion_mutex); - ao_xmemcpy(&telemetry.companion.companion_data, + memcpy(&telemetry.companion.companion_data, ao_companion_data, ao_companion_setup.channels * 2); ao_mutex_put(&ao_companion_mutex); - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_companion_cur = ao_telemetry_companion_max; + ao_telemetry_send(); } } #endif -void +#if HAS_APRS +static void +ao_set_aprs_time(void) +{ + uint16_t interval = ao_config.aprs_interval; + + if ((ao_gps_data.flags & AO_GPS_DATE_VALID) && interval != 0) { + int second = (ao_gps_data.second / interval + 1) * interval + ao_config.aprs_offset; + int delta; + if (second >= 60) { + second = ao_config.aprs_offset; + delta = second + 60 - ao_gps_data.second; + } else { + delta = second - ao_gps_data.second; + } + ao_aprs_time = ao_gps_tick + AO_SEC_TO_TICKS(delta); + } else { + ao_aprs_time += AO_SEC_TO_TICKS(ao_config.aprs_interval); + } +} +#endif + +static void ao_telemetry(void) { - uint16_t time; - int16_t delay; + AO_TICK_TYPE time; + AO_TICK_SIGNED delay; ao_config_get(); if (!ao_config.radio_enable) @@ -398,101 +509,133 @@ ao_telemetry(void) while (!ao_flight_number) ao_sleep(&ao_flight_number); + ao_telemetry_flight_number = ao_flight_number; +#if HAS_LOG + if (ao_log_full()) + ao_telemetry_flight_number = 0; +#endif telemetry.generic.serial = ao_serial_number; for (;;) { while (ao_telemetry_interval == 0) ao_sleep(&telemetry); time = ao_time(); + ao_telemetry_time = time; #if HAS_RDF ao_rdf_time = time; #endif #if HAS_APRS ao_aprs_time = time; + ao_set_aprs_time(); #endif while (ao_telemetry_interval) { -#if HAS_APRS + time = ao_time() + AO_SEC_TO_TICKS(100); +#ifndef SIMPLIFY if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY)) #endif { -#ifdef AO_SEND_ALL_BARO - ao_send_baro(); +#ifndef SIMPLIFY + if ( (int16_t) (ao_time() - ao_telemetry_time) >= 0) #endif - -#if HAS_FLIGHT + { + ao_telemetry_time = ao_time() + ao_telemetry_interval; # ifdef AO_SEND_MEGA - ao_send_mega_sensor(); - ao_send_mega_data(); + ao_send_mega_sensor(); + ao_send_mega_data(); # endif # ifdef AO_SEND_METRUM - ao_send_metrum_sensor(); - ao_send_metrum_data(); + ao_send_metrum_sensor(); + ao_send_metrum_data(); # endif # ifdef AO_SEND_MINI - ao_send_mini(); + ao_send_mini(); # endif # ifdef AO_TELEMETRY_SENSOR - ao_send_sensor(); + ao_send_sensor(); # endif -#endif /* HAS_FLIGHT */ - #if HAS_COMPANION - if (ao_companion_running) - ao_send_companion(); + if (ao_companion_running) + ao_send_companion(); #endif - ao_send_configuration(); #if HAS_GPS - ao_send_location(); - ao_send_satellite(); + ao_send_location(); + ao_send_satellite(); +#endif + ao_send_configuration(); + } +#ifndef SIMPLIFY + time = ao_telemetry_time; #endif } -#ifndef AO_SEND_ALL_BARO #if HAS_RDF - if (ao_rdf && -#if HAS_APRS - !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) && -#endif /* HAS_APRS */ - (int16_t) (ao_time() - ao_rdf_time) >= 0) + if (ao_rdf +#ifndef SIMPLIFY + && !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) +#endif + ) { + if ((int16_t) (ao_time() - ao_rdf_time) >= 0) { #if HAS_IGNITE_REPORT - uint8_t c; -#endif /* HAS_IGNITE_REPORT */ - ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; + uint8_t c; +#endif + ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; #if HAS_IGNITE_REPORT - if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter())) - ao_radio_continuity(c); - else -#endif /* HAS_IGNITE_REPORT*/ - ao_radio_rdf(); + if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter())) + ao_radio_continuity(c); + else +#endif + ao_radio_rdf(); + } +#ifndef SIMPLIFY + if ((int16_t) (time - ao_rdf_time) > 0) + time = ao_rdf_time; +#endif } #endif /* HAS_RDF */ #if HAS_APRS - if (ao_config.aprs_interval != 0 && - (int16_t) (ao_time() - ao_aprs_time) >= 0) - { - ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval); - ao_aprs_send(); + if (ao_config.aprs_interval != 0) { + if ((int16_t) (ao_time() - ao_aprs_time) >= 0) { + ao_set_aprs_time(); + ao_aprs_send(); + } + if ((int16_t) (time - ao_aprs_time) > 0) + time = ao_aprs_time; } #endif /* HAS_APRS */ -#endif /* !AO_SEND_ALL_BARO */ - time += ao_telemetry_interval; - delay = time - ao_time(); + delay = (AO_TICK_SIGNED) (time - ao_time()); if (delay > 0) { - ao_alarm(delay); - ao_sleep(&telemetry); - ao_clear_alarm(); + ao_sleep_for(&telemetry, (AO_TICK_TYPE) delay); } - else - time = ao_time(); } } } +#if HAS_RADIO_RATE +void +ao_telemetry_reset_interval(void) +{ + ao_telemetry_set_interval(ao_telemetry_desired_interval); +} +#endif + void ao_telemetry_set_interval(uint16_t interval) { - int8_t cur = 0; + int16_t cur = 0; + +#if HAS_RADIO_RATE + /* Limit max telemetry rate based on available radio bandwidth. + */ + static const uint16_t min_interval[] = { + /* [AO_RADIO_RATE_38400] = */ AO_MS_TO_TICKS(100), + /* [AO_RADIO_RATE_9600] = */ AO_MS_TO_TICKS(500), + /* [AO_RADIO_RATE_2400] = */ AO_MS_TO_TICKS(1000) + }; + + ao_telemetry_desired_interval = interval; + if (interval && interval < min_interval[ao_config.radio_rate]) + interval = min_interval[ao_config.radio_rate]; +#endif ao_telemetry_interval = interval; - #if AO_SEND_MEGA if (interval > 1) ao_telemetry_mega_data_max = 1; @@ -503,7 +646,7 @@ ao_telemetry_set_interval(uint16_t interval) ao_telemetry_mega_data_cur = cur; #endif #if AO_SEND_METRUM - ao_telemetry_metrum_data_max = AO_SEC_TO_TICKS(1) / interval; + ao_telemetry_metrum_data_max = (int16_t) (AO_SEC_TO_TICKS(1) / interval); if (ao_telemetry_metrum_data_max > cur) cur++; ao_telemetry_metrum_data_cur = cur; @@ -512,27 +655,37 @@ ao_telemetry_set_interval(uint16_t interval) #if HAS_COMPANION if (!ao_companion_setup.update_period) ao_companion_setup.update_period = AO_SEC_TO_TICKS(1); - ao_telemetry_companion_max = ao_companion_setup.update_period / interval; + ao_telemetry_companion_max = (int16_t) (ao_companion_setup.update_period / interval); if (ao_telemetry_companion_max > cur) cur++; ao_telemetry_companion_cur = cur; #endif - ao_telemetry_config_max = AO_SEC_TO_TICKS(1) / interval; -#if HAS_COMPANION - if (ao_telemetry_config_max > cur) - cur++; - ao_telemetry_config_cur = cur; -#endif - #if HAS_GPS - if (ao_telemetry_config_max > cur) + ao_telemetry_gps_max = (int16_t) (AO_SEC_TO_TICKS(1) / interval); + if (ao_telemetry_gps_max > cur) cur++; ao_telemetry_loc_cur = cur; - if (ao_telemetry_config_max > cur) + if (ao_telemetry_gps_max > cur) cur++; ao_telemetry_sat_cur = cur; #endif + + ao_telemetry_config_max = (int16_t) (AO_SEC_TO_TICKS(5) / interval); + if (ao_telemetry_config_max > cur) + cur++; + ao_telemetry_config_cur = cur; + +#ifndef SIMPLIFY + ao_telemetry_time = +#if HAS_RDF + ao_rdf_time = +#endif +#if HAS_APRS + ao_aprs_time = +#endif + ao_time(); +#endif ao_wakeup(&telemetry); } @@ -549,7 +702,7 @@ ao_rdf_set(uint8_t rdf) } #endif -__xdata struct ao_task ao_telemetry_task; +struct ao_task ao_telemetry_task; void ao_telemetry_init()