From 24167015705ae831692b95735968b04a876f935e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 4 Apr 2014 23:34:48 -0700 Subject: altos: Rename 'core' to 'kernel' core remains a bad name to use -- dirvish skips files (and directories, it seems) with that name. Signed-off-by: Keith Packard --- src/kernel/ao_report.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 src/kernel/ao_report.c (limited to 'src/kernel/ao_report.c') diff --git a/src/kernel/ao_report.c b/src/kernel/ao_report.c new file mode 100644 index 00000000..1104cd82 --- /dev/null +++ b/src/kernel/ao_report.c @@ -0,0 +1,198 @@ +/* + * Copyright © 2009 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 "ao.h" +#include +#include + +#define BIT(i,x) ((x) ? (1 << (i)) : 0) +#define MORSE1(a) (1 | BIT(3,a)) +#define MORSE2(a,b) (2 | BIT(3,a) | BIT(4,b)) +#define MORSE3(a,b,c) (3 | BIT(3,a) | BIT(4,b) | BIT(5,c)) +#define MORSE4(a,b,c,d) (4 | BIT(3,a) | BIT(4,b) | BIT(5,c) | BIT(6,d)) +#define MORSE5(a,b,c,d,e) (5 | BIT(3,a) | BIT(4,b) | BIT(5,c) | BIT(6,d) | BIT(7,e)) + +static const uint8_t flight_reports[] = { + MORSE3(0,0,0), /* startup, 'S' */ + MORSE2(0,0), /* idle 'I' */ + MORSE4(0,1,1,0), /* pad 'P' */ + MORSE4(1,0,0,0), /* boost 'B' */ + MORSE4(0,0,1,0), /* fast 'F' */ + MORSE4(1,0,1,0), /* coast 'C' */ + MORSE3(1,0,0), /* drogue 'D' */ + MORSE2(1,1), /* main 'M' */ + MORSE4(0,1,0,0), /* landed 'L' */ + MORSE4(1,0,0,1), /* invalid 'X' */ +}; + +#if HAS_BEEP +#define low(time) ao_beep_for(AO_BEEP_LOW, time) +#define mid(time) ao_beep_for(AO_BEEP_MID, time) +#define high(time) ao_beep_for(AO_BEEP_HIGH, time) +#else +#define low(time) ao_led_for(AO_LED_GREEN, time) +#define mid(time) ao_led_for(AO_LED_RED, time) +#define high(time) ao_led_for(AO_LED_GREEN|AO_LED_RED, time) +#endif +#define pause(time) ao_delay(time) + +static __pdata enum ao_flight_state ao_report_state; + +static void +ao_report_beep(void) __reentrant +{ + uint8_t r = flight_reports[ao_flight_state]; + uint8_t l = r & 7; + + if (!r) + return; + while (l--) { + if (r & 8) + mid(AO_MS_TO_TICKS(600)); + else + mid(AO_MS_TO_TICKS(200)); + pause(AO_MS_TO_TICKS(200)); + r >>= 1; + } + pause(AO_MS_TO_TICKS(400)); +} + +static void +ao_report_digit(uint8_t digit) __reentrant +{ + if (!digit) { + mid(AO_MS_TO_TICKS(500)); + pause(AO_MS_TO_TICKS(200)); + } else { + while (digit--) { + mid(AO_MS_TO_TICKS(200)); + pause(AO_MS_TO_TICKS(200)); + } + } + pause(AO_MS_TO_TICKS(300)); +} + +static void +ao_report_altitude(void) +{ + __pdata int16_t agl = ao_max_height; + __xdata uint8_t digits[10]; + __pdata uint8_t ndigits, i; + + if (agl < 0) + agl = 0; + ndigits = 0; + do { + digits[ndigits++] = agl % 10; + agl /= 10; + } while (agl); + + i = ndigits; + do + ao_report_digit(digits[--i]); + while (i != 0); +} + +#if HAS_IGNITE_REPORT +static uint8_t +ao_report_igniter_ready(enum ao_igniter igniter) +{ + return ao_igniter_status(igniter) == ao_igniter_ready ? 1 : 0; +} + +uint8_t +ao_report_igniter(void) +{ + return (ao_report_igniter_ready(ao_igniter_drogue) | + (ao_report_igniter_ready(ao_igniter_main) << 1)); +} + +static void +ao_report_continuity(void) __reentrant +{ + uint8_t c; + +#if !HAS_IGNITE + if (!ao_igniter_present) + return; +#endif + c = ao_report_igniter(); + if (c) { + while (c--) { + high(AO_MS_TO_TICKS(25)); + pause(AO_MS_TO_TICKS(100)); + } + } else { + c = 10; + while (c--) { + high(AO_MS_TO_TICKS(20)); + low(AO_MS_TO_TICKS(20)); + } + } +#if HAS_LOG + if (ao_log_full()) { + pause(AO_MS_TO_TICKS(100)); + c = 2; + while (c--) { + low(AO_MS_TO_TICKS(100)); + mid(AO_MS_TO_TICKS(100)); + high(AO_MS_TO_TICKS(100)); + mid(AO_MS_TO_TICKS(100)); + } + } +#endif +} +#endif + +void +ao_report(void) +{ + ao_report_state = ao_flight_state; + for(;;) { + ao_report_beep(); + if (ao_flight_state == ao_flight_landed) { + ao_report_altitude(); +#if HAS_FLIGHT + ao_delay(AO_SEC_TO_TICKS(5)); + continue; +#endif + } +#if HAS_IGNITE_REPORT + if (ao_flight_state == ao_flight_idle) + ao_report_continuity(); + while (ao_flight_state == ao_flight_pad) { + uint8_t c; + ao_report_continuity(); + c = 50; + while (c-- && ao_flight_state == ao_flight_pad) + pause(AO_MS_TO_TICKS(100)); + } +#endif + + while (ao_report_state == ao_flight_state) + ao_sleep(DATA_TO_XDATA(&ao_flight_state)); + ao_report_state = ao_flight_state; + } +} + +static __xdata struct ao_task ao_report_task; + +void +ao_report_init(void) +{ + ao_add_task(&ao_report_task, ao_report, "report"); +} -- cgit v1.2.3 From 0d367fc24bfd0377db6f3b00a888a18245616767 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Apr 2014 00:18:57 -0700 Subject: altos: Report battery voltage instead of S at startup This works on everything with a beeper except TeleMetrum v1.0 which just doesn't have enough flash space for the code. Signed-off-by: Keith Packard --- src/cc1111/ao_arch.h | 2 ++ src/cc1111/ao_pins.h | 19 +++++++++++++++++++ src/easymega-v1.0/ao_pins.h | 1 + src/easymini-v1.0/Makefile | 1 + src/easymini-v1.0/ao_pins.h | 20 +++++++++++++++++++- src/kernel/ao_convert_volt.c | 10 ++++++++-- src/kernel/ao_report.c | 41 +++++++++++++++++++++++++++++++++-------- src/lpc/ao_arch.h | 4 ++++ src/teleballoon-v1.1/ao_pins.h | 1 + src/teleballoon-v2.0/ao_pins.h | 1 + src/telemega-v0.1/ao_pins.h | 1 + src/telemega-v1.0/ao_pins.h | 1 + src/telemetrum-v1.1/Makefile | 1 + src/telemetrum-v1.2/Makefile | 1 + src/telemetrum-v2.0/ao_pins.h | 1 + src/telemini-v2.0/Makefile | 1 + src/telemini-v2.0/ao_pins.h | 18 ++++++++++++++++++ 17 files changed, 113 insertions(+), 11 deletions(-) (limited to 'src/kernel/ao_report.c') diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 34235b08..fcac331b 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -326,4 +326,6 @@ void ao_p0_isr(void) __interrupt(13); #endif +#define AO_ADC_MAX 32767 + #endif /* _AO_ARCH_H_ */ diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 2f0e2884..5b1586e0 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -58,6 +58,7 @@ #define HAS_FLIGHT 1 #define HAS_USB 1 #define HAS_BEEP 1 + #define HAS_BATTERY_REPORT 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 #define HAS_ADC 1 @@ -94,6 +95,7 @@ #define HAS_FLIGHT 1 #define HAS_USB 1 #define HAS_BEEP 1 + #define HAS_BATTERY_REPORT 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 #define HAS_ADC 1 @@ -572,4 +574,21 @@ struct ao_adc { #endif }; +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 5 /* 5k */ +#define AO_BATTERY_DIV_MINUS 10 /* 10k */ + +/* + * Voltage divider on ADC igniter samplers + */ +#define AO_IGNITE_DIV_PLUS 100 /* 100k */ +#define AO_IGNITE_DIV_MINUS 27 /* 27k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 + #endif /* _AO_PINS_H_ */ diff --git a/src/easymega-v1.0/ao_pins.h b/src/easymega-v1.0/ao_pins.h index 0b6c0f07..fb6e05b1 100644 --- a/src/easymega-v1.0/ao_pins.h +++ b/src/easymega-v1.0/ao_pins.h @@ -66,6 +66,7 @@ #define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define HAS_RADIO 0 #define HAS_TELEMETRY 0 #define HAS_APRS 0 diff --git a/src/easymini-v1.0/Makefile b/src/easymini-v1.0/Makefile index 7dae2692..654be22b 100644 --- a/src/easymini-v1.0/Makefile +++ b/src/easymini-v1.0/Makefile @@ -32,6 +32,7 @@ ALTOS_SRC = \ ao_sample.c \ ao_data.c \ ao_convert_pa.c \ + ao_convert_volt.c \ ao_task.c \ ao_log.c \ ao_log_mini.c \ diff --git a/src/easymini-v1.0/ao_pins.h b/src/easymini-v1.0/ao_pins.h index 6757047f..0edde5a2 100644 --- a/src/easymini-v1.0/ao_pins.h +++ b/src/easymini-v1.0/ao_pins.h @@ -15,7 +15,8 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define HAS_BEEP 1 +#define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define AO_STACK_SIZE 384 @@ -133,3 +134,20 @@ struct ao_adc { #define AO_ADC_DUMP(p) \ printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \ (p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt) + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 100 /* 100k */ +#define AO_BATTERY_DIV_MINUS 27 /* 27k */ + +/* + * Voltage divider on ADC igniter samplers + */ +#define AO_IGNITE_DIV_PLUS 100 /* 100k */ +#define AO_IGNITE_DIV_MINUS 27 /* 27k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 diff --git a/src/kernel/ao_convert_volt.c b/src/kernel/ao_convert_volt.c index 8556d423..7afc34bf 100644 --- a/src/kernel/ao_convert_volt.c +++ b/src/kernel/ao_convert_volt.c @@ -17,17 +17,23 @@ #include "ao.h" -#define scale(v,p,m) ((int32_t) (v) * (AO_ADC_REFERENCE_DV * ((p) + (m))) / (AO_ADC_MAX * (m))) +#define MUL(p,m) ((int32_t) AO_ADC_REFERENCE_DV * ((p) + (m))) +#define ADD(p,m) (MUL(p,m)/2) +#define DIV(p,m) ((int32_t) AO_ADC_MAX * (m)) +#define scale(v,p,m) (((int32_t) (v) * MUL(p,m) + ADD(p,m)) / DIV(p,m)) +#if HAS_APRS || HAS_BATTERY_REPORT int16_t ao_battery_decivolt(int16_t adc) { return scale(adc, AO_BATTERY_DIV_PLUS, AO_BATTERY_DIV_MINUS); } +#endif +#if HAS_APRS int16_t ao_ignite_decivolt(int16_t adc) { return scale(adc, AO_IGNITE_DIV_PLUS, AO_IGNITE_DIV_MINUS); } - +#endif diff --git a/src/kernel/ao_report.c b/src/kernel/ao_report.c index 1104cd82..1a0e9e16 100644 --- a/src/kernel/ao_report.c +++ b/src/kernel/ao_report.c @@ -87,19 +87,18 @@ ao_report_digit(uint8_t digit) __reentrant } static void -ao_report_altitude(void) +ao_report_number(int16_t n) { - __pdata int16_t agl = ao_max_height; __xdata uint8_t digits[10]; __pdata uint8_t ndigits, i; - if (agl < 0) - agl = 0; + if (n < 0) + n = 0; ndigits = 0; do { - digits[ndigits++] = agl % 10; - agl /= 10; - } while (agl); + digits[ndigits++] = n % 10; + n /= 10; + } while (n); i = ndigits; do @@ -107,6 +106,27 @@ ao_report_altitude(void) while (i != 0); } +static void +ao_report_altitude(void) +{ + ao_report_number(ao_max_height); +} + +#if HAS_BATTERY_REPORT +static void +ao_report_battery(void) +{ + __xdata struct ao_data packet; + for (;;) { + ao_data_get(&packet); + if (packet.adc.v_batt != 0) + break; + ao_sleep(DATA_TO_XDATA(&ao_sample_data)); + } + ao_report_number(ao_battery_decivolt(packet.adc.v_batt)); +} +#endif + #if HAS_IGNITE_REPORT static uint8_t ao_report_igniter_ready(enum ao_igniter igniter) @@ -163,7 +183,12 @@ ao_report(void) { ao_report_state = ao_flight_state; for(;;) { - ao_report_beep(); +#if HAS_BATTERY_REPORT + if (ao_flight_state == ao_flight_startup) + ao_report_battery(); + else +#endif + ao_report_beep(); if (ao_flight_state == ao_flight_landed) { ao_report_altitude(); #if HAS_FLIGHT diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 9dcfadc0..dd0debd4 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -143,4 +143,8 @@ ao_serial_init(void); #define AO_BOOT_LOADER_BASE ((uint32_t *) 0x00000000) #define HAS_BOOT_LOADER 1 +/* ADC definitions */ + +#define AO_ADC_MAX 32767 + #endif /* _AO_ARCH_H_ */ diff --git a/src/teleballoon-v1.1/ao_pins.h b/src/teleballoon-v1.1/ao_pins.h index 7ba48c96..4c23ca88 100644 --- a/src/teleballoon-v1.1/ao_pins.h +++ b/src/teleballoon-v1.1/ao_pins.h @@ -28,6 +28,7 @@ #define HAS_FLIGHT 1 #define HAS_USB 1 #define HAS_BEEP 1 + #define HAS_BATTERY_REPORT 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 #define HAS_ADC 1 diff --git a/src/teleballoon-v2.0/ao_pins.h b/src/teleballoon-v2.0/ao_pins.h index 22551d9e..f2515521 100644 --- a/src/teleballoon-v2.0/ao_pins.h +++ b/src/teleballoon-v2.0/ao_pins.h @@ -66,6 +66,7 @@ #define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define BEEPER_CHANNEL 4 #define HAS_RADIO 1 #define HAS_TELEMETRY 1 diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index db397c66..a63c76a0 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -71,6 +71,7 @@ #define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define HAS_RADIO 1 #define HAS_TELEMETRY 1 #define HAS_APRS 1 diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h index fe97c684..7f0b1f94 100644 --- a/src/telemega-v1.0/ao_pins.h +++ b/src/telemega-v1.0/ao_pins.h @@ -71,6 +71,7 @@ #define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define HAS_RADIO 1 #define HAS_TELEMETRY 1 #define HAS_APRS 1 diff --git a/src/telemetrum-v1.1/Makefile b/src/telemetrum-v1.1/Makefile index e44be7f9..61e9273b 100644 --- a/src/telemetrum-v1.1/Makefile +++ b/src/telemetrum-v1.1/Makefile @@ -12,6 +12,7 @@ TM_SRC = \ ao_companion.c \ ao_gps_skytraq.c \ ao_gps_show.c \ + ao_convert_volt.c \ ao_m25.c include ../product/Makefile.telemetrum diff --git a/src/telemetrum-v1.2/Makefile b/src/telemetrum-v1.2/Makefile index f2285fbe..38ba6d49 100644 --- a/src/telemetrum-v1.2/Makefile +++ b/src/telemetrum-v1.2/Makefile @@ -12,6 +12,7 @@ TM_SRC = \ ao_companion.c \ ao_gps_skytraq.c \ ao_gps_show.c \ + ao_convert_volt.c \ ao_m25.c include ../product/Makefile.telemetrum diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index 1b5cedc7..2ccac628 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -66,6 +66,7 @@ #define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define BEEPER_CHANNEL 4 #define HAS_RADIO 1 #define HAS_TELEMETRY 1 diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index 606b4f3b..34f35cd9 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -59,6 +59,7 @@ CC1111_SRC = \ ao_spi.c \ ao_usb.c \ ao_convert_pa.c \ + ao_convert_volt.c \ ao_beep.c \ ao_timer.c \ ao_exti.c \ diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index c4681ee2..dc18aff7 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -24,6 +24,7 @@ #define HAS_USB 1 #define USB_FORCE_FLIGHT_IDLE 1 #define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 #define HAS_GPS 0 #define HAS_SERIAL_1 0 #define HAS_EEPROM 1 @@ -158,4 +159,21 @@ struct ao_adc { ao_data_ring[ao_data_head].ms5607_raw.temp = ao_ms5607_current.temp; \ } while (0) +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 100 /* 100k */ +#define AO_BATTERY_DIV_MINUS 27 /* 27k */ + +/* + * Voltage divider on ADC igniter samplers + */ +#define AO_IGNITE_DIV_PLUS 100 /* 100k */ +#define AO_IGNITE_DIV_MINUS 27 /* 27k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 + #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 3b5c4d88671e6c511fbfb1ce6b046f558dd6c2bf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 12 Apr 2014 17:46:34 -0700 Subject: altos: Switch beeping to farnsworth spacing Use 17wpm/12wpm farnsworth spacing for the state reports. Leave the numeric reports running slowly as those require counting. Signed-off-by: Keith Packard --- src/kernel/ao_report.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'src/kernel/ao_report.c') diff --git a/src/kernel/ao_report.c b/src/kernel/ao_report.c index 1a0e9e16..f2263154 100644 --- a/src/kernel/ao_report.c +++ b/src/kernel/ao_report.c @@ -52,6 +52,60 @@ static const uint8_t flight_reports[] = { static __pdata enum ao_flight_state ao_report_state; +/* + * Farnsworth spacing + * + * From: http://www.arrl.org/files/file/Technology/x9004008.pdf + * + * c: character rate in wpm + * s: overall rate in wpm + * u: unit rate (dit speed) + * + * dit: u + * dah: 3u + * intra-character-time: u + * + * u = 1.2/c + * + * Because our clock runs at 10ms, we'll round up to 70ms for u, which + * is about 17wpm + * + * Farnsworth adds space between characters and + * words: + * 60 c - 37.2 s + * Ta = ------------- + * sc + * + * 3 Ta + * Tc = ---- + * 19 + * + * 7 Ta + * Tw = ---- + * 19 + * + * Ta = total delay to add to the characters (31 units) + * of a standard 50-unit "word", in seconds + * + * Tc = period between characters, in seconds + * + * Tw = period between words, in seconds + * + * We'll use Farnsworth spacing with c=18 and s=12: + * + * u = 1.2/18 = 0.0667 + * + * Ta = (60 * 17 - 37.2 * 12) / (17 * 12) = 2.812 + * + * Tc = 3 * Ta / 19 = .444 + * + * Tw = 1.036 + * + * Note that the values below are all reduced by 10ms; that's because + * the timer always adds a tick to make sure the task actually sleeps + * at least as long as the argument. + */ + static void ao_report_beep(void) __reentrant { @@ -62,13 +116,13 @@ ao_report_beep(void) __reentrant return; while (l--) { if (r & 8) - mid(AO_MS_TO_TICKS(600)); - else mid(AO_MS_TO_TICKS(200)); - pause(AO_MS_TO_TICKS(200)); + else + mid(AO_MS_TO_TICKS(60)); + pause(AO_MS_TO_TICKS(60)); r >>= 1; } - pause(AO_MS_TO_TICKS(400)); + pause(AO_MS_TO_TICKS(360)); } static void -- cgit v1.2.3