diff --git a/firmware/Peripherals.md b/firmware/Peripherals.md index 00ddfa7..9820366 100644 --- a/firmware/Peripherals.md +++ b/firmware/Peripherals.md @@ -34,7 +34,7 @@ | --- | --- | --- | --- |TC0_IRQn|telemetry tick timer|0|latency critical for symbol timing. rate <= 1200Hz |[GPS_SERCOM]_IRQn|gps usart rx|1|latency not so critical. rate <= 960Hz -|EIC_IRQn|timepulse|1|latency not so critical. rate = 2 +|EIC_IRQn|timepulse|1|latency not so critical. rate = 1 |TC2_IRQn|xosc measurement done|2|latency not critical diff --git a/firmware/inc/cron.h b/firmware/inc/cron.h new file mode 100644 index 0000000..8ac4f95 --- /dev/null +++ b/firmware/inc/cron.h @@ -0,0 +1,39 @@ +/* + * Cron job for the system + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CRON_H +#define CRON_H + +typedef struct tracker_time { + uint64_t epoch; + uint16_t year; + uint8_t month, day, hour, minute, second; + uint8_t valid; +} tracker_time; + +void do_cron(void); +void cron_tick(void); +void cron_init(void); + +#endif /* CRON_H */ diff --git a/firmware/inc/data.h b/firmware/inc/data.h new file mode 100644 index 0000000..e7a2505 --- /dev/null +++ b/firmware/inc/data.h @@ -0,0 +1,58 @@ +/* + * Collects data from sensors etc into a struct + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef DATA_H +#define DATA_H + +#include "samd20.h" +#include "cron.h" + +/** + * Structure for all the information in each datapoint. + * + * Size is approx 40 bytes + */ +typedef struct tracker_datapoint { + /* Time */ + struct tracker_time time; + + /* Position */ + uint32_t latitude; /* 100 nanodeg */ + uint32_t longitude; /* 100 nanodeg */ + uint32_t altitude; /* mm */ + uint8_t satillite_count; /* */ + + /* Sensors */ + float battery; /* Volts */ + float temperature; /* ÂșC */ + uint32_t xosc_error; /* Hertz */ + +} tracker_datapoint; + + +void collect_data_async(void); +struct tracker_datapoint* collect_data(void); +void data_init(void); + +#endif /* DATA_H */ diff --git a/firmware/inc/hw_config.h b/firmware/inc/hw_config.h index dce5d81..aff49a1 100644 --- a/firmware/inc/hw_config.h +++ b/firmware/inc/hw_config.h @@ -147,14 +147,12 @@ * Telemetry */ #define TELEMETRY_FREQUENCY 434600000 -#define TELEMETRY_INTERVAL 30 #define TELEMETRY_POWER RF_POWER_8dBm /** * APRS */ #define APRS_ENABLE 1 -#define APRS_INTERVAL 180 #define APRS_POWER RF_POWER_14dBm /** @@ -186,4 +184,5 @@ #define TC2_INT_PRIO 2 /* XOSC Measure Timer */ + #endif /* HW_CONFIG_H */ diff --git a/firmware/inc/pips.h b/firmware/inc/pips.h index e8633da..f8a7257 100644 --- a/firmware/inc/pips.h +++ b/firmware/inc/pips.h @@ -26,13 +26,11 @@ #define PIPS_H /** - * 10ms pips, once per second + * 50ms pips, once per second */ #define PIPS_RATE 1 #define PIPS_LENGTH_MS 50 - -#define PIPS_ON_FREQUENCY (1000 / PIPS_LENGTH_MS) -#define PIPS_OFF_FREQUENCY PIPS_RATE +#define PIPS_FREQUENCY (1000 / PIPS_LENGTH_MS) #endif /* PIPS_H */ diff --git a/firmware/inc/rf_tests.h b/firmware/inc/rf_tests.h index 9298f40..658ac1b 100644 --- a/firmware/inc/rf_tests.h +++ b/firmware/inc/rf_tests.h @@ -33,7 +33,7 @@ enum rf_tests { RF_TEST_TELEMETRY_TONE, }; -#define RF_TEST RF_TEST_APRS +#define RF_TEST RF_TEST_NONE #include "samd20.h" diff --git a/firmware/inc/telemetry.h b/firmware/inc/telemetry.h index 1363f94..64c462d 100644 --- a/firmware/inc/telemetry.h +++ b/firmware/inc/telemetry.h @@ -48,7 +48,6 @@ int telemetry_active(void); int telemetry_start(enum telemetry_t type, int32_t length); int telemetry_start_rsid(rsid_code_t rsid); void telemetry_aprs_set_frequency(int32_t frequency); -void telemetry_request_stop(void); float telemetry_si_temperature(void); float timer0_tick_init(float frequency); diff --git a/firmware/inc/ubx_messages.h b/firmware/inc/ubx_messages.h index a2cfb61..8f5062d 100644 --- a/firmware/inc/ubx_messages.h +++ b/firmware/inc/ubx_messages.h @@ -285,4 +285,14 @@ __PACKED__ struct ubx_nav_status { } payload; }; +/** + * UBX TIMEUTC valid flags + */ +enum { + UBX_TIMEUTC_VALID_TOW = (1 << 0), + UBX_TIMEUTC_VALID_WKN = (1 << 1), + UBX_TIMEUTC_VALID_UTC = (1 << 2), +}; + + #endif /* UBX_MESSAGES_H */ diff --git a/firmware/src/cron.c b/firmware/src/cron.c new file mode 100644 index 0000000..a0c45f1 --- /dev/null +++ b/firmware/src/cron.c @@ -0,0 +1,144 @@ +/* + * Cron job for the system + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "samd20.h" +#include "cron.h" +#include "gps.h" +#include "ubx_messages.h" +#include "data.h" +#include "hw_config.h" + +/* Internal time representation */ +struct tracker_time time; + +/* Pointer to latest datapoint */ +struct tracker_datapoint* dp; + + +void rtty_telemetry(struct tracker_datapoint* dp); +void contestia_telemetry(struct tracker_datapoint* dp); +void aprs_telemetry(struct tracker_datapoint* dp); +void pips_telemetry(void); + + +/** + * Reads current time from the GPS + */ +void read_gps_time(void) +{ + /* GPS Time */ + gps_update_time(); + + /* Sleep Wait */ + while (gps_update_time_pending()) { + system_sleep(); + } + + /* Time */ + struct ubx_nav_timeutc gt = gps_get_nav_timeutc(); + time.year = gt.payload.year; + time.month = gt.payload.month; + time.day = gt.payload.day; + time.hour = gt.payload.hour; + time.minute = gt.payload.min; + time.second = gt.payload.sec; + time.valid = gt.payload.valid; + + /* TODO calculate epoch time here */ +} + +/** + * Cron job for the system. + * + * Run at the top of the second but may take longer than a second + */ +void do_cron(void) +{ + /* ---- Local representation of the time ---- */ + struct tracker_time t; + memcpy(&t, &time, sizeof(struct tracker_time)); + + /* ---- Data every 30 seconds ---- */ + if ((time.second % 30) == 0) { + dp = collect_data(); + memcpy(&dp->time, &t, sizeof(struct tracker_time)); + } else if ((time.second % 30) == 20) { + collect_data_async(); + } + + + /* ---- Telemetry output ---- */ + /* RTTY */ + if (time.second == 0) { + rtty_telemetry(dp); + + /* Contestia */ + } else if (time.second == 30) { + contestia_telemetry(dp); + + /* APRS */ /* LIMIT CONTESTIA PACKET LENGTH */ +#ifdef APRS_ENABLE + } else if ((time.minute % 2) == 0 && time.second == 55) { + aprs_telemetry(dp); +#endif + /* Pips */ + } else if ((time.second % 1) == 0) { + pips_telemetry(); + + } +} + +/** + * Called in an interrupt, increments internal time representation + */ +void cron_tick(void) { + + /* Update time internally */ + time.epoch++; time.second++; + if (time.second > 60) { + time.second = 0; time.minute++; + if (time.minute > 60) { + time.minute = 0; time.hour++; + if (time.hour > 23) { + time.hour = 0; + } + } + } + + /* Update internal time from GPS */ + /* We do this just after midnight or if time is yet to set UTC exactly */ + if (((time.hour == 0) && (time.minute == 0) && (time.second == 5)) || + ((time.second == 5) && !(time.valid & UBX_TIMEUTC_VALID_UTC))) { + + /* Be careful not a call this while the collect_data function is running */ + read_gps_time(); + } +} + +void cron_init(void) +{ + memset(&time, 0, sizeof(struct tracker_time)); +} diff --git a/firmware/src/data.c b/firmware/src/data.c new file mode 100644 index 0000000..b582ebb --- /dev/null +++ b/firmware/src/data.c @@ -0,0 +1,97 @@ +/* + * Collects data from sensors etc into a struct + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "samd20.h" +#include "data.h" +#include "xosc.h" +#include "hw_config.h" +#include "analogue.h" +#include "gps.h" +#include "ubx_messages.h" +#include "telemetry.h" + +struct tracker_datapoint datapoint; + +void xosc_measure_callback(uint32_t result) +{ + datapoint.xosc_error = result - XOSC_FREQUENCY; +} + + +/** + * Collect data asynchronously + */ +void collect_data_async(void) +{ + /* Measure XOSC against gps timepulse */ + measure_xosc(XOSC_MEASURE_TIMEPULSE, xosc_measure_callback); +} +/** + * Collect Data synchronously and return datapoint + */ +struct tracker_datapoint* collect_data(void) +{ + /** + * ---- Analogue ---- + */ + datapoint.battery = get_battery(); + datapoint.temperature = telemetry_si_temperature(); + + + /** + * ---- GPS ---- + */ + gps_update_position(); + + /* Wait for the gps update */ + while (gps_update_position_pending()) { + system_sleep(); + } + + /* GPS Status */ + struct ubx_nav_sol sol = gps_get_nav_sol(); + datapoint.satillite_count = sol.payload.numSV; + + /* GPS Position */ + if (gps_is_locked()) { + struct ubx_nav_posllh pos = gps_get_nav_posllh(); + + datapoint.latitude = pos.payload.lat; + datapoint.longitude = pos.payload.lon; + datapoint.altitude = pos.payload.height; +} + + /* GPS Powersave */ + gps_set_powersave_auto(); + +return &datapoint; +} + + +void data_init(void) +{ + memset(&datapoint, 0, sizeof(struct tracker_datapoint)); +} diff --git a/firmware/src/init.c b/firmware/src/init.c index 7ac258d..022872e 100644 --- a/firmware/src/init.c +++ b/firmware/src/init.c @@ -33,6 +33,8 @@ #include "watchdog.h" #include "xosc.h" #include "timer.h" +#include "cron.h" +#include "data.h" /** * Initialises the status LED. SHOULD TURN ON THE LED @@ -53,7 +55,7 @@ void powermananger_init(void) { system_apb_clock_clear_mask(SYSTEM_CLOCK_APB_APBA, // PM_APBAMASK_EIC | /* EIC is used now */ -// PM_APBAMASK_RTC | /* RTC is used now */ + PM_APBAMASK_RTC | 0); } @@ -104,7 +106,7 @@ void init(timepulse_callback_t callback) system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2); /* Disable CPU, AHB and APB */ /* Configure the Power Manager */ - //powermananger_init(); + powermananger_init(); /** * System initialisation @@ -123,4 +125,8 @@ void init(timepulse_callback_t callback) /* Initialise Si4060 interface */ si_trx_init(); + + /* Data and Cron structures */ + data_init(); + cron_init(); } diff --git a/firmware/src/main.c b/firmware/src/main.c index 88ab83b..793621d 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -27,145 +27,110 @@ #include #include "samd20.h" -#include "semihosting.h" #include "hw_config.h" -#include "system/system.h" -#include "sercom/usart.h" -#include "system/port.h" -#include "system/extint.h" -#include "tc/tc_driver.h" #include "init.h" #include "gps.h" #include "mfsk.h" -#include "ubx_messages.h" #include "watchdog.h" -#include "xosc.h" #include "telemetry.h" #include "timer.h" #include "contestia.h" -#include "rsid.h" #include "aprs.h" #include "location.h" -#include "si_trx.h" -#include "si_trx_defs.h" -#include "analogue.h" -#include "spi_bitbang.h" -#include "system/interrupt.h" #include "rf_tests.h" +#include "data.h" #define CALLSIGN "UBSEDSx" -void xosc_measure_callback(uint32_t result); -void timepulse_callback(uint32_t sequence); - -int32_t _xosc_error = 0; - /** - * Telemetry String - * ============================================================================= + * Formats a UKHAS telemetry string for the given datapoint + * + * The telemetry string starts with the specified number of dollar signs */ -void output_telemetry_string(enum telemetry_t type) +uint16_t format_telemetry_string(char* string, struct tracker_datapoint* dp, + uint8_t dollars) { double lat_fmt = 0.0; double lon_fmt = 0.0; uint32_t altitude = 0; uint16_t len; - uint8_t dollars = 2; - /** - * Collect Data - * --------------------------------------------------------------------------- - */ - - /* Analogue */ - float battery = get_battery(); - float temperature = telemetry_si_temperature(); - - /* GPS Time */ - gps_update_time(); - - /* Sleep Wait */ - while (gps_update_time_pending()) { - system_sleep(); - } - - /* Time */ - struct ubx_nav_timeutc time = gps_get_nav_timeutc(); - uint8_t hours = time.payload.hour; - uint8_t minutes = time.payload.min; - uint8_t seconds = time.payload.sec; - - /* Request updates from the gps */ - gps_update_position(); - if (gps_is_locked()) { - led_on(); - } else { - led_off(); - } - - /* Wait for the gps update */ - while (gps_update_position_pending()) { - system_sleep(); - } - - if (gps_is_locked()) { - led_off(); - } else { - led_on(); - } - - /* GPS Status */ - struct ubx_nav_sol sol = gps_get_nav_sol(); - uint8_t satillite_count = sol.payload.numSV; - - /* GPS Position */ - if (gps_is_locked()) { - struct ubx_nav_posllh pos = gps_get_nav_posllh(); - lat_fmt = (double)pos.payload.lat / 10000000.0; - lon_fmt = (double)pos.payload.lon / 10000000.0; - altitude = pos.payload.height / 1000; - } - - /* GPS Powersave */ - gps_set_powersave_auto(); - - /** - * Format - * --------------------------------------------------------------------------- - */ - - if (type == TELEMETRY_RTTY) { - dollars = 5; // Extra dollars for RTTY - } + lat_fmt = (double)dp->latitude / 10000000.0; /* degrees */ + lon_fmt = (double)dp->longitude / 10000000.0; /* degrees */ + altitude = dp->altitude / 1000; /* meters */ /* sprintf - preamble */ - memset(telemetry_string, '$', dollars); + memset(string, '$', dollars); len = dollars; /* sprintf - full string */ len += sprintf(telemetry_string + len, - "%s,%02u:%02u:%02u,%02.5f,%03.5f,%ld,%u,%.2f,%.1f,%ld", - CALLSIGN, hours, minutes, seconds, lat_fmt, lon_fmt, - altitude, satillite_count, battery, temperature, _xosc_error); - - if (type == TELEMETRY_CONTESTIA) { contestiaize(telemetry_string + dollars); } + "%s,%02u:%02u:%02u,%02.5f,%03.5f,%ld,%u,%.2f,%.1f,%ld", + CALLSIGN, + dp->time.hour, dp->time.minute, dp->time.second, + lat_fmt, lon_fmt, altitude, dp->satillite_count, + dp->battery, dp->temperature, dp->xosc_error); /* sprintf - checksum. don't include dollars */ len += sprintf(telemetry_string + len, "*%04X\r", crc_checksum(telemetry_string + dollars)); + /* Length should be no more than 100 characters!! */ + if (len <= 100) { + return len; + } + + /* Okay, let's use a shorter backup format */ + len = dollars; + + /* sprintf - short format */ + len += sprintf(telemetry_string + len, + "%s,%02u:%02u:%02u,%02.5f,%03.5f,%ld", + CALLSIGN, + dp->time.hour, dp->time.minute, dp->time.second, + lat_fmt, lon_fmt, altitude); + + /* sprintf - checksum. don't include dollars */ + len += sprintf(telemetry_string + len, + "*%04X\r", + crc_checksum(telemetry_string + dollars)); + + return len; +} /** - * Starting up the radio blocks on high-prio interrupt for ~100ms: todo fixme + * RTTY telemetry. Uses 5 dollar symbols */ +#define RTTY_DOLLARS 5 +void rtty_telemetry(struct tracker_datapoint* dp) { + uint16_t len; + + len = format_telemetry_string(telemetry_string, dp, RTTY_DOLLARS); + + /* Main telemetry */ + telemetry_start(TELEMETRY_RTTY, len); + + /* Sleep Wait for main telemetry */ + while (telemetry_active()) { + system_sleep(); + } +} +/** + * Contestia telemetry. Uses 2 dollar symbols + */ +#define CONTESTIA_DOLLARS 2 +void contestia_telemetry(struct tracker_datapoint* dp) { + uint16_t len; + + len = format_telemetry_string(telemetry_string, dp, CONTESTIA_DOLLARS); + + /* Reduce character set */ + contestiaize(telemetry_string + CONTESTIA_DOLLARS); /* RSID */ - /* start - SI NOW BELONGS TO TELEMETRY, WE CANNOT ACCESS */ - if (type == TELEMETRY_CONTESTIA) { - telemetry_start_rsid(RSID_CONTESTIA_32_1000); - } + telemetry_start_rsid(RSID_CONTESTIA_32_1000); /* Sleep Wait for RSID */ while (telemetry_active()) { @@ -173,22 +138,23 @@ void output_telemetry_string(enum telemetry_t type) } /* Main telemetry */ - telemetry_start(type, len); + telemetry_start(TELEMETRY_CONTESTIA, len); /* Sleep Wait for main telemetry */ while (telemetry_active()) { system_sleep(); } } - -void aprs_telemetry(void) { +/** + * APRS telemetry if required + */ +void aprs_telemetry(struct tracker_datapoint* dp) { if (!gps_is_locked()) return; /* Don't bother with no GPS */ - struct ubx_nav_posllh pos = gps_get_nav_posllh(); - float lat = (float)pos.payload.lat / 10000000.0; // This division is from the gps reciver, not for geofence - float lon = (float)pos.payload.lon / 10000000.0; - uint32_t altitude = pos.payload.height / 1000; + float lat = (float)dp->latitude / 10000000.0; /* degrees */ + float lon = (float)dp->longitude / 10000000.0; /* degrees */ + uint32_t altitude = dp->altitude / 1000; /* meters */ /* Update location */ aprs_location_update(lon, lat, altitude); @@ -209,37 +175,34 @@ void aprs_telemetry(void) { } } } - - -void xosc_measure_callback(uint32_t result) +/** + * Pips telemetry + */ +void pips_telemetry(void) { - _xosc_error = result - XOSC_FREQUENCY; + /* Pips */ + telemetry_start(TELEMETRY_PIPS, 0xFFFF); + + while (telemetry_active()) { + system_sleep(); + } } -uint32_t telemetry_interval_count = TELEMETRY_INTERVAL; -uint32_t aprs_interval_count = APRS_INTERVAL; -uint8_t telemetry_trigger_flag = 0; -uint8_t aprs_trigger_flag = 0; +uint8_t tick_flag = 0; /** - * Called by the timer at 1Hz + * Called at 1Hz by the GPS */ -void timepulse_callback(uint32_t sequence) +void gps_tick(uint32_t sequence) { - telemetry_interval_count++; - aprs_interval_count++; + /* Sequence not used */ + (void)sequence; - /* Runs at the rate of telemetry packets */ - if (telemetry_interval_count >= TELEMETRY_INTERVAL) { - telemetry_interval_count = 0; - telemetry_trigger_flag = 1; - } + /* Update internal time representation */ + cron_tick(); - /* Runs at the rate of aprs packets */ - if (aprs_interval_count >= APRS_INTERVAL) { - aprs_interval_count = 0; - aprs_trigger_flag = 1; - } + /* Raise the tick flag */ + tick_flag = 1; } /** @@ -248,9 +211,8 @@ void timepulse_callback(uint32_t sequence) */ int main(void) { - uint32_t telemetry_alternate = 0; - - init(timepulse_callback); + /* Init */ + init(gps_tick); /* Maybe do some rf tests */ rf_tests(); @@ -259,35 +221,12 @@ int main(void) led_off(); while (1) { - /* Send a packet */ - output_telemetry_string((telemetry_alternate++ & 1) ? - TELEMETRY_CONTESTIA : - TELEMETRY_RTTY); - - /* Maybe aprs? */ -#if APRS_ENABLE - if (aprs_trigger_flag) { - aprs_telemetry(); + /* Run cron job */ + if (tick_flag) { + tick_flag = 0; do_cron(); } - aprs_trigger_flag = 0; -#endif - /* Pips */ - telemetry_start(TELEMETRY_PIPS, 0xFFFF); - - /* Measure XOSC against gps timepulse */ - measure_xosc(XOSC_MEASURE_TIMEPULSE, xosc_measure_callback); - - /* Sleep wait for next telemetry */ - while (telemetry_trigger_flag == 0) { - system_sleep(); - } - telemetry_trigger_flag = 0; - - /* End pips */ - telemetry_request_stop(); - while (telemetry_active()) { - system_sleep(); - } + /* Idle */ + system_sleep(); } } diff --git a/firmware/src/telemetry.c b/firmware/src/telemetry.c index d5dc309..66db780 100644 --- a/firmware/src/telemetry.c +++ b/firmware/src/telemetry.c @@ -106,10 +106,6 @@ int32_t telemetry_string_length = 0; * Where we are in the current output */ int32_t telemetry_index; -/** - * Should we stop? - */ -uint8_t telemetry_stop_flag = 0; /** * Is the radio currently on? */ @@ -142,7 +138,6 @@ int telemetry_start(enum telemetry_t type, int32_t length) { telemetry_type = type; telemetry_index = 0; telemetry_string_length = length; - telemetry_stop_flag = 0; /* Setup timer tick */ switch(telemetry_type) { @@ -153,7 +148,7 @@ int telemetry_start(enum telemetry_t type, int32_t length) { timer0_tick_init(RTTY_BITRATE); break; case TELEMETRY_PIPS: - timer0_tick_init(PIPS_OFF_FREQUENCY); + timer0_tick_init(PIPS_FREQUENCY); break; case TELEMETRY_APRS: timer0_tick_init(AX25_TICK_RATE); @@ -207,7 +202,6 @@ float telemetry_si_temperature(void) { void telemetry_stop(void) { /* All done, deactivate */ telemetry_string_length = 0; - telemetry_stop_flag = 0; /* Turn radio off */ if (radio_on) { @@ -222,7 +216,7 @@ void telemetry_stop(void) { timer0_tick_deinit(); } uint8_t is_telemetry_finished(void) { - if (telemetry_index >= telemetry_string_length || telemetry_stop_flag) { + if (telemetry_index >= telemetry_string_length) { /* Finish telemetry */ telemetry_stop(); @@ -230,16 +224,6 @@ uint8_t is_telemetry_finished(void) { } return 0; } -/** - * Stops the ongoing telemetry at the earliest possible moment (end of - * symbol / block). - */ -void telemetry_request_stop(void) { - if (telemetry_active()) { - telemetry_stop_flag = 1; - } -} - /** @@ -338,8 +322,7 @@ void telemetry_tick(void) { if (!aprs_tick()) { /* Transmission Finished */ - telemetry_request_stop(); - if (is_telemetry_finished()) return; + telemetry_stop(); } break; @@ -350,14 +333,11 @@ void telemetry_tick(void) { /* Pips: Cw */ si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER); radio_on = 1; - timer0_tick_frequency(PIPS_ON_FREQUENCY); } else { /* Turn off */ si_trx_off(); radio_on = 0; - timer0_tick_frequency(PIPS_OFF_FREQUENCY); - telemetry_index++; - if (is_telemetry_finished()) return; + telemetry_stop(); } break; }