From fa813bcb6afc851cf4029b56c19ba46a3ae578f5 Mon Sep 17 00:00:00 2001 From: Tom Marble Date: Mon, 9 Feb 2015 08:35:24 -0600 Subject: Minor typo in man page --- ao-tools/ao-usbtrng/ao-usbtrng.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ao-tools/ao-usbtrng/ao-usbtrng.1 b/ao-tools/ao-usbtrng/ao-usbtrng.1 index 7a1311b9..b4a3e5ec 100644 --- a/ao-tools/ao-usbtrng/ao-usbtrng.1 +++ b/ao-tools/ao-usbtrng/ao-usbtrng.1 @@ -16,7 +16,7 @@ .\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. .\" .\" -.TH AO-LOAD 1 "ao-usbtrng" "" +.TH AO-USBTRNG 1 "ao-usbtrng" "" .SH NAME ao-usbtrng \- dump random numbers from USBtrng .SH SYNOPSIS -- cgit v1.2.3 From 65837616a6d073da8e3e2bf9da524a48cffb77c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Feb 2015 07:28:18 -0800 Subject: altos/stmf0: Add ao_crc_stm.c Tom discovered that this was missing Signed-off-by: Keith Packard --- src/stmf0/ao_crc_stm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/stmf0/ao_crc_stm.c diff --git a/src/stmf0/ao_crc_stm.c b/src/stmf0/ao_crc_stm.c new file mode 100644 index 00000000..78efa93a --- /dev/null +++ b/src/stmf0/ao_crc_stm.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2015 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 +#include + +#ifndef AO_CRC_WIDTH +#error "Must define AO_CRC_WIDTH" +#endif + +/* Only the STM32F07x and ST32F09x series have + * programmable CRC units. Others can only do the ANSI CRC-32 computation + */ + +#if !AO_HAVE_PROGRAMMABLE_CRC_UNIT && AO_CRC_WIDTH != 32 +#error "Target hardware does not have programmable CRC unit" +#endif + +#ifndef AO_CRC_POLY +#if AO_CRC_WIDTH == 16 +#define AO_CRC_POLY AO_CRC_16_DEFAULT +#endif +#if AO_CRC_WIDTH == 32 +#define AO_CRC_POLY AO_CRC_32_DEFAULT +#endif +#endif + +#if !AO_HAVE_PROGRAMMABLE_CRC_UNIT && (AO_CRC_WIDTH != 32 || AO_CRC_POLY != AO_CRC_32_ANSI) +#error "Target hardware does not have programmable CRC unit" +#endif + +#if AO_CRC_WIDTH == 32 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_32 +#endif + +#if AO_CRC_WIDTH == 16 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_16 +#endif + +#if AO_CRC_WIDTH == 8 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_8 +#endif + +#if AO_CRC_WIDTH == 7 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_7 +#endif + +#ifndef AO_CRC_INIT +#define AO_CRC_INIT 0xffffffff; +#endif + +void +ao_crc_reset(void) +{ + stm_crc.cr |= (1 << STM_CRC_CR_RESET); + while ((stm_crc.cr & (1 << STM_CRC_CR_RESET)) != 0) + ; +} + +void +ao_crc_init(void) +{ + /* Turn on the CRC clock */ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_CRCEN); + + /* Need to initialize CR even on non-programmable hardware, + * the write to the POLYSIZE bits will be ignored in that + * case + */ + stm_crc.cr = (AO_CRC_CR_POLYSIZE << STM_CRC_CR_POLYSIZE); + stm_crc.init = AO_CRC_INIT; +#if AO_HAVE_PROGRAMMABLE_CRC_UNIT + stm_crc.pol = AO_CRC_POLY; +#endif + ao_crc_reset(); +} -- cgit v1.2.3 From 1445725b983134d5a967dee88ef997bf15d4a422 Mon Sep 17 00:00:00 2001 From: Tom Marble Date: Wed, 11 Feb 2015 08:21:27 -0600 Subject: Added continuous output option to ao-usbtrng --- ao-tools/ao-usbtrng/ao-usbtrng.1 | 20 +++++++++--------- ao-tools/ao-usbtrng/ao-usbtrng.c | 44 ++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/ao-tools/ao-usbtrng/ao-usbtrng.1 b/ao-tools/ao-usbtrng/ao-usbtrng.1 index b4a3e5ec..eabdd8a1 100644 --- a/ao-tools/ao-usbtrng/ao-usbtrng.1 +++ b/ao-tools/ao-usbtrng/ao-usbtrng.1 @@ -20,24 +20,24 @@ .SH NAME ao-usbtrng \- dump random numbers from USBtrng .SH SYNOPSIS -.B "ao-usbtrng" -[\-T \fItty-device\fP] -[\--tty \fItty-device\fP] -[\-D \fIaltos-device\fP] -[\--device \fIaltos-device\fP] -\fIkbytes\fP +.B "ao-usbtrng" [OPTION...] [KBYTES] .SH DESCRIPTION .I ao-usbtrng -dumps random numbers from a USBtrng device +dumps random numbers from a USBtrng device. If provided KBYTES specifies the number of 1024 byte blocks to produce on standard output. Without KBYTES +.I ao-usbtrng +produces random bytes continuously until killed. .SH OPTIONS .TP -\-T tty-device | --tty tty-device +\-v, --verbose +increase verbosity +.TP +\-T, -tty=TTYDEVICE This selects which tty device the debugger uses to communicate with the target device. The special name 'BITBANG' directs ao-dbg to use the cp2103 connection, otherwise this should be a usb serial port connected to a suitable cc1111 debug node. .TP -\-D AltOS-device | --device AltOS-device +\-D, --device=ALTOSDEVICE Search for a connected device. This requires an argument of one of the following forms: .IP @@ -52,7 +52,7 @@ product, leaving out the serial number will cause the tool to match one of the available devices. .SH USAGE .I ao-usbtrng -opens the target device and reads the specified number of kbytes of +opens the target device and reads the specified number of KBYTES of random data. .SH AUTHOR Keith Packard diff --git a/ao-tools/ao-usbtrng/ao-usbtrng.c b/ao-tools/ao-usbtrng/ao-usbtrng.c index 232f4e3e..456885d9 100644 --- a/ao-tools/ao-usbtrng/ao-usbtrng.c +++ b/ao-tools/ao-usbtrng/ao-usbtrng.c @@ -35,14 +35,13 @@ static const struct option options[] = { { .name = "tty", .has_arg = 1, .val = 'T' }, { .name = "device", .has_arg = 1, .val = 'D' }, - { .name = "raw", .has_arg = 0, .val = 'r' }, - { .name = "verbose", .has_arg = 1, .val = 'v' }, + { .name = "verbose", .has_arg = 0, .val = 'v' }, { 0, 0, 0, 0}, }; static void usage(char *program) { - fprintf(stderr, "usage: %s [--verbose=] [--device=] [-tty=] \n", program); + fprintf(stderr, "usage: %s [--verbose] [--device=] [-tty=] []\n", program); exit(1); } @@ -58,21 +57,17 @@ main (int argc, char **argv) { char *device = NULL; char *filename; - Elf *e; - unsigned int s; int i; int c; - int tries; struct cc_usb *cc = NULL; char *tty = NULL; - int success; int verbose = 0; int ret = 0; - int expected_size; - int kbytes; + int kbytes = 0; /* 0 == continuous */ + int written; uint8_t bits[1024]; - while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "vT:D:", options, NULL)) != -1) { switch (c) { case 'T': tty = optarg; @@ -89,12 +84,8 @@ main (int argc, char **argv) } } - if (!argv[optind]) - usage(argv[0]); - - kbytes = atoi(argv[optind]); - if (kbytes < 1) - kbytes = 1; + if (optind < argc) + kbytes = atoi(argv[optind]); ao_verbose = verbose; @@ -113,13 +104,22 @@ main (int argc, char **argv) if (!cc) exit(1); - cc_usb_printf(cc, "f %d\n", kbytes); + if (kbytes) { + cc_usb_printf(cc, "f %d\n", kbytes); - while (kbytes--) { - int i; - for (i = 0; i < 1024; i++) - bits[i] = cc_usb_getchar(cc); - write(1, bits, 1024); + while (kbytes--) { + for (i = 0; i < 1024; i++) + bits[i] = cc_usb_getchar(cc); + write(1, bits, 1024); + } + } else { /* 0 == continuous */ + written = 0; + while (written >= 0) { + cc_usb_printf(cc, "f 1\n"); + for (i = 0; i < 1024; i++) + bits[i] = cc_usb_getchar(cc); + written = write(1, bits, 1024); + } } done(cc, ret); -- cgit v1.2.3 From f4c812bef76a2cd95f675cb27ea89059561ceec7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Feb 2015 23:51:10 -0800 Subject: altos: Replace ao_alarm/ao_clear_alarm with ao_sleep_for Having arbitrary alarms firing in the middle of complicated device logic makes no sense at all. Therefore only correct use of ao_alarm and ao_clear_alarm was around a specific ao_sleep call, with correct recovery in case the alarm fires. This patch replaces all uses of ao_alarm/ao_sleep/ao_clear_alarm with ao_sleep_for, a new function which takes the alarm timeout directly. A few cases which weren't simply calling ao_sleep have been reworked to pass the timeout value down to the place where sleep *is* being called, and having that code deal with the return correctly. Signed-off-by: Keith Packard --- src/cc1111/ao_arch.h | 2 +- src/cc1111/ao_button.c | 4 ++-- src/cc1111/ao_radio.c | 6 +----- src/drivers/ao_btm.c | 8 +++----- src/drivers/ao_cc1120.c | 16 +++------------- src/drivers/ao_cc1200.c | 8 +------- src/drivers/ao_companion.c | 3 +-- src/drivers/ao_hmc5883.c | 4 +--- src/drivers/ao_packet.c | 4 ++-- src/drivers/ao_packet_master.c | 8 ++------ src/drivers/ao_packet_slave.c | 2 +- src/kernel/ao_packet.h | 2 +- src/kernel/ao_pyro.c | 4 +--- src/kernel/ao_serial.h | 8 ++++---- src/kernel/ao_task.c | 20 +++++++++++++++----- src/kernel/ao_task.h | 10 ++++++++++ src/kernel/ao_telemetry.c | 4 +--- src/product/ao_terraui.c | 4 +--- src/stm/ao_i2c_stm.c | 18 +++++------------- src/stm/ao_serial_stm.c | 16 ++++++++-------- src/telebt-v3.0/ao_pins.h | 2 +- src/telelco-v0.1/ao_lco.c | 6 +----- src/telelco-v0.2/ao_lco.c | 4 +--- 23 files changed, 67 insertions(+), 96 deletions(-) diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index b3c6b5dc..6eb1a111 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -228,7 +228,7 @@ void ao_button_init(void); char -ao_button_get(void) __critical; +ao_button_get(uint16_t timeout) __critical; void ao_button_clear(void) __critical; diff --git a/src/cc1111/ao_button.c b/src/cc1111/ao_button.c index 69f3475f..a0f221c2 100644 --- a/src/cc1111/ao_button.c +++ b/src/cc1111/ao_button.c @@ -72,12 +72,12 @@ ao_button_mask(uint8_t reg) } char -ao_button_get(void) __critical +ao_button_get(uint16_t timeout) __critical { char b; while (ao_fifo_empty(ao_button_fifo)) - if (ao_sleep(&ao_button_fifo)) + if (ao_sleep_for(&ao_button_fifo, timeout)) return 0; ao_fifo_remove(ao_button_fifo, b); return b; diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index b9821a42..cead0364 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -451,13 +451,9 @@ ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant /* Wait for DMA to be done, for the radio receive process to * get aborted or for a receive timeout to fire */ - if (timeout) - ao_alarm(timeout); __critical while (!ao_radio_dma_done && !ao_radio_abort) - if (ao_sleep(&ao_radio_dma_done)) + if (ao_sleep_for(&ao_radio_dma_done, timeout)) break; - if (timeout) - ao_clear_alarm(); /* If recv was aborted, clean up by stopping the DMA engine * and idling the radio diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index e6b28688..93d9dd9d 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -23,7 +23,7 @@ #ifndef ao_serial_btm_getchar #define ao_serial_btm_putchar ao_serial1_putchar #define _ao_serial_btm_pollchar _ao_serial1_pollchar -#define _ao_serial_btm_sleep() ao_sleep((void *) &ao_serial1_rx_fifo) +#define _ao_serial_btm_sleep_for(timeout) ao_sleep_for((void *) &ao_serial1_rx_fifo, timeout) #define ao_serial_btm_set_speed ao_serial1_set_speed #define ao_serial_btm_drain ao_serial1_drain #endif @@ -111,7 +111,7 @@ ao_btm_do_echo(void) while (ao_btm_enable) { ao_arch_block_interrupts(); while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN && ao_btm_enable) - _ao_serial_btm_sleep(); + _ao_serial_btm_sleep_for(0); ao_arch_release_interrupts(); if (c != AO_READ_AGAIN) { putchar(c); @@ -166,9 +166,7 @@ ao_btm_getchar(void) ao_arch_block_interrupts(); while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN) { - ao_alarm(AO_MS_TO_TICKS(10)); - c = _ao_serial_btm_sleep(); - ao_clear_alarm(); + c = _ao_serial_btm_sleep_for(AO_MS_TO_TICKS(10)); if (c) { c = AO_READ_AGAIN; break; diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 90d6cc75..5b814667 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -837,15 +837,11 @@ ao_radio_test_cmd(void) static void ao_radio_wait_isr(uint16_t timeout) { - if (timeout) - ao_alarm(timeout); ao_arch_block_interrupts(); while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort) - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; ao_arch_release_interrupts(); - if (timeout) - ao_clear_alarm(); if (ao_radio_mcu_wake) ao_radio_check_marc_status(); } @@ -1060,19 +1056,17 @@ ao_radio_rx_isr(void) static uint16_t ao_radio_rx_wait(void) { - ao_alarm(AO_MS_TO_TICKS(100)); ao_arch_block_interrupts(); rx_waiting = 1; while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK && !ao_radio_abort && !ao_radio_mcu_wake) { - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, AO_MS_TO_TICKS(100))) ao_radio_abort = 1; } rx_waiting = 0; ao_arch_release_interrupts(); - ao_clear_alarm(); if (ao_radio_abort || ao_radio_mcu_wake) return 0; rx_data_consumed += AO_FEC_DECODE_BLOCK; @@ -1133,19 +1127,15 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) ao_radio_strobe(CC1120_SRX); - if (timeout) - ao_alarm(timeout); ao_arch_block_interrupts(); while (rx_starting && !ao_radio_abort) { - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; } uint8_t rx_task_id_save = rx_task_id; rx_task_id = 0; rx_starting = 0; ao_arch_release_interrupts(); - if (timeout) - ao_clear_alarm(); if (ao_radio_abort) { if (rx_task_id_save == 0) diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index 8546900e..df4bd335 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -715,17 +715,11 @@ ao_radio_show_state(char *where) static void ao_radio_wait_isr(uint16_t timeout) { - if (timeout) - ao_alarm(timeout); - ao_arch_block_interrupts(); while (!ao_radio_wake && !ao_radio_abort) - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; ao_arch_release_interrupts(); - - if (timeout) - ao_clear_alarm(); } static void diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 570b9e40..7e02939b 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -102,8 +102,7 @@ ao_companion(void) break; } while (ao_companion_running) { - ao_alarm(ao_companion_setup.update_period); - if (ao_sleep(DATA_TO_XDATA(&ao_flight_state))) + if (ao_sleep_for(DATA_TO_XDATA(&ao_flight_state), ao_companion_setup.update_period)) ao_companion_get_data(); else ao_companion_notify(); diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c index 2d217bcf..f761671a 100644 --- a/src/drivers/ao_hmc5883.c +++ b/src/drivers/ao_hmc5883.c @@ -75,13 +75,11 @@ ao_hmc5883_sample(struct ao_hmc5883_sample *sample) ao_exti_enable(AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN); ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE); - ao_alarm(AO_MS_TO_TICKS(10)); ao_arch_block_interrupts(); while (!ao_hmc5883_done) - if (ao_sleep(&ao_hmc5883_done)) + if (ao_sleep_for(&ao_hmc5883_done, AO_MS_TO_TICKS(10))) ++ao_hmc5883_missed_irq; ao_arch_release_interrupts(); - ao_clear_alarm(); ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample)); #if __BYTE_ORDER == __LITTLE_ENDIAN diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 8cdf85a9..18330ead 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -54,14 +54,14 @@ ao_packet_send(void) } uint8_t -ao_packet_recv(void) +ao_packet_recv(uint16_t timeout) { uint8_t dma_done; #ifdef AO_LED_GREEN ao_led_on(AO_LED_GREEN); #endif - dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), 0); + dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), timeout); #ifdef AO_LED_GREEN ao_led_off(AO_LED_GREEN); #endif diff --git a/src/drivers/ao_packet_master.c b/src/drivers/ao_packet_master.c index 42a4f5bf..5e440db0 100644 --- a/src/drivers/ao_packet_master.c +++ b/src/drivers/ao_packet_master.c @@ -97,9 +97,7 @@ ao_packet_master(void) if (ao_tx_packet.len) ao_packet_master_busy(); ao_packet_master_check_busy(); - ao_alarm(AO_PACKET_MASTER_RECV_DELAY); - r = ao_packet_recv(); - ao_clear_alarm(); + r = ao_packet_recv(AO_PACKET_MASTER_RECV_DELAY); if (r) { /* if we can transmit data, do so */ if (ao_packet_tx_used && ao_tx_packet.len == 0) @@ -107,9 +105,7 @@ ao_packet_master(void) if (ao_rx_packet.packet.len) ao_packet_master_busy(); ao_packet_master_sleeping = 1; - ao_alarm(ao_packet_master_delay); - ao_sleep(&ao_packet_master_sleeping); - ao_clear_alarm(); + ao_sleep_for(&ao_packet_master_sleeping, ao_packet_master_delay); ao_packet_master_sleeping = 0; } } diff --git a/src/drivers/ao_packet_slave.c b/src/drivers/ao_packet_slave.c index e75df0d6..0872682f 100644 --- a/src/drivers/ao_packet_slave.c +++ b/src/drivers/ao_packet_slave.c @@ -24,7 +24,7 @@ ao_packet_slave(void) ao_tx_packet.len = AO_PACKET_SYN; ao_packet_restart = 1; while (ao_packet_enable) { - if (ao_packet_recv()) { + if (ao_packet_recv(0)) { ao_xmemcpy(&ao_tx_packet.callsign, &ao_rx_packet.packet.callsign, AO_MAX_CALLSIGN); #if HAS_FLIGHT ao_flight_force_idle = TRUE; diff --git a/src/kernel/ao_packet.h b/src/kernel/ao_packet.h index b8426cf9..136609c3 100644 --- a/src/kernel/ao_packet.h +++ b/src/kernel/ao_packet.h @@ -54,7 +54,7 @@ void ao_packet_send(void); uint8_t -ao_packet_recv(void); +ao_packet_recv(uint16_t timeout); void ao_packet_flush(void); diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c index 3044d565..43e73de4 100644 --- a/src/kernel/ao_pyro.c +++ b/src/kernel/ao_pyro.c @@ -375,9 +375,7 @@ ao_pyro(void) ao_sleep(&ao_flight_state); for (;;) { - ao_alarm(AO_MS_TO_TICKS(100)); - ao_sleep(&ao_pyro_wakeup); - ao_clear_alarm(); + ao_sleep_for(&ao_pyro_wakeup, AO_MS_TO_TICKS(100)); if (ao_flight_state >= ao_flight_landed) break; any_waiting = ao_pyro_check(); diff --git a/src/kernel/ao_serial.h b/src/kernel/ao_serial.h index dbc9f8e4..e21643ac 100644 --- a/src/kernel/ao_serial.h +++ b/src/kernel/ao_serial.h @@ -35,7 +35,7 @@ int _ao_serial0_pollchar(void); uint8_t -_ao_serial0_sleep(void); +_ao_serial0_sleep_for(uint16_t timeout); void ao_serial0_putchar(char c); @@ -58,7 +58,7 @@ int _ao_serial1_pollchar(void); uint8_t -_ao_serial1_sleep(void); +_ao_serial1_sleep_for(uint16_t timeout); void ao_serial1_putchar(char c); @@ -81,7 +81,7 @@ int _ao_serial2_pollchar(void); uint8_t -_ao_serial2_sleep(void); +_ao_serial2_sleep_for(uint16_t timeout); void ao_serial2_putchar(char c); @@ -104,7 +104,7 @@ int _ao_serial3_pollchar(void); uint8_t -_ao_serial3_sleep(void); +_ao_serial3_sleep_for(uint16_t timeout); void ao_serial3_putchar(char c); diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index bafb4943..1ecdd7dd 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -450,7 +450,7 @@ ao_wakeup(__xdata void *wchan) __reentrant ao_check_stack(); } -void +static void ao_alarm(uint16_t delay) { #if HAS_TASK_QUEUE @@ -468,7 +468,7 @@ ao_alarm(uint16_t delay) #endif } -void +static void ao_clear_alarm(void) { #if HAS_TASK_QUEUE @@ -483,14 +483,24 @@ ao_clear_alarm(void) #endif } +uint8_t +ao_sleep_for(__xdata void *wchan, uint16_t timeout) +{ + uint8_t ret; + if (timeout) + ao_alarm(timeout); + ret = ao_sleep(wchan); + if (timeout) + ao_clear_alarm(); + return ret; +} + static __xdata uint8_t ao_forever; void ao_delay(uint16_t ticks) { - ao_alarm(ticks); - ao_sleep(&ao_forever); - ao_clear_alarm(); + ao_sleep_for(&ao_forever, ticks); } void diff --git a/src/kernel/ao_task.h b/src/kernel/ao_task.h index 9c56b480..c6bec0e3 100644 --- a/src/kernel/ao_task.h +++ b/src/kernel/ao_task.h @@ -68,10 +68,19 @@ extern __data uint8_t ao_task_minimize_latency; /* Reduce IRQ latency */ uint8_t ao_sleep(__xdata void *wchan); +/* Suspend the current task until wchan is awoken or the timeout + * expires. returns: + * 0 on normal wake + * 1 on alarm + */ +uint8_t +ao_sleep_for(__xdata void *wchan, uint16_t timeout); + /* Wake all tasks sleeping on wchan */ void ao_wakeup(__xdata void *wchan) __reentrant; +#if 0 /* set an alarm to go off in 'delay' ticks */ void ao_alarm(uint16_t delay); @@ -79,6 +88,7 @@ ao_alarm(uint16_t delay); /* Clear any pending alarm */ void ao_clear_alarm(void); +#endif /* Yield the processor to another task */ void diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index e2197f7a..854ac898 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -486,9 +486,7 @@ ao_telemetry(void) #endif /* HAS_APRS */ delay = time - ao_time(); if (delay > 0) { - ao_alarm(delay); - ao_sleep(&telemetry); - ao_clear_alarm(); + ao_sleep_for(&telemetry, delay); } } } diff --git a/src/product/ao_terraui.c b/src/product/ao_terraui.c index 8fd97033..1e7b5dcd 100644 --- a/src/product/ao_terraui.c +++ b/src/product/ao_terraui.c @@ -539,9 +539,7 @@ ao_terraui(void) else ao_terraui_page[ao_current_page](); - ao_alarm(AO_SEC_TO_TICKS(1)); - b = ao_button_get(); - ao_clear_alarm(); + b = ao_button_get(AO_SEC_TO_TICKS(1)); if (b > 0) { ao_beep_for(AO_BEEP_HIGH, AO_MS_TO_TICKS(10)); diff --git a/src/stm/ao_i2c_stm.c b/src/stm/ao_i2c_stm.c index 1c90cdb8..158f5b21 100644 --- a/src/stm/ao_i2c_stm.c +++ b/src/stm/ao_i2c_stm.c @@ -195,15 +195,13 @@ ao_i2c_start(uint8_t index, uint16_t addr) if (!(stm_i2c->cr1 & (1 << STM_I2C_CR1_START))) break; } - ao_alarm(AO_MS_TO_TICKS(250)); ao_arch_block_interrupts(); stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN); ao_i2c_ev_isr(index); while (ao_i2c_state[index] == I2C_IDLE) - if (ao_sleep(&ao_i2c_state[index])) + if (ao_sleep_for(&ao_i2c_state[index], AO_MS_TO_TICKS(250))) break; ao_arch_release_interrupts(); - ao_clear_alarm(); return ao_i2c_state[index] == I2C_RUNNING; } @@ -258,16 +256,14 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop) (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); ao_dma_start(tx_dma_index); - ao_alarm(1 + len); ao_arch_block_interrupts(); while (!ao_dma_done[tx_dma_index]) - if (ao_sleep(&ao_dma_done[tx_dma_index])) + if (ao_sleep_for(&ao_dma_done[tx_dma_index], 1 + len)) break; - ao_clear_alarm(); ao_dma_done_transfer(tx_dma_index); stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN); while ((stm_i2c->sr1 & (1 << STM_I2C_SR1_BTF)) == 0) - if (ao_sleep(&ao_i2c_state[index])) + if (ao_sleep_for(&ao_i2c_state[index], 1 + len)) break; stm_i2c->cr2 = AO_STM_I2C_CR2; ao_arch_release_interrupts(); @@ -321,14 +317,12 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop) if (stop) stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP); - ao_alarm(1); ao_arch_block_interrupts(); while (ao_i2c_recv_len[index]) - if (ao_sleep(&ao_i2c_recv_len[index])) + if (ao_sleep_for(&ao_i2c_recv_len[index], 1)) break; ao_arch_release_interrupts(); ret = ao_i2c_recv_len[index] == 0; - ao_clear_alarm(); } else { uint8_t rx_dma_index = ao_i2c_stm_info[index].rx_dma_index; ao_dma_set_transfer(rx_dma_index, @@ -351,13 +345,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop) ao_i2c_wait_addr(index); ao_dma_start(rx_dma_index); - ao_alarm(len); ao_arch_block_interrupts(); while (!ao_dma_done[rx_dma_index]) - if (ao_sleep(&ao_dma_done[rx_dma_index])) + if (ao_sleep_for(&ao_dma_done[rx_dma_index], len)) break; ao_arch_release_interrupts(); - ao_clear_alarm(); ret = ao_dma_done[rx_dma_index]; ao_dma_done_transfer(rx_dma_index); stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP); diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index 2568cf43..88f2d029 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -86,9 +86,9 @@ ao_usart_getchar(struct ao_stm_usart *usart) } static inline uint8_t -_ao_usart_sleep(struct ao_stm_usart *usart) +_ao_usart_sleep_for(struct ao_stm_usart *usart, uint16_t timeout) { - return ao_sleep(&usart->rx_fifo); + return ao_sleep_for(&usart->rx_fifo, timeout); } void @@ -217,9 +217,9 @@ _ao_serial1_pollchar(void) } uint8_t -_ao_serial1_sleep(void) +_ao_serial1_sleep_for(uint16_t timeout) { - return _ao_usart_sleep(&ao_stm_usart1); + return _ao_usart_sleep_for(&ao_stm_usart1, timeout); } void @@ -260,9 +260,9 @@ _ao_serial2_pollchar(void) } uint8_t -_ao_serial2_sleep(void) +_ao_serial2_sleep_for(uint16_t timeout) { - return _ao_usart_sleep(&ao_stm_usart2); + return _ao_usart_sleep_for(&ao_stm_usart2, timeout); } void @@ -303,9 +303,9 @@ _ao_serial3_pollchar(void) } uint8_t -_ao_serial3_sleep(void) +_ao_serial3_sleep_for(uint16_t timeout) { - return _ao_usart_sleep(&ao_stm_usart3); + return _ao_usart_sleep_for(&ao_stm_usart3, timeout); } void diff --git a/src/telebt-v3.0/ao_pins.h b/src/telebt-v3.0/ao_pins.h index 838f0dfc..6e90afcc 100644 --- a/src/telebt-v3.0/ao_pins.h +++ b/src/telebt-v3.0/ao_pins.h @@ -168,7 +168,7 @@ struct ao_adc { #define ao_serial_btm_getchar ao_serial2_getchar #define ao_serial_btm_putchar ao_serial2_putchar #define _ao_serial_btm_pollchar _ao_serial2_pollchar -#define _ao_serial_btm_sleep _ao_serial2_sleep +#define _ao_serial_btm_sleep_for _ao_serial2_sleep_for #define ao_serial_btm_set_speed ao_serial2_set_speed #define ao_serial_btm_drain ao_serial2_drain #define ao_serial_btm_rx_fifo (ao_stm_usart2.rx_fifo) diff --git a/src/telelco-v0.1/ao_lco.c b/src/telelco-v0.1/ao_lco.c index 79f3896b..cb2195ef 100644 --- a/src/telelco-v0.1/ao_lco.c +++ b/src/telelco-v0.1/ao_lco.c @@ -280,9 +280,7 @@ ao_lco_igniter_status(void) uint16_t delay; for (;;) { -// ao_alarm(delay); ao_sleep(&ao_pad_query); -// ao_clear_alarm(); if (!ao_lco_valid) { ao_led_on(AO_LED_RED); ao_led_off(AO_LED_GREEN); @@ -364,9 +362,7 @@ ao_lco_monitor(void) delay = AO_MS_TO_TICKS(100); else delay = AO_SEC_TO_TICKS(1); - ao_alarm(delay); - ao_sleep(&ao_lco_armed); - ao_clear_alarm(); + ao_sleep_for(&ao_lco_armed, delay); } } diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index 4b5f7a9b..12a247bf 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -369,9 +369,7 @@ ao_lco_monitor(void) delay = AO_MS_TO_TICKS(100); else delay = AO_SEC_TO_TICKS(1); - ao_alarm(delay); - ao_sleep(&ao_lco_armed); - ao_clear_alarm(); + ao_sleep_for(&ao_lco_armed, delay); } } -- cgit v1.2.3 From 0e929ee2d0a3d1b1bacd36c2c3723ab860eb40b6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 01:11:30 -0800 Subject: altosui: Run all igniter status requests from non-GUI thread Anything run from the UI thread blocks the UI entirely; the Fire Igniters startup code to collect the number of pyro channels when building the UI was doing that from the UI thread. Switch that around so that the UI doesn't get built until that reply comes back, allowing the user to see the 'connecting' dialog, and cancel it if required. Signed-off-by: Keith Packard --- altosui/AltosIgniteUI.java | 60 ++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 42 deletions(-) diff --git a/altosui/AltosIgniteUI.java b/altosui/AltosIgniteUI.java index 944c659b..1a2dc4f1 100644 --- a/altosui/AltosIgniteUI.java +++ b/altosui/AltosIgniteUI.java @@ -50,8 +50,6 @@ public class AltosIgniteUI LinkedBlockingQueue command_queue; - LinkedBlockingQueue reply_queue; - class Igniter { JRadioButton button; JLabel status_label; @@ -150,8 +148,7 @@ public class AltosIgniteUI } reply = "status"; } else if (command.equals("get_npyro")) { - put_reply(String.format("%d", ignite.npyro())); - continue; + reply = String.format("npyro %d", ignite.npyro()); } else if (command.equals("quit")) { ignite.close(); break; @@ -211,6 +208,9 @@ public class AltosIgniteUI set_ignite_status(); } else if (reply.equals("fired")) { fired(); + } else if (reply.startsWith("npyro")) { + npyro = Integer.parseInt(reply.substring(6)); + make_ui(); } } @@ -250,24 +250,6 @@ public class AltosIgniteUI } } - void put_reply(String reply) { - try { - reply_queue.put(reply); - } catch (Exception ex) { - ignite_exception(ex); - } - } - - String get_reply() { - String reply = ""; - try { - reply = reply_queue.take(); - } catch (Exception ex) { - ignite_exception(ex); - } - return reply; - } - boolean getting_status = false; boolean visible = false; @@ -287,12 +269,6 @@ public class AltosIgniteUI } } - int get_npyro() { - send_command("get_npyro"); - String reply = get_reply(); - return Integer.parseInt(reply); - } - boolean firing = false; void start_fire(String which) { @@ -310,8 +286,9 @@ public class AltosIgniteUI void close() { if (opened) { send_command("quit"); - timer.stop(); } + if (timer != null) + timer.stop(); setVisible(false); dispose(); } @@ -383,7 +360,6 @@ public class AltosIgniteUI private boolean open() { command_queue = new LinkedBlockingQueue(); - reply_queue = new LinkedBlockingQueue(); opened = false; device = AltosDeviceUIDialog.show(owner, Altos.product_any); @@ -403,13 +379,7 @@ public class AltosIgniteUI return false; } - public AltosIgniteUI(JFrame in_owner) { - - owner = in_owner; - - if (!open()) - return; - + private void make_ui() { group = new ButtonGroup(); Container pane = getContentPane(); @@ -422,8 +392,6 @@ public class AltosIgniteUI timer_running = false; timer.restart(); - owner = in_owner; - pane.setLayout(new GridBagLayout()); c.fill = GridBagConstraints.NONE; @@ -443,8 +411,6 @@ public class AltosIgniteUI y++; - int npyro = get_npyro(); - igniters = new Igniter[2 + npyro]; igniters[0] = new Igniter(this, "Apogee", AltosIgnite.Apogee, y++); @@ -492,4 +458,14 @@ public class AltosIgniteUI addWindowListener(new ConfigListener(this)); } -} \ No newline at end of file + + public AltosIgniteUI(JFrame in_owner) { + + owner = in_owner; + + if (!open()) + return; + + send_command("get_npyro"); + } +} -- cgit v1.2.3 From c4f9d96bdea192486f0e3f2d80b846c39a05c0ab Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 01:13:21 -0800 Subject: altosuilib: Detect pair programming by product name, not USB id With TeleDongle, TeleBT and TeleMetrum coming in both pair- and self- programmable versions, we can't use the USB id to tell them apart. Instead, fetch the device name and use that instead. Signed-off-by: Keith Packard --- altosuilib/AltosFlashUI.java | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 6e497c42..ace8fbe5 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -54,7 +54,7 @@ public class AltosFlashUI // Flash controller AltosProgrammer programmer; - private static String[] pair_programmed = { + private static final String[] pair_programmed_files = { "teleballoon", "telebt-v1", "teledongle-v0", @@ -67,20 +67,34 @@ public class AltosFlashUI "teleterra" }; + private static final String[] pair_programmed_devices = { + "TeleBalloon", + "TeleBT-v1", + "TeleDongle-v0", + "TeleFire", + "TeleMetrum-v0", + "TeleMetrum-v1", + "TeleMini", + "TeleNano", + "TeleShield", + "TeleTerra" + }; + private boolean is_pair_programmed() { if (file != null) { String name = file.getName(); - for (int i = 0; i < pair_programmed.length; i++) { - if (name.startsWith(pair_programmed[i])) + for (int i = 0; i < pair_programmed_files.length; i++) { + if (name.startsWith(pair_programmed_files[i])) return true; } } if (device != null) { - if (!device.matchProduct(AltosLib.product_altusmetrum) && - (device.matchProduct(AltosLib.product_teledongle) || - device.matchProduct(AltosLib.product_telebt))) - return true; + String name = device.toString(); + for (int i = 0; i < pair_programmed_devices.length; i++) { + if (name.startsWith(pair_programmed_devices[i])) + return true; + } } return false; } -- cgit v1.2.3 From cc64e0e9d35e01b349680159a5bbd68d059134cd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 01:16:42 -0800 Subject: ao-bringup/turnon_telemini: Detect which programmer to use by $USER Bdale uses TD 100, keithp uses TD 186. Signed-off-by: Keith Packard --- ao-bringup/turnon_telemini | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ao-bringup/turnon_telemini b/ao-bringup/turnon_telemini index 4450d6f6..6aef7f51 100755 --- a/ao-bringup/turnon_telemini +++ b/ao-bringup/turnon_telemini @@ -18,11 +18,13 @@ else exit 1 fi -echo "TeleMini v1.0 Turn-On and Calibration Program" +VERSION=1.0 + +echo "TeleMini v$VERSION Turn-On and Calibration Program" echo "Copyright 2011 by Bdale Garbee. Released under GPL v2" echo echo "Expectations:" -echo "\tTeleMini v1.0 powered from LiPo" +echo "\tTeleMini v$VERSION powered from LiPo" echo "\t\twith TeleDongle (on /dev/ttyACM0) cabled to debug header" echo "\t\twith frequency counter able to sample RF output" echo @@ -31,18 +33,27 @@ read SERIAL echo $RAWLOAD -$RAWLOAD -D 100 -r ao_led_blink.ihx +case $USER in + bdale) + programmer=100 + ;; + keithp) + programmer=186 + ;; +esac + +$RAWLOAD -D $programmer -r ao_led_blink.ihx echo "LEDs should be blinking" sleep 5 -$RAWLOAD -D 100 -r ao_radio_xmit.ihx +$RAWLOAD -D $programmer -r ao_radio_xmit.ihx echo -n "Generating RF carrier. Please enter measured frequency: " read FREQ CAL_VALUE=`nickle -e "floor(434.55 / $FREQ * 1186611 + 0.5)"` echo "Programming flash with cal value " $CAL_VALUE -$AOLOAD -D 100 --cal $CAL_VALUE /usr/share/altos/stable/telemini-v1.0*.ihx $SERIAL +$AOLOAD -D $programmer --cal $CAL_VALUE ~/altusmetrumllc/Binaries/telemini-v$VERSION-*.ihx $SERIAL echo "Serial number "$SERIAL" programmed with RF cal value "$CAL_VALUE echo "Unplug and replug USB, cu to the board, confirm freq and record power" -- cgit v1.2.3 From 9c75faf1ec51eb2f9a8dc9402653490143a784d9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 08:35:47 -0800 Subject: altos: embed ao_alarm and ao_clear_alarm in ao_sleep_for sdcc won't embed these itself, and thus consumes too much flash for telemetrum-v1.0 Signed-off-by: Keith Packard --- src/kernel/ao_task.c | 54 +++++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 1ecdd7dd..55e423bb 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -450,48 +450,38 @@ ao_wakeup(__xdata void *wchan) __reentrant ao_check_stack(); } -static void -ao_alarm(uint16_t delay) +uint8_t +ao_sleep_for(__xdata void *wchan, uint16_t timeout) { + uint8_t ret; + if (timeout) { #if HAS_TASK_QUEUE - uint32_t flags; - /* Make sure we sleep *at least* delay ticks, which means adding - * one to account for the fact that we may be close to the next tick - */ - flags = ao_arch_irqsave(); + uint32_t flags; + /* Make sure we sleep *at least* delay ticks, which means adding + * one to account for the fact that we may be close to the next tick + */ + flags = ao_arch_irqsave(); #endif - if (!(ao_cur_task->alarm = ao_time() + delay + 1)) - ao_cur_task->alarm = 1; + if (!(ao_cur_task->alarm = ao_time() + timeout + 1)) + ao_cur_task->alarm = 1; #if HAS_TASK_QUEUE - ao_task_to_alarm_queue(ao_cur_task); - ao_arch_irqrestore(flags); + ao_task_to_alarm_queue(ao_cur_task); + ao_arch_irqrestore(flags); #endif -} - -static void -ao_clear_alarm(void) -{ + } + ret = ao_sleep(wchan); + if (timeout) { #if HAS_TASK_QUEUE - uint32_t flags; + uint32_t flags; - flags = ao_arch_irqsave(); + flags = ao_arch_irqsave(); #endif - ao_cur_task->alarm = 0; + ao_cur_task->alarm = 0; #if HAS_TASK_QUEUE - ao_task_from_alarm_queue(ao_cur_task); - ao_arch_irqrestore(flags); + ao_task_from_alarm_queue(ao_cur_task); + ao_arch_irqrestore(flags); #endif -} - -uint8_t -ao_sleep_for(__xdata void *wchan, uint16_t timeout) -{ - uint8_t ret; - if (timeout) - ao_alarm(timeout); - ret = ao_sleep(wchan); - if (timeout) - ao_clear_alarm(); + } return ret; } -- cgit v1.2.3 From 135abf0e7c5ceb5738a0b5f68fe2be4b7abdae5e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 23:18:38 -0800 Subject: altos/cc1200: Adjust bit-sync configuration The default bit timing adjustment mechanism allows for only a 0.2% deviation from the programmed bit timing. I found one TeleMini device which is beyond that tolerance as it was built with an older crystal with more error. Switch to the more expensive synchronization mechanism which allows up to 2% timing error, but requires a multi-byte preamble (which we have). This fixes packet mode nicely. Signed-off-by: Keith Packard --- src/drivers/ao_cc1200.h | 32 ++++++++++++++++++++++++++++++++ src/drivers/ao_cc1200_CC1200.h | 9 +++++++++ src/drivers/ao_packet.c | 14 ++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_cc1200.h b/src/drivers/ao_cc1200.h index b04775fd..b2b63cde 100644 --- a/src/drivers/ao_cc1200.h +++ b/src/drivers/ao_cc1200.h @@ -438,6 +438,38 @@ #define CC1200_IF_MIX_CFG (CC1200_EXTENDED_BIT | 0x00) #define CC1200_FREQOFF_CFG (CC1200_EXTENDED_BIT | 0x01) #define CC1200_TOC_CFG (CC1200_EXTENDED_BIT | 0x02) + +#define CC1200_TOC_CFG_TOC_LIMIT 6 +#define CC1200_TOC_CFG_TOC_LIMIT_0_2 0 +#define CC1200_TOC_CFG_TOC_LIMIT_2 1 +#define CC1200_TOC_CFG_TOC_LIMIT_12 3 + +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN 3 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_8 0 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_16 1 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_32 2 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_64 3 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_128 4 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_256 5 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_8_16 0 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_6_16 1 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_2_16 2 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_1_16 3 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_1_16_SYNC 4 + +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN 0 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_8 0 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_16 1 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_32 2 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_64 3 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_128 4 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_256 5 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_FREEZE 0 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_6_32 1 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_2_32 2 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_1_32 3 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_1_32_SYNC 4 + #define CC1200_MARC_SPARE (CC1200_EXTENDED_BIT | 0x03) #define CC1200_ECG_CFG (CC1200_EXTENDED_BIT | 0x04) #define CC1200_MDMCFG2 (CC1200_EXTENDED_BIT | 0x05) diff --git a/src/drivers/ao_cc1200_CC1200.h b/src/drivers/ao_cc1200_CC1200.h index 35673123..f0214c2a 100644 --- a/src/drivers/ao_cc1200_CC1200.h +++ b/src/drivers/ao_cc1200_CC1200.h @@ -101,6 +101,15 @@ (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) | (0 << CC1200_MDMCFG2_CFM_DATA_EN)), + CC1200_MDMCFG0, /* General Modem Parameter Configuration Reg. 0 */ + ((0 << CC1200_MDMCFG0_TRANSPARENT_MODE_EN) | + (0 << CC1200_MDMCFG0_TRANSPARENT_INTFACT) | + (0 << CC1200_MDMCFG0_DATA_FILTER_EN) | + (1 << CC1200_MDMCFG0_VITERBI_EN)), + CC1200_TOC_CFG, /* Timing Offset Correction Configuration */ + ((CC1200_TOC_CFG_TOC_LIMIT_2 << CC1200_TOC_CFG_TOC_LIMIT) | + (CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_6_16 << CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN)| + (CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_2_32 << CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN)), CC1200_FREQ2, 0x6c, /* Frequency Configuration [23:16] */ CC1200_FREQ1, 0xa3, /* Frequency Configuration [15:8] */ CC1200_FREQ0, 0x33, /* Frequency Configuration [7:0] */ diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 18330ead..8c2db275 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -81,8 +81,16 @@ ao_packet_recv(uint16_t timeout) /* Check to see if we got a valid packet */ if (!dma_done) return 0; - if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) + if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) { + printf("bad crc addr %d len %d seq %d ack %d callsign %8.8s\n", + ao_rx_packet.packet.addr, + ao_rx_packet.packet.len, + ao_rx_packet.packet.seq, + ao_rx_packet.packet.ack, + ao_rx_packet.packet.callsign); + flush(); return 0; + } /* Accept packets with matching call signs, or any packet if * our callsign hasn't been configured @@ -90,8 +98,10 @@ ao_packet_recv(uint16_t timeout) if (ao_xmemcmp(ao_rx_packet.packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN) != 0 && - ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) + ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) { + printf ("bad call\n"); flush(); return 0; + } /* SYN packets carry no data */ if (ao_rx_packet.packet.len == AO_PACKET_SYN) { -- cgit v1.2.3 From 2ebb4dff758058ae9512cf36518416eb69b928f0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Feb 2015 08:57:55 -0800 Subject: altos: Remove some accidental debug printfs from ao_packet.c While fixing the cc1200 configuration, I added some debug printfs to this code. They were accidentally committed with the fix... Signed-off-by: Keith Packard --- src/drivers/ao_packet.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 8c2db275..18330ead 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -81,16 +81,8 @@ ao_packet_recv(uint16_t timeout) /* Check to see if we got a valid packet */ if (!dma_done) return 0; - if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) { - printf("bad crc addr %d len %d seq %d ack %d callsign %8.8s\n", - ao_rx_packet.packet.addr, - ao_rx_packet.packet.len, - ao_rx_packet.packet.seq, - ao_rx_packet.packet.ack, - ao_rx_packet.packet.callsign); - flush(); + if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) return 0; - } /* Accept packets with matching call signs, or any packet if * our callsign hasn't been configured @@ -98,10 +90,8 @@ ao_packet_recv(uint16_t timeout) if (ao_xmemcmp(ao_rx_packet.packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN) != 0 && - ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) { - printf ("bad call\n"); flush(); + ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) return 0; - } /* SYN packets carry no data */ if (ao_rx_packet.packet.len == AO_PACKET_SYN) { -- cgit v1.2.3 From b13a78e4f457f67605fc6dafc7f9733746a4f70c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Feb 2015 20:49:39 -0800 Subject: ao-bringup: Changes for telebt for keith's hacking Make the programming device auto-detect by username. Load binary from ~/altusmetrumllc Signed-off-by: Keith Packard --- ao-bringup/turnon_telebt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ao-bringup/turnon_telebt b/ao-bringup/turnon_telebt index c4902f31..f4100ae2 100755 --- a/ao-bringup/turnon_telebt +++ b/ao-bringup/turnon_telebt @@ -1,8 +1,5 @@ #!/bin/sh -# serial number of the TeleDongle being used as the flash programmer -DONGLE=612 - if [ -x ../ao-tools/ao-load/ao-load ]; then AOLOAD=../ao-tools/ao-load/ao-load elif [ -x /usr/bin/ao-load ]; then @@ -34,6 +31,19 @@ read SERIAL echo $RAWLOAD +case $USER in + bdale) + DONGLE=100 + ;; + keithp) + DONGLE=186 + ;; + *) + echo "Unknow user" + exit 1 + ;; +esac + $RAWLOAD -D $DONGLE -r ao_led_blink.ihx echo "LEDs should be blinking" sleep 5 @@ -45,7 +55,7 @@ read FREQ CAL_VALUE=`nickle -e "floor(434.55 / $FREQ * 1186611 + 0.5)"` echo "Programming flash with cal value " $CAL_VALUE -$AOLOAD -D $DONGLE --cal $CAL_VALUE /usr/share/altos/telebt-v1.0*.ihx $SERIAL +$AOLOAD -D $DONGLE --cal $CAL_VALUE ~/altusmetrumllc/Binaries/telebt-v1.0*.ihx $SERIAL echo "Serial number "$SERIAL" programmed with RF cal value "$CAL_VALUE echo $SERIAL","$CAL_VALUE >> cal_values -- cgit v1.2.3 From c51d39c7ea1153cd2d0dc02c47824a9f35b22fb9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Feb 2015 20:57:11 -0800 Subject: altosdroid: Lots of bluetooth connection changes Appears to more reliably abort in-progress connection attempts so you can switch TBT devices without having the previous device in operation. Shows which device the connection is being attempted for. Eliminate the 10-second timer and just disable the service when the GUI shuts down while no BT connection is running. Signed-off-by: Keith Packard --- .../org/altusmetrum/AltosDroid/AltosBluetooth.java | 175 ++++++++---- .../src/org/altusmetrum/AltosDroid/AltosDroid.java | 38 +-- .../AltosDroid/AltosDroidPreferences.java | 18 +- .../org/altusmetrum/AltosDroid/AltosDroidTab.java | 8 +- .../altusmetrum/AltosDroid/DeviceListActivity.java | 14 +- .../altusmetrum/AltosDroid/TelemetryService.java | 302 ++++++++++++--------- .../org/altusmetrum/AltosDroid/TelemetryState.java | 9 +- 7 files changed, 330 insertions(+), 234 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java index 3740f55d..973250a5 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java @@ -62,6 +62,65 @@ public class AltosBluetooth extends AltosLink { } + private void connected() { + try { + synchronized(this) { + if (socket != null) { + input = socket.getInputStream(); + output = socket.getOutputStream(); + + input_thread = new Thread(this); + input_thread.start(); + + // Configure the newly connected device for telemetry + print("~\nE 0\n"); + set_monitor(false); + if (D) Log.d(TAG, "ConnectThread: connected"); + + /* Let TelemetryService know we're connected + */ + handler.obtainMessage(TelemetryService.MSG_CONNECTED).sendToTarget(); + + /* Notify other waiting threads that we're connected now + */ + notifyAll(); + } + } + } catch (IOException io) { + connect_failed(); + } + } + + private void connect_failed() { + synchronized (this) { + if (socket != null) { + try { + socket.close(); + } catch (IOException e2) { + if (D) Log.e(TAG, "ConnectThread: Failed to close() socket after failed connection"); + } + socket = null; + } + input = null; + output = null; + handler.obtainMessage(TelemetryService.MSG_CONNECT_FAILED).sendToTarget(); + if (D) Log.e(TAG, "ConnectThread: Failed to establish connection"); + } + } + + private Object closing_lock = new Object(); + private boolean closing = false; + + private void disconnected() { + synchronized(closing_lock) { + if (D) Log.e(TAG, String.format("Connection lost during I/O. Closing %b", closing)); + if (!closing) { + if (D) Log.d(TAG, "Sending disconnected message"); + handler.obtainMessage(TelemetryService.MSG_DISCONNECTED).sendToTarget(); + } + } + } + private class ConnectThread extends Thread { private final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); @@ -83,54 +142,44 @@ public class AltosBluetooth extends AltosLink { // Always cancel discovery because it will slow down a connection adapter.cancelDiscovery(); - synchronized (AltosBluetooth.this) { - // Make a connection to the BluetoothSocket - try { - // This is a blocking call and will only return on a - // successful connection or an exception - socket.connect(); + BluetoothSocket local_socket; - input = socket.getInputStream(); - output = socket.getOutputStream(); - } catch (IOException e) { - // Close the socket - try { - socket.close(); - } catch (IOException e2) { - if (D) Log.e(TAG, "ConnectThread: Failed to close() socket after failed connection"); - } - input = null; - output = null; - AltosBluetooth.this.notifyAll(); - handler.obtainMessage(TelemetryService.MSG_CONNECT_FAILED).sendToTarget(); - if (D) Log.e(TAG, "ConnectThread: Failed to establish connection"); - return; + try { + synchronized (AltosBluetooth.this) { + local_socket = socket; } - input_thread = new Thread(AltosBluetooth.this); - input_thread.start(); - - // Configure the newly connected device for telemetry - print("~\nE 0\n"); - set_monitor(false); + if (local_socket != null) { + // Make a connection to the BluetoothSocket + // This is a blocking call and will only return on a + // successful connection or an exception + local_socket.connect(); + } - // Let TelemetryService know we're connected - handler.obtainMessage(TelemetryService.MSG_CONNECTED).sendToTarget(); + connected(); - // Notify other waiting threads, now that we're connected - AltosBluetooth.this.notifyAll(); + } catch (IOException e) { + connect_failed(); + } - // Reset the ConnectThread because we're done + synchronized (AltosBluetooth.this) { + /* Reset the ConnectThread because we're done + */ connect_thread = null; - - if (D) Log.d(TAG, "ConnectThread: Connect completed"); } + if (D) Log.d(TAG, "ConnectThread: Connect completed"); } public void cancel() { try { - if (socket != null) - socket.close(); + BluetoothSocket local_socket; + synchronized(AltosBluetooth.this) { + local_socket = socket; + socket = null; + } + if (local_socket != null) + local_socket.close(); + } catch (IOException e) { if (D) Log.e(TAG, "ConnectThread: close() of connect socket failed", e); } @@ -154,17 +203,13 @@ public class AltosBluetooth extends AltosLink { } private synchronized void wait_connected() throws InterruptedException, IOException { - if (input == null) { + if (input == null && socket != null) { if (D) Log.d(TAG, "wait_connected..."); wait(); if (D) Log.d(TAG, "wait_connected done"); - if (input == null) throw new IOException(); } - } - - private void connection_lost() { - if (D) Log.e(TAG, "Connection lost during I/O"); - handler.obtainMessage(TelemetryService.MSG_DISCONNECTED).sendToTarget(); + if (socket == null) + throw new IOException(); } public void print(String data) { @@ -175,9 +220,9 @@ public class AltosBluetooth extends AltosLink { output.write(bytes); if (D) Log.d(TAG, "print(): Wrote bytes: '" + data.replace('\n', '\\') + "'"); } catch (IOException e) { - connection_lost(); + disconnected(); } catch (InterruptedException e) { - connection_lost(); + disconnected(); } } @@ -189,9 +234,9 @@ public class AltosBluetooth extends AltosLink { output.write(bytes); if (D) Log.d(TAG, "print(): Wrote byte: '" + c + "'"); } catch (IOException e) { - connection_lost(); + disconnected(); } catch (InterruptedException e) { - connection_lost(); + disconnected(); } } @@ -208,32 +253,44 @@ public class AltosBluetooth extends AltosLink { buffer_len = input.read(buffer); buffer_off = 0; } catch (IOException e) { - connection_lost(); + if (D) Log.d(TAG, "getchar IOException"); + disconnected(); return AltosLink.ERROR; } catch (java.lang.InterruptedException e) { - connection_lost(); + if (D) Log.d(TAG, "getchar Interrupted"); + disconnected(); return AltosLink.ERROR; } } return buffer[buffer_off++]; } + public void closing() { + synchronized(closing_lock) { + if (D) Log.d(TAG, "Marked closing true"); + closing = true; + } + } + + public void close() { if (D) Log.d(TAG, "close(): begin"); + + closing(); + synchronized(this) { if (D) Log.d(TAG, "close(): synched"); - if (connect_thread != null) { - if (D) Log.d(TAG, "close(): stopping connect_thread"); - connect_thread.cancel(); - connect_thread = null; - } - if (D) Log.d(TAG, "close(): Closing socket"); - try { - socket.close(); - } catch (IOException e) { - if (D) Log.e(TAG, "close(): unable to close() socket"); + if (socket != null) { + if (D) Log.d(TAG, "close(): Closing socket"); + try { + socket.close(); + } catch (IOException e) { + if (D) Log.e(TAG, "close(): unable to close() socket"); + } + socket = null; } + connect_thread = null; if (input_thread != null) { if (D) Log.d(TAG, "close(): stopping input_thread"); try { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 53963f25..10e735c8 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -207,9 +207,12 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } break; case TelemetryState.CONNECT_CONNECTING: - mTitle.setText(R.string.title_connecting); + if (telemetry_state.address != null) + mTitle.setText(String.format("Connecting to %s...", telemetry_state.address.name)); + else + mTitle.setText("Connecting to something..."); break; - case TelemetryState.CONNECT_READY: + case TelemetryState.CONNECT_DISCONNECTED: case TelemetryState.CONNECT_NONE: mTitle.setText(R.string.title_not_connected); break; @@ -244,8 +247,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { update_ui(telemetry_state.state, telemetry_state.location); if (telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) start_timer(); - else - stop_timer(); } boolean same_string(String a, String b) { @@ -267,8 +268,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { void update_ui(AltosState state, Location location) { - Log.d(TAG, "update_ui"); - int prev_state = AltosLib.ao_flight_invalid; AltosGreatCircle from_receiver = null; @@ -277,7 +276,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { prev_state = saved_state.state; if (state != null) { - Log.d(TAG, String.format("prev state %d new state %d\n", prev_state, state.state)); if (state.state == AltosLib.ao_flight_stateless) { boolean prev_locked = false; boolean locked = false; @@ -297,7 +295,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } else { if (prev_state != state.state) { String currentTab = mTabHost.getCurrentTabTag(); - Log.d(TAG, "switch state"); switch (state.state) { case AltosLib.ao_flight_boost: if (currentTab.equals("pad")) mTabHost.setCurrentTabByTag("ascent"); @@ -328,22 +325,18 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } if (saved_state == null || !same_string(saved_state.callsign, state.callsign)) { - Log.d(TAG, "update callsign"); mCallsignView.setText(state.callsign); } if (saved_state == null || state.serial != saved_state.serial) { - Log.d(TAG, "update serial"); mSerialView.setText(String.format("%d", state.serial)); } if (saved_state == null || state.flight != saved_state.flight) { - Log.d(TAG, "update flight"); if (state.flight == AltosLib.MISSING) mFlightView.setText(""); else mFlightView.setText(String.format("%d", state.flight)); } if (saved_state == null || state.state != saved_state.state) { - Log.d(TAG, "update state"); if (state.state == AltosLib.ao_flight_stateless) { mStateLayout.setVisibility(View.GONE); } else { @@ -352,7 +345,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } } if (saved_state == null || state.rssi != saved_state.rssi) { - Log.d(TAG, "update rssi"); mRSSIView.setText(String.format("%d", state.rssi)); } } @@ -495,13 +487,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } @Override - public synchronized void onResume() { + public void onResume() { super.onResume(); if(D) Log.e(TAG, "+ ON RESUME +"); } @Override - public synchronized void onPause() { + public void onPause() { super.onPause(); if(D) Log.e(TAG, "- ON PAUSE -"); } @@ -548,21 +540,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } } - private void connectDevice(String address) { + private void connectDevice(Intent data) { // Attempt to connect to the device try { - if (D) Log.d(TAG, "Connecting to " + address); - mService.send(Message.obtain(null, TelemetryService.MSG_CONNECT, address)); + String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); + String name = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_NAME); + + if (D) Log.d(TAG, "Connecting to " + address + name); + DeviceAddress a = new DeviceAddress(address, name); + mService.send(Message.obtain(null, TelemetryService.MSG_CONNECT, a)); } catch (RemoteException e) { } } - private void connectDevice(Intent data) { - // Get the device MAC address - String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); - connectDevice(address); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java index 7ab70147..372500c1 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java @@ -22,9 +22,10 @@ import org.altusmetrum.altoslib_6.*; public class AltosDroidPreferences extends AltosPreferences { /* Active device preference name */ - final static String activeDevicePreference = "ACTIVE-DEVICE"; + final static String activeDeviceAddressPreference = "ACTIVE-DEVICE-ADDRESS"; + final static String activeDeviceNamePreference = "ACTIVE-DEVICE-NAME"; - static String active_device_address; + static DeviceAddress active_device_address; public static void init(Context context) { if (backend != null) @@ -32,18 +33,23 @@ public class AltosDroidPreferences extends AltosPreferences { AltosPreferences.init(new AltosDroidPreferencesBackend(context)); - active_device_address = backend.getString(activeDevicePreference, null); + String address = backend.getString(activeDeviceAddressPreference, null); + String name = backend.getString(activeDeviceNamePreference, null); + + if (address != null && name != null) + active_device_address = new DeviceAddress (address, name); } - public static void set_active_device(String address) { + public static void set_active_device(DeviceAddress address) { synchronized(backend) { active_device_address = address; - backend.putString(activeDevicePreference, active_device_address); + backend.putString(activeDeviceAddressPreference, active_device_address.address); + backend.putString(activeDeviceNamePreference, active_device_address.name); flush_preferences(); } } - public static String active_device() { + public static DeviceAddress active_device() { synchronized(backend) { return active_device_address; } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java index cbb20045..f61e7ef2 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java @@ -71,13 +71,9 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen last_state = state; last_from_receiver = from_receiver; last_receiver = receiver; - if (is_current) { - if (AltosDroid.D) Log.d(AltosDroid.TAG, String.format("%s: visible, performing update", tab_name())); - + if (is_current) show(state, from_receiver, receiver); - } else { - if (AltosDroid.D) Log.d(AltosDroid.TAG, String.format("%s: not visible, skipping update", tab_name())); + else return; - } } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java index 71692122..fd6abe0f 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java @@ -50,7 +50,8 @@ public class DeviceListActivity extends Activity { private static final boolean D = true; // Return Intent extra - public static String EXTRA_DEVICE_ADDRESS = "device_address"; + public static final String EXTRA_DEVICE_ADDRESS = "device_address"; + public static final String EXTRA_DEVICE_NAME = "device_name"; // Member fields private BluetoothAdapter mBtAdapter; @@ -164,9 +165,20 @@ public class DeviceListActivity extends Activity { String info = ((TextView) v).getText().toString(); String address = info.substring(info.length() - 17); + int newline = info.indexOf('\n'); + + String name = null; + if (newline > 0) + name = info.substring(0, newline); + else + name = info; + + if (D) Log.d(TAG, String.format("******* selected item '%s'", info)); + // Create the result Intent and include the MAC address Intent intent = new Intent(); intent.putExtra(EXTRA_DEVICE_ADDRESS, address); + intent.putExtra(EXTRA_DEVICE_NAME, name); // Set result and finish this Activity setResult(Activity.RESULT_OK, intent); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index d4ac66aa..5e34d610 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -69,24 +69,21 @@ public class TelemetryService extends Service implements LocationListener { private int NOTIFICATION = R.string.telemetry_service_label; //private NotificationManager mNM; - // Timer - we wake up every now and then to decide if the service should stop - private Timer timer = new Timer(); - - ArrayList mClients = new ArrayList(); // Keeps track of all current registered clients. - final Handler mHandler = new IncomingHandler(this); - final Messenger mMessenger = new Messenger(mHandler); // Target we publish for clients to send messages to IncomingHandler. + ArrayList clients = new ArrayList(); // Keeps track of all current registered clients. + final Handler handler = new IncomingHandler(this); + final Messenger messenger = new Messenger(handler); // Target we publish for clients to send messages to IncomingHandler. // Name of the connected device - String address; - private AltosBluetooth mAltosBluetooth = null; - private TelemetryReader mTelemetryReader = null; - private TelemetryLogger mTelemetryLogger = null; - // Local Bluetooth adapter - private BluetoothAdapter mBluetoothAdapter = null; + DeviceAddress address; + private AltosBluetooth altos_bluetooth = null; + private TelemetryReader telemetry_reader = null; + private TelemetryLogger telemetry_logger = null; - private TelemetryState telemetry_state; + // Local Bluetooth adapter + private BluetoothAdapter bluetooth_adapter = null; // Last data seen; send to UI when it starts + private TelemetryState telemetry_state; // Handler of incoming messages from clients. static class IncomingHandler extends Handler { @@ -99,27 +96,46 @@ public class TelemetryService extends Service implements LocationListener { if (s == null) return; switch (msg.what) { + + /* Messages from application */ case MSG_REGISTER_CLIENT: - s.mClients.add(msg.replyTo); - try { - // Now we try to send the freshly connected UI any relavant information about what - // we're talking to - msg.replyTo.send(s.message()); - } catch (RemoteException e) { - s.mClients.remove(msg.replyTo); - } - if (D) Log.d(TAG, "Client bound to service"); + s.add_client(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: - s.mClients.remove(msg.replyTo); - if (D) Log.d(TAG, "Client unbound from service"); + s.remove_client(msg.replyTo); break; case MSG_CONNECT: if (D) Log.d(TAG, "Connect command received"); - String address = (String) msg.obj; + DeviceAddress address = (DeviceAddress) msg.obj; AltosDroidPreferences.set_active_device(address); - s.startAltosBluetooth(address); + s.start_altos_bluetooth(address); + break; + case MSG_SETFREQUENCY: + if (D) Log.d(TAG, "MSG_SETFREQUENCY"); + s.telemetry_state.frequency = (Double) msg.obj; + if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) { + try { + s.altos_bluetooth.set_radio_frequency(s.telemetry_state.frequency); + s.altos_bluetooth.save_frequency(); + } catch (InterruptedException e) { + } catch (TimeoutException e) { + } + } + s.send_to_clients(); + break; + case MSG_SETBAUD: + if (D) Log.d(TAG, "MSG_SETBAUD"); + s.telemetry_state.telemetry_rate = (Integer) msg.obj; + if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) { + s.altos_bluetooth.set_telemetry_rate(s.telemetry_state.telemetry_rate); + s.altos_bluetooth.save_telemetry_rate(); + } + s.send_to_clients(); break; + + /* + *Messages from AltosBluetooth + */ case MSG_CONNECTED: if (D) Log.d(TAG, "Connected to device"); try { @@ -128,51 +144,40 @@ public class TelemetryService extends Service implements LocationListener { } break; case MSG_CONNECT_FAILED: - if (D) Log.d(TAG, "Connection failed... retrying"); - if (s.address != null) - s.startAltosBluetooth(s.address); + if (s.address != null && !s.clients.isEmpty()) { + if (D) Log.d(TAG, "Connection failed... retrying"); + s.start_altos_bluetooth(s.address); + } else { + s.stop_altos_bluetooth(true); + } break; case MSG_DISCONNECTED: Log.d(TAG, "MSG_DISCONNECTED"); - s.stopAltosBluetooth(); + if (s.address != null && !s.clients.isEmpty()) { + if (D) Log.d(TAG, "Connection lost... retrying"); + s.start_altos_bluetooth(s.address); + } else { + s.stop_altos_bluetooth(true); + } break; + + /* + * Messages from TelemetryReader + */ case MSG_TELEMETRY: - // forward telemetry messages s.telemetry_state.state = (AltosState) msg.obj; if (s.telemetry_state.state != null) { if (D) Log.d(TAG, "Save state"); AltosPreferences.set_state(0, s.telemetry_state.state, null); } if (D) Log.d(TAG, "MSG_TELEMETRY"); - s.sendMessageToClients(); + s.send_to_clients(); break; case MSG_CRC_ERROR: // forward crc error messages s.telemetry_state.crc_errors = (Integer) msg.obj; if (D) Log.d(TAG, "MSG_CRC_ERROR"); - s.sendMessageToClients(); - break; - case MSG_SETFREQUENCY: - if (D) Log.d(TAG, "MSG_SETFREQUENCY"); - s.telemetry_state.frequency = (Double) msg.obj; - if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) { - try { - s.mAltosBluetooth.set_radio_frequency(s.telemetry_state.frequency); - s.mAltosBluetooth.save_frequency(); - } catch (InterruptedException e) { - } catch (TimeoutException e) { - } - } - s.sendMessageToClients(); - break; - case MSG_SETBAUD: - if (D) Log.d(TAG, "MSG_SETBAUD"); - s.telemetry_state.telemetry_rate = (Integer) msg.obj; - if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) { - s.mAltosBluetooth.set_telemetry_rate(s.telemetry_state.telemetry_rate); - s.mAltosBluetooth.save_telemetry_rate(); - } - s.sendMessageToClients(); + s.send_to_clients(); break; default: super.handleMessage(msg); @@ -180,6 +185,8 @@ public class TelemetryService extends Service implements LocationListener { } } + /* Construct the message to deliver to clients + */ private Message message() { if (telemetry_state == null) Log.d(TAG, "telemetry_state null!"); @@ -188,117 +195,149 @@ public class TelemetryService extends Service implements LocationListener { return Message.obtain(null, AltosDroid.MSG_STATE, telemetry_state); } - private void sendMessageToClients() { - Message m = message(); - if (D) Log.d(TAG, String.format("Send message to %d clients", mClients.size())); - for (int i=mClients.size()-1; i>=0; i--) { - try { - if (D) Log.d(TAG, String.format("Send message to client %d", i)); - mClients.get(i).send(m); - } catch (RemoteException e) { - mClients.remove(i); - } + /* A new friend has connected + */ + private void add_client(Messenger client) { + + clients.add(client); + if (D) Log.d(TAG, "Client bound to service"); + + /* On connect, send the current state to the new client + */ + send_to_client(client, message()); + + /* If we've got an address from a previous session, then + * go ahead and try to reconnect to the device + */ + if (address != null && telemetry_state.connect == TelemetryState.CONNECT_DISCONNECTED) { + if (D) Log.d(TAG, "Reconnecting now..."); + start_altos_bluetooth(address); } } - private void stopAltosBluetooth() { - if (D) Log.d(TAG, "stopAltosBluetooth(): begin"); - telemetry_state.connect = TelemetryState.CONNECT_READY; - if (mTelemetryReader != null) { - if (D) Log.d(TAG, "stopAltosBluetooth(): stopping TelemetryReader"); - mTelemetryReader.interrupt(); + /* A client has disconnected, clean up + */ + private void remove_client(Messenger client) { + clients.remove(client); + if (D) Log.d(TAG, "Client unbound from service"); + + /* When the list of clients is empty, stop the service if + * we have no current telemetry source + */ + + if (clients.isEmpty() && telemetry_state.connect == TelemetryState.CONNECT_DISCONNECTED) { + if (!D) Log.d(TAG, "No clients, no connection. Stopping\n"); + stopSelf(); + } + } + + private void send_to_client(Messenger client, Message m) { + try { + if (D) Log.d(TAG, String.format("Send message to client %s", client.toString())); + client.send(m); + } catch (RemoteException e) { + if (D) Log.e(TAG, String.format("Client %s disappeared", client.toString())); + remove_client(client); + } + } + + private void send_to_clients() { + Message m = message(); + if (D) Log.d(TAG, String.format("Send message to %d clients", clients.size())); + for (Messenger client : clients) + send_to_client(client, m); + } + + private void stop_altos_bluetooth(boolean notify) { + if (D) Log.d(TAG, "stop_altos_bluetooth(): begin"); + telemetry_state.connect = TelemetryState.CONNECT_DISCONNECTED; + telemetry_state.address = null; + + if (altos_bluetooth != null) + altos_bluetooth.closing(); + + if (telemetry_reader != null) { + if (D) Log.d(TAG, "stop_altos_bluetooth(): stopping TelemetryReader"); + telemetry_reader.interrupt(); try { - mTelemetryReader.join(); + telemetry_reader.join(); } catch (InterruptedException e) { } - mTelemetryReader = null; + telemetry_reader = null; } - if (mTelemetryLogger != null) { - if (D) Log.d(TAG, "stopAltosBluetooth(): stopping TelemetryLogger"); - mTelemetryLogger.stop(); - mTelemetryLogger = null; + if (telemetry_logger != null) { + if (D) Log.d(TAG, "stop_altos_bluetooth(): stopping TelemetryLogger"); + telemetry_logger.stop(); + telemetry_logger = null; } - if (mAltosBluetooth != null) { - if (D) Log.d(TAG, "stopAltosBluetooth(): stopping AltosBluetooth"); - mAltosBluetooth.close(); - mAltosBluetooth = null; + if (altos_bluetooth != null) { + if (D) Log.d(TAG, "stop_altos_bluetooth(): stopping AltosBluetooth"); + altos_bluetooth.close(); + altos_bluetooth = null; } telemetry_state.config = null; - if (D) Log.d(TAG, "stopAltosBluetooth(): send message to clients"); - sendMessageToClients(); + if (notify) { + if (D) Log.d(TAG, "stop_altos_bluetooth(): send message to clients"); + send_to_clients(); + if (clients.isEmpty()) { + if (D) Log.d(TAG, "stop_altos_bluetooth(): no clients, terminating"); + stopSelf(); + } + } } - private void startAltosBluetooth(String address) { + private void start_altos_bluetooth(DeviceAddress address) { // Get the BLuetoothDevice object - BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); + BluetoothDevice device = bluetooth_adapter.getRemoteDevice(address.address); + stop_altos_bluetooth(false); this.address = address; - if (mAltosBluetooth == null) { - if (D) Log.d(TAG, String.format("startAltosBluetooth(): Connecting to %s (%s)", device.getName(), device.getAddress())); - mAltosBluetooth = new AltosBluetooth(device, mHandler); - telemetry_state.connect = TelemetryState.CONNECT_CONNECTING; - sendMessageToClients(); - } else { - // This is a bit of a hack - if it appears we're still connected, we treat this as a restart. - // So, to give a suitable delay to teardown/bringup, we just schedule a resend of a message - // to ourselves in a few seconds time that will ultimately call this method again. - // ... then we tear down the existing connection. - // We do it this way around so that we don't lose a reference to the device when this method - // is called on reception of MSG_CONNECT_FAILED in the handler above. - mHandler.sendMessageDelayed(Message.obtain(null, MSG_CONNECT, address), 3000); - stopAltosBluetooth(); - } + if (D) Log.d(TAG, String.format("start_altos_bluetooth(): Connecting to %s (%s)", device.getName(), device.getAddress())); + altos_bluetooth = new AltosBluetooth(device, handler); + telemetry_state.connect = TelemetryState.CONNECT_CONNECTING; + telemetry_state.address = address; + send_to_clients(); } private void connected() throws InterruptedException { if (D) Log.d(TAG, "connected top"); try { - if (mAltosBluetooth == null) + if (altos_bluetooth == null) throw new InterruptedException("no bluetooth"); - telemetry_state.config = mAltosBluetooth.config_data(); - mAltosBluetooth.set_radio_frequency(telemetry_state.frequency); - mAltosBluetooth.set_telemetry_rate(telemetry_state.telemetry_rate); + telemetry_state.config = altos_bluetooth.config_data(); + altos_bluetooth.set_radio_frequency(telemetry_state.frequency); + altos_bluetooth.set_telemetry_rate(telemetry_state.telemetry_rate); } catch (TimeoutException e) { // If this timed out, then we really want to retry it, but // probably safer to just retry the connection from scratch. - mHandler.obtainMessage(MSG_CONNECT_FAILED).sendToTarget(); + handler.obtainMessage(MSG_CONNECT_FAILED).sendToTarget(); return; } if (D) Log.d(TAG, "connected bluetooth configured"); telemetry_state.connect = TelemetryState.CONNECT_CONNECTED; + telemetry_state.address = address; - mTelemetryReader = new TelemetryReader(mAltosBluetooth, mHandler, telemetry_state.state); - mTelemetryReader.start(); + telemetry_reader = new TelemetryReader(altos_bluetooth, handler, telemetry_state.state); + telemetry_reader.start(); if (D) Log.d(TAG, "connected TelemetryReader started"); - mTelemetryLogger = new TelemetryLogger(this, mAltosBluetooth); + telemetry_logger = new TelemetryLogger(this, altos_bluetooth); if (D) Log.d(TAG, "Notify UI of connection"); - sendMessageToClients(); - } - - private void onTimerTick() { - if (D) Log.d(TAG, "Timer wakeup"); - try { - if (mClients.size() <= 0 && telemetry_state.connect != TelemetryState.CONNECT_CONNECTED) { - stopSelf(); - } - } catch (Throwable t) { - Log.e(TAG, "Timer failed: ", t); - } + send_to_clients(); } @Override public void onCreate() { // Get local Bluetooth adapter - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + bluetooth_adapter = BluetoothAdapter.getDefaultAdapter(); // If the adapter is null, then Bluetooth is not supported - if (mBluetoothAdapter == null) { + if (bluetooth_adapter == null) { Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); } @@ -310,7 +349,8 @@ public class TelemetryService extends Service implements LocationListener { // Create a reference to the NotificationManager so that we can update our notifcation text later //mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - telemetry_state.connect = TelemetryState.CONNECT_READY; + telemetry_state.connect = TelemetryState.CONNECT_DISCONNECTED; + telemetry_state.address = null; AltosSavedState saved_state = AltosPreferences.state(0); @@ -319,17 +359,14 @@ public class TelemetryService extends Service implements LocationListener { telemetry_state.state = saved_state.state; } - // Start our timer - first event in 10 seconds, then every 10 seconds after that. - timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 10000L, 10000L); - // Listen for GPS and Network position updates LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this); - String address = AltosDroidPreferences.active_device(); + DeviceAddress address = AltosDroidPreferences.active_device(); if (address != null) - startAltosBluetooth(address); + start_altos_bluetooth(address); } @Override @@ -366,28 +403,25 @@ public class TelemetryService extends Service implements LocationListener { ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this); // Stop the bluetooth Comms threads - stopAltosBluetooth(); + stop_altos_bluetooth(true); // Demote us from the foreground, and cancel the persistent notification. stopForeground(true); - // Stop our timer - if (timer != null) {timer.cancel();} - // Tell the user we stopped. Toast.makeText(this, R.string.telemetry_service_stopped, Toast.LENGTH_SHORT).show(); } @Override public IBinder onBind(Intent intent) { - return mMessenger.getBinder(); + return messenger.getBinder(); } public void onLocationChanged(Location location) { telemetry_state.location = location; if (D) Log.d(TAG, "location changed"); - sendMessageToClients(); + send_to_clients(); } public void onStatusChanged(String provider, int status, Bundle extras) { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryState.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryState.java index 862847d2..ca066fc2 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryState.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryState.java @@ -21,12 +21,13 @@ import org.altusmetrum.altoslib_6.*; import android.location.Location; public class TelemetryState { - public static final int CONNECT_NONE = 0; - public static final int CONNECT_READY = 1; - public static final int CONNECT_CONNECTING = 2; - public static final int CONNECT_CONNECTED = 3; + public static final int CONNECT_NONE = 0; + public static final int CONNECT_DISCONNECTED = 1; + public static final int CONNECT_CONNECTING = 2; + public static final int CONNECT_CONNECTED = 3; int connect; + DeviceAddress address; AltosConfigData config; AltosState state; Location location; -- cgit v1.2.3 From 877609a60a9f2c61c1efad8285b2a3c22f59be28 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Feb 2015 21:19:09 -0800 Subject: altosdroid: Explicitly disconnect BT on termination or 'disconnect' This adds an explicit message to the telemetry service telling it when to stop trying to talk to the bluetooth device. Until this message is received, the service will reconnect to the specified BT device. That message is sent when you 'quit' the application, or when you 'disconnect'. Signed-off-by: Keith Packard --- altosdroid/res/menu/option_menu.xml | 3 +++ altosdroid/res/values/strings.xml | 1 + altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java | 14 +++++++++++++- .../src/org/altusmetrum/AltosDroid/TelemetryService.java | 10 ++++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/altosdroid/res/menu/option_menu.xml b/altosdroid/res/menu/option_menu.xml index 3bd5a54e..f005e881 100644 --- a/altosdroid/res/menu/option_menu.xml +++ b/altosdroid/res/menu/option_menu.xml @@ -17,6 +17,9 @@ + diff --git a/altosdroid/res/values/strings.xml b/altosdroid/res/values/strings.xml index 0cc99349..8a5b29b4 100644 --- a/altosdroid/res/values/strings.xml +++ b/altosdroid/res/values/strings.xml @@ -27,6 +27,7 @@ Connect a device + Disconnect device Quit Select radio frequency Select data rate diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 10e735c8..273688d8 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -553,6 +553,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } } + private void disconnectDevice() { + try { + mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, null)); + } catch (RemoteException e) { + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -610,9 +617,14 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { serverIntent = new Intent(this, DeviceListActivity.class); startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); return true; + case R.id.disconnect: + /* Disconnect the bluetooth device + */ + disconnectDevice(); + return true; case R.id.quit: Log.d(TAG, "R.id.quit"); - stopService(new Intent(AltosDroid.this, TelemetryService.class)); + disconnectDevice(); finish(); return true; case R.id.select_freq: diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 5e34d610..5f138972 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -63,6 +63,7 @@ public class TelemetryService extends Service implements LocationListener { static final int MSG_SETFREQUENCY = 8; static final int MSG_CRC_ERROR = 9; static final int MSG_SETBAUD = 10; + static final int MSG_DISCONNECT = 11; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. @@ -110,6 +111,11 @@ public class TelemetryService extends Service implements LocationListener { AltosDroidPreferences.set_active_device(address); s.start_altos_bluetooth(address); break; + case MSG_DISCONNECT: + if (D) Log.d(TAG, "Disconnect command received"); + s.address = null; + s.stop_altos_bluetooth(true); + break; case MSG_SETFREQUENCY: if (D) Log.d(TAG, "MSG_SETFREQUENCY"); s.telemetry_state.frequency = (Double) msg.obj; @@ -144,7 +150,7 @@ public class TelemetryService extends Service implements LocationListener { } break; case MSG_CONNECT_FAILED: - if (s.address != null && !s.clients.isEmpty()) { + if (s.address != null) { if (D) Log.d(TAG, "Connection failed... retrying"); s.start_altos_bluetooth(s.address); } else { @@ -153,7 +159,7 @@ public class TelemetryService extends Service implements LocationListener { break; case MSG_DISCONNECTED: Log.d(TAG, "MSG_DISCONNECTED"); - if (s.address != null && !s.clients.isEmpty()) { + if (s.address != null) { if (D) Log.d(TAG, "Connection lost... retrying"); s.start_altos_bluetooth(s.address); } else { -- cgit v1.2.3 From 8f2d82461f3cf5da157b23ea45a2fa60d56b196b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Feb 2015 21:32:54 -0800 Subject: altosdroid: Only speak when GUI is running Create voice in onStart, stop it in onStop. This way, if some other application is in use, the voice won't be annoying you. Signed-off-by: Keith Packard --- altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 273688d8..41045f03 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -352,7 +352,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { for (AltosDroidTab mTab : mTabs) mTab.update_ui(state, from_receiver, location, mTab == mTabsAdapter.currentItem()); - if (state != null) + if (state != null && mAltosVoice != null) mAltosVoice.tell(state, from_receiver); saved_state = state; @@ -465,8 +465,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { mStateLayout = (RelativeLayout) findViewById(R.id.state_container); mStateView = (TextView) findViewById(R.id.state_value); mAgeView = (TextView) findViewById(R.id.age_value); - - mAltosVoice = new AltosVoice(this); } @Override @@ -484,6 +482,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { doBindService(); + if (mAltosVoice == null) + mAltosVoice = new AltosVoice(this); } @Override @@ -504,6 +504,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { if(D) Log.e(TAG, "-- ON STOP --"); doUnbindService(); + if (mAltosVoice != null) { + mAltosVoice.stop(); + mAltosVoice = null; + } } @Override -- cgit v1.2.3 From e6630ac41ca0d8563cf9a0df5d4acba8192e9624 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Feb 2015 21:35:34 -0800 Subject: altosdroid: Missing file: DeviceAddress.java Signed-off-by: Keith Packard --- .../org/altusmetrum/AltosDroid/DeviceAddress.java | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 altosdroid/src/org/altusmetrum/AltosDroid/DeviceAddress.java diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/DeviceAddress.java b/altosdroid/src/org/altusmetrum/AltosDroid/DeviceAddress.java new file mode 100644 index 00000000..673d72dd --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/DeviceAddress.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2015 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. + */ + +package org.altusmetrum.AltosDroid; + +public class DeviceAddress { + public String address; + public String name; + + public DeviceAddress(String address, String name) { + this.address = address; + this.name = name; + } +} -- cgit v1.2.3 From 106b16b4d5d024543d7ad8c4b4762151e253f3c4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Feb 2015 22:22:37 -0800 Subject: altosdroid: Ignore automatic tab changing while activity is saved When the activity state is saved (after onSaveInstanceState()), we can't update the UI until the activity is restarted or restored; that means any UI changes we make, like switching tabs, must deal with this by allowing those changes to be ignored, using commitAllowingStateLoss instead of commit. Signed-off-by: Keith Packard --- altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java index f61e7ef2..0896b3a3 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java @@ -64,7 +64,7 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen ft.show(this); } else ft.hide(this); - ft.commit(); + ft.commitAllowingStateLoss(); } public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver, boolean is_current) { -- cgit v1.2.3