From 4a5b3837b460d1b6fcea99312728114c4734495a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 6 Feb 2014 17:08:34 -0800 Subject: altos: report 0/0/0 for APRS position when GPS is not locked We were reporting whatever the GPS device sent, even if it wasn't reporting a valid status. That's not terribly useful. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 56d98437..25a651ca 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -515,13 +515,19 @@ static int tncComment(uint8_t *buf) */ static int tncPositionPacket(void) { - int32_t latitude = ao_gps_data.latitude; - int32_t longitude = ao_gps_data.longitude; - int32_t altitude = ao_gps_data.altitude; + int32_t latitude = 0; + int32_t longitude = 0; + int32_t altitude = 0; uint8_t *buf; - if (altitude < 0) - altitude = 0; + if (ao_gps_data.flags & AO_GPS_VALID) { + latitude = ao_gps_data.latitude; + longitude = ao_gps_data.longitude; + altitude = ao_gps_data.altitude; + if (altitude < 0) + altitude = 0; + } + altitude = (altitude * (int32_t) 10000 + (3048/2)) / (int32_t) 3048; buf = tncBuffer; -- cgit v1.2.3 From 7a8adfed8fbbcaac71da9c6d54bbd3091f4d7511 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Mar 2013 10:16:35 -0700 Subject: altos: Add watchdog timer task This new task frobs a pin periodically to inform the hardware that the operating system is running. Signed-off-by: Keith Packard --- src/drivers/ao_watchdog.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ src/drivers/ao_watchdog.h | 24 ++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/drivers/ao_watchdog.c create mode 100644 src/drivers/ao_watchdog.h (limited to 'src/drivers') diff --git a/src/drivers/ao_watchdog.c b/src/drivers/ao_watchdog.c new file mode 100644 index 00000000..096a5564 --- /dev/null +++ b/src/drivers/ao_watchdog.c @@ -0,0 +1,62 @@ +/* + * Copyright © 2013 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; version 2 of the License. + * + * 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 + +static int ao_watchdog_enabled = TRUE; + +static void +ao_watchdog(void) +{ + for (;;) { + while (!ao_watchdog_enabled) + ao_sleep(&ao_watchdog_enabled); + while (ao_watchdog_enabled) { + ao_delay(AO_WATCHDOG_INTERVAL); + ao_gpio_set(AO_WATCHDOG_PORT, AO_WATCHDOG_BIT, AO_WATCHDOG_PIN, 1); + ao_delay(1); + ao_gpio_set(AO_WATCHDOG_PORT, AO_WATCHDOG_BIT, AO_WATCHDOG_PIN, 0); + } + } +} + +static void +ao_watchdog_set(void) +{ + ao_cmd_hex(); + if (ao_cmd_status == ao_cmd_success) { + ao_watchdog_enabled = ao_cmd_lex_i != 0; + ao_wakeup(&ao_watchdog_enabled); + } +} + + +static __code struct ao_cmds ao_watchdog_cmds[] = { + { ao_watchdog_set, "Q <0 off, 1 on>\0Enable or disable watchdog timer" }, + { 0, NULL }, +}; + +static struct ao_task watchdog_task; + +void +ao_watchdog_init(void) +{ + ao_enable_output(AO_WATCHDOG_PORT, AO_WATCHDOG_BIT, AO_WATCHDOG, 0); + ao_cmd_register(&ao_watchdog_cmds[0]); + ao_add_task(&watchdog_task, ao_watchdog, "watchdog"); +} + diff --git a/src/drivers/ao_watchdog.h b/src/drivers/ao_watchdog.h new file mode 100644 index 00000000..73e1559d --- /dev/null +++ b/src/drivers/ao_watchdog.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2013 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; version 2 of the License. + * + * 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_WATCHDOG_H_ +#define _AO_WATCHDOG_H_ + +void +ao_watchdog_init(void); + +#endif /* _AO_WATCHDOG_H_ */ -- cgit v1.2.3 From 1d3420e51db4d1a46237e97aeb189d2a8eba7f5e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 31 Jan 2014 17:44:45 -0800 Subject: altos: Eliminate warnings in FAT code The FAT file system code wasn't cleaned up when the warning fixes were done recently. Signed-off-by: Keith Packard --- src/drivers/ao_bufio.c | 2 +- src/drivers/ao_fat.c | 23 ++++++++++++----------- src/drivers/ao_sdcard.c | 20 +++++++++----------- 3 files changed, 22 insertions(+), 23 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_bufio.c b/src/drivers/ao_bufio.c index c0fe604a..70e30b67 100644 --- a/src/drivers/ao_bufio.c +++ b/src/drivers/ao_bufio.c @@ -45,7 +45,7 @@ static uint8_t ao_bufio_mutex; #if 0 #define DBG(...) printf(__VA_ARGS__) #else -#define DBG(...) +#define DBG(...) (void) 0 #endif static inline void diff --git a/src/drivers/ao_fat.c b/src/drivers/ao_fat.c index 1a1b8eb0..cbcd42bc 100644 --- a/src/drivers/ao_fat.c +++ b/src/drivers/ao_fat.c @@ -187,7 +187,7 @@ _ao_fat_entry_replace(cluster_t cluster, cluster_t new_value) sector_t sector; cluster_offset_t offset; uint8_t *buf; - cluster_t ret; + cluster_t ret = 0; cluster_t old_value; uint8_t fat; @@ -747,7 +747,7 @@ _ao_fat_current_sector(struct ao_file *file) DBG("current sector offset %d size %d\n", file->offset, file->dirent->size); - if (file->offset > file->dirent->size) { + if (file->offset > (offset_t) file->dirent->size) { printf ("file offset %d larger than size %d\n", file->offset, file->dirent->size); return 0xffffffff; @@ -761,7 +761,7 @@ _ao_fat_current_sector(struct ao_file *file) DBG("\treset to start of file %08x\n", file->cluster); } - if (file->cluster_offset + bytes_per_cluster <= file->offset) { + if ((offset_t) (file->cluster_offset + bytes_per_cluster) <= file->offset) { cluster_t cluster_distance; cluster_offset = sector_offset / sectors_per_cluster; @@ -804,7 +804,7 @@ _ao_fat_invalidate_cluster_offset(struct ao_fat_dirent *dirent) if (!file->busy) continue; if (file->dirent == dirent) { - if (file->cluster_offset >= dirent->size) { + if (file->cluster_offset >= (offset_t) dirent->size) { file->cluster_offset = 0; file->cluster = dirent->cluster; } @@ -838,7 +838,7 @@ _ao_fat_set_size(struct ao_file *file, uint32_t size) DBG ("\tfirst cluster %08x have %d need %d\n", first_cluster, have_clusters, need_clusters); if (have_clusters != need_clusters) { - if (file->cluster && size > file->cluster_offset) { + if (file->cluster && (offset_t) size > file->cluster_offset) { cluster_t offset_clusters = (file->cluster_offset + bytes_per_cluster) / bytes_per_cluster; cluster_t extra_clusters = need_clusters - offset_clusters; cluster_t next_cluster; @@ -888,6 +888,7 @@ _ao_fat_set_size(struct ao_file *file, uint32_t size) static void _ao_fat_root_init(uint8_t *dent, char name[11], uint8_t attr) { + (void) attr; memset(dent, '\0', 0x20); memmove(dent, name, 11); @@ -1249,7 +1250,7 @@ ao_fat_read(int8_t fd, void *dst, int len) goto done; } - if (file->offset + len > file->dirent->size) + if (file->offset + len > (offset_t) file->dirent->size) len = file->dirent->size - file->offset; if (len < 0) @@ -1296,7 +1297,7 @@ ao_fat_write(int8_t fd, void *src, int len) goto done; } - if (file->offset + len > file->dirent->size) { + if (file->offset + len > (offset_t) file->dirent->size) { ret = _ao_fat_set_size(file, file->offset + len); if (ret < 0) goto done; @@ -1424,6 +1425,8 @@ done: int8_t ao_fat_rename(char old[11], char new[11]) { + (void) old; + (void) new; return -AO_FAT_EIO; } @@ -1499,7 +1502,7 @@ ao_fat_list_cmd(void) putchar('.'); for (; i < 11; i++) putchar(dirent.name[i]); - for (i = 0; i < NUM_FAT_ATTR; i++) + for (i = 0; i < (int) NUM_FAT_ATTR; i++) putchar (dirent.attr & ao_fat_attr[i].bit ? ao_fat_attr[i].label : ' '); printf (" @%08x %d\n", dirent.cluster, dirent.size); } @@ -1507,7 +1510,7 @@ ao_fat_list_cmd(void) printf ("readdir failed: %d\n", status); } -static uint8_t +static void ao_fat_parse_name(char name[11]) { uint8_t c; @@ -1560,8 +1563,6 @@ ao_fat_write_cmd(void) { static char name[11]; int8_t fd; - int cnt, i; - static char buf[64]; char c; int status; diff --git a/src/drivers/ao_sdcard.c b/src/drivers/ao_sdcard.c index 7806bc19..47188ef3 100644 --- a/src/drivers/ao_sdcard.c +++ b/src/drivers/ao_sdcard.c @@ -56,13 +56,13 @@ static enum ao_sdtype sdtype; #if SDCARD_TRACE #define DBG(...) printf(__VA_ARGS__) #else -#define DBG(...) +#define DBG(...) (void) 0 #endif #if SDCARD_WARN #define WARN(...) printf(__VA_ARGS__) #else -#define WARN(...) +#define WARN(...) (void) 0 #endif #define later(x,y) ((int16_t) ((x) - (y)) >= 0) @@ -100,7 +100,6 @@ ao_sdcard_send_cmd(uint8_t cmd, uint32_t arg) { uint8_t data[6]; uint8_t reply; - int i; uint16_t timeout; DBG ("\tsend_cmd %d arg %08x\n", cmd, arg); @@ -111,7 +110,7 @@ ao_sdcard_send_cmd(uint8_t cmd, uint32_t arg) return SDCARD_STATUS_TIMEOUT; } - data[0] = cmd & 0x3f | 0x40; + data[0] = (cmd & 0x3f) | 0x40; data[1] = arg >> 24; data[2] = arg >> 16; data[3] = arg >> 8; @@ -402,7 +401,7 @@ static uint8_t _ao_sdcard_reset(void) { int i; - uint8_t ret; + uint8_t ret = 0x3f; uint8_t response[10]; for (i = 0; i < SDCARD_IDLE_RETRY; i++) { @@ -419,12 +418,12 @@ _ao_sdcard_reset(void) */ if (ao_sdcard_send_if_cond(0x1aa, response) == SDCARD_STATUS_IDLE_STATE) { uint32_t arg = 0; - uint8_t sdver2 = 0; +// uint8_t sdver2 = 0; /* Check for SD version 2 */ if ((response[2] & 0xf) == 1 && response[3] == 0xaa) { arg = 0x40000000; - sdver2 = 1; +// sdver2 = 1; } for (i = 0; i < SDCARD_IDLE_RETRY; i++) { @@ -487,7 +486,7 @@ ao_sdcard_wait_block_start(void) uint8_t ao_sdcard_read_block(uint32_t block, uint8_t *data) { - uint8_t ret; + uint8_t ret = 0x3f; uint8_t start_block; uint8_t crc[2]; int tries; @@ -518,6 +517,7 @@ ao_sdcard_read_block(uint32_t block, uint8_t *data) WARN ("read block command failed %d status %02x\n", block, ret); status = _ao_sdcard_send_status(); WARN ("\tstatus now %04x\n", status); + (void) status; goto bail; } @@ -567,8 +567,6 @@ ao_sdcard_write_block(uint32_t block, uint8_t *data) uint8_t response[1]; uint8_t start_block[8]; uint16_t status; - static uint8_t check_data[512]; - int i; int tries; ao_sdcard_lock(); @@ -612,7 +610,7 @@ ao_sdcard_write_block(uint32_t block, uint8_t *data) if ((response[0] & SDCARD_DATA_RES_MASK) != SDCARD_DATA_RES_ACCEPTED) { int i; WARN("Data not accepted, response"); - for (i = 0; i < sizeof (response); i++) + for (i = 0; i < (int) sizeof (response); i++) WARN(" %02x", response[i]); WARN("\n"); ret = 0x3f; -- cgit v1.2.3 From 8ddbbdcdc498a19ebf4a440bbf5d73b6538e0a57 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 8 Feb 2014 20:00:56 -0800 Subject: altos: Don't write more than 12 sat infos in ublox driver This was overwriting memory past the end of the ao_gps_tracking_data array, which isn't a good idea. Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 4fb90746..01169522 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -746,18 +746,20 @@ ao_gps(void) __reentrant ao_gps_tracking_data.channels = 0; struct ao_telemetry_satellite_info *dst = &ao_gps_tracking_data.sats[0]; + struct nav_svinfo_sat *src = &nav_svinfo_sat[0]; for (i = 0; i < nav_svinfo_nsat; i++) { - struct nav_svinfo_sat *src = &nav_svinfo_sat[i]; - if (!(src->flags & (1 << NAV_SVINFO_SAT_FLAGS_UNHEALTHY)) && src->quality >= NAV_SVINFO_SAT_QUALITY_ACQUIRED) { - dst->svid = src->svid; - dst->c_n_1 = src->cno; - dst++; - ao_gps_tracking_data.channels++; + if (ao_gps_tracking_data.channels < AO_TELEMETRY_SATELLITE_MAX_SAT) { + dst->svid = src->svid; + dst->c_n_1 = src->cno; + dst++; + ao_gps_tracking_data.channels++; + } } + src++; } ao_mutex_put(&ao_gps_mutex); -- cgit v1.2.3 From 6367ab2dec718c512073f70dfab86dbd1656b1fe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 8 Feb 2014 20:02:54 -0800 Subject: altos: Report nsat in view in APRS packet This adds the number of sats in view (as opposed to the number of sats in solution) to the APRS packet. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 25a651ca..c327c897 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -488,9 +488,21 @@ static void tncCompressInt(uint8_t *dest, int32_t value, int len) { } } -#if HAS_ADC +static int ao_num_sats(void) +{ + int i; + int n = 0; + + for (i = 0; i < ao_gps_tracking_data.channels; i++) { + if (ao_gps_tracking_data.sats[i].svid) + n++; + } + return n; +} + static int tncComment(uint8_t *buf) { +#if HAS_ADC struct ao_data packet; ao_arch_critical(ao_data_get(&packet);); @@ -500,15 +512,19 @@ static int tncComment(uint8_t *buf) int16_t main = ao_ignite_decivolt(AO_SENSE_MAIN(&packet)); return sprintf((char *) buf, - "B:%d.%d A:%d.%d M:%d.%d", + "S: %d B:%d.%d A:%d.%d M:%d.%d", + ao_num_sats(), battery/10, battery % 10, apogee/10, apogee%10, main/10, main%10); -} +#else + return sprintf((char *) buf, + "S: %d", ao_num_sats()); #endif +} /** * Generate the plain text position packet. @@ -556,11 +572,7 @@ static int tncPositionPacket(void) *buf++ = 33 + ((1 << 5) | (2 << 3)); -#if HAS_ADC buf += tncComment(buf); -#else - *buf = '\0'; -#endif return buf - tncBuffer; } -- cgit v1.2.3 From 5001a0f882af53dde33fc531215944c9d727baf4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Feb 2014 22:53:05 -0800 Subject: altos: Re-send previous GPS position in APRS if lock is lost APRS radios often show only the last received APRS packet, which means that erasing the last known GPS position when we lose lock by sending 0/0/0 is unhelpful. Instead, just send the last known position, and make sure that we send 0/0/0 before we're locked the first time. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index c327c897..d472af4e 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -531,9 +531,10 @@ static int tncComment(uint8_t *buf) */ static int tncPositionPacket(void) { - int32_t latitude = 0; - int32_t longitude = 0; - int32_t altitude = 0; + static int32_t latitude; + static int32_t longitude; + static int32_t altitude; + int32_t lat, lon, alt; uint8_t *buf; if (ao_gps_data.flags & AO_GPS_VALID) { @@ -544,30 +545,29 @@ static int tncPositionPacket(void) altitude = 0; } - altitude = (altitude * (int32_t) 10000 + (3048/2)) / (int32_t) 3048; - buf = tncBuffer; *buf++ = '!'; /* Symbol table ID */ *buf++ = '/'; - latitude = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; - longitude = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; + lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; + lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; #define ALTITUDE_LOG_BASE 0.001998002662673f /* log(1.002) */ - altitude = logf((float) altitude) * (1/ALTITUDE_LOG_BASE); + alt = (altitude * (int32_t) 10000 + (3048/2)) / (int32_t) 3048; + alt = logf((float) altitude) * (1/ALTITUDE_LOG_BASE); - tncCompressInt(buf, latitude, 4); + tncCompressInt(buf, lat, 4); buf += 4; - tncCompressInt(buf, longitude, 4); + tncCompressInt(buf, lon, 4); buf += 4; /* Symbol code */ *buf++ = '\''; - tncCompressInt(buf, altitude, 2); + tncCompressInt(buf, alt, 2); buf += 2; *buf++ = 33 + ((1 << 5) | (2 << 3)); -- cgit v1.2.3 From e76948d382cf6980c3a5b6c48405d71c8811780b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Feb 2014 22:54:31 -0800 Subject: altos: Put locked/unlocked GPS status in APRS comments Replace the 'S' (which marks the field showing sats in view) with either 'L' or 'U' to tell the user whether the GPS receiver is locked or unlocked. This also removes the colons in the comment field to shorten it. This makes it fit on one line of my FT1D display. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index d472af4e..0a6c72ce 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -500,6 +500,14 @@ static int ao_num_sats(void) return n; } +static char ao_gps_locked(void) +{ + if (ao_gps_data.flags & AO_GPS_VALID) + return 'L'; + else + return 'U'; +} + static int tncComment(uint8_t *buf) { #if HAS_ADC @@ -512,7 +520,8 @@ static int tncComment(uint8_t *buf) int16_t main = ao_ignite_decivolt(AO_SENSE_MAIN(&packet)); return sprintf((char *) buf, - "S: %d B:%d.%d A:%d.%d M:%d.%d", + "%c%d B%d.%d A%d.%d M%d.%d", + ao_gps_locked(), ao_num_sats(), battery/10, battery % 10, @@ -522,7 +531,9 @@ static int tncComment(uint8_t *buf) main%10); #else return sprintf((char *) buf, - "S: %d", ao_num_sats()); + "%c%d", + ao_gps_locked(), + ao_num_sats()); #endif } -- cgit v1.2.3