$(TELE_COMMON_SRC) \
$(TI_TASK_SRC)
+TT_TASK_SRC = \
+ ao_teleterra.c
+#
+# All sources for TeleTerra
+#
+TT_SRC = \
+ $(ALTOS_SRC) \
+ $(ALTOS_DRIVER_SRC) \
+ $(TELE_RECEIVER_SRC) \
+ $(TELE_DRIVER_SRC) \
+ $(TELE_COMMON_SRC) \
+ $(TT_TASK_SRC)
+
+
SRC = \
$(ALTOS_SRC) \
$(ALTOS_DRIVER_SRC) \
TM_REL=$(TM_SRC:.c=.rel)
TI_REL=$(TI_SRC:.c=.rel)
+TT_REL=$(TT_SRC:.c=.rel)
ADB=$(SRC:.c=.adb)
ASM=$(SRC:.c=.asm)
RST=$(SRC:.c=.rst)
SYM=$(SRC:.c=.sym)
-PROGS=telemetrum.ihx tidongle.ihx
+PROGS=telemetrum.ihx tidongle.ihx teleterra.ihx
PCDB=$(PROGS:.ihx=.cdb)
PLNK=$(PROGS:.ihx=.lnk)
PMAP=$(PROGS:.ihx=.map)
tidongle.ihx: telemetrum.ihx
+teleterra.ihx: $(TT_REL) Makefile
+ $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TT_REL)
+ sh check-stack ao.h teleterra.mem
+
+teleterra.ihx: tidongle.ihx
+
altitude.h: make-altitude
nickle make-altitude > altitude.h
void
ao_dbg_reset(void);
+void
+ao_dbg_init(void);
+
/*
* ao_serial.c
*/
* ao_telemetry.c
*/
-#define AO_TELEMETRY_SENSOR 1
-#define AO_TELEMETRY_GPS 2
-
struct ao_telemetry {
- uint8_t addr;
- uint8_t type;
- uint8_t flight_state;
- union {
- struct ao_adc adc;
- struct ao_gps_data gps;
- } u;
+ uint8_t addr;
+ uint8_t flight_state;
+ struct ao_adc adc;
+ struct ao_gps_data gps;
};
void
}
__code struct ao_cmds ao_adc_cmds[] = {
- { 'a', ao_adc_dump, "a Display current ADC values\n" },
+ { 'a', ao_adc_dump, "a Display current ADC values" },
{ 0, ao_adc_dump, NULL },
};
{
__xdata uint8_t cmds;
__xdata uint8_t cmd;
+ __code struct ao_cmds * __xdata cs;
puts(help_txt);
- for (cmds = 0; cmds < ao_ncmds; cmds++)
- for (cmd = 0; ao_cmds[cmds][cmd].cmd; cmd++)
- puts(ao_cmds[cmds][cmd].help);
+ for (cmds = 0; cmds < ao_ncmds; cmds++) {
+ cs = ao_cmds[cmds];
+ for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
+ puts(cs[cmd].help);
+ }
}
static void
{
__xdata uint8_t c;
__xdata uint8_t cmd, cmds;
+ __code struct ao_cmds * __xdata cs;
+ void (*__xdata func)(void);
(void) parameters;
lex_echo = 1;
ao_cmd_lex();
if (c == '\r' || c == '\n')
continue;
- cmd = 0;
+ func = (void (*)(void)) NULL;
for (cmds = 0; cmds < ao_ncmds; cmds++) {
- for (cmd = 0; ao_cmds[cmds][cmd].cmd != '\0'; cmd++)
- if (ao_cmds[cmds][cmd].cmd == c)
+ cs = ao_cmds[cmds];
+ for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
+ if (cs[cmd].cmd == c) {
+ func = cs[cmd].func;
break;
- if (ao_cmds[cmds][cmd].cmd)
+ }
+ if (func)
break;
}
- if (ao_cmds[cmds][cmd].cmd)
- (*ao_cmds[cmds][cmd].func);
+ if (func)
+ (*func)();
else
ao_cmd_status = ao_cmd_syntax_error;
report();
__code struct ao_cmds ao_base_cmds[] = {
{ '?', help, "? Print this message" },
- { 'T', ao_task_info, "T Show task states\n" },
- { 'E', echo, "E <0 off, 1 on> Set command echo mode\n" },
- { 'd', dump, "d <start> <end> Dump memory\n" },
+ { 'T', ao_task_info, "T Show task states" },
+ { 'E', echo, "E <0 off, 1 on> Set command echo mode" },
+ { 'd', dump, "d <start> <end> Dump memory" },
{ 0, help, NULL },
};
}
__code struct ao_cmds ao_dbg_cmds[7] = {
- { 'D', debug_enable, "D Enable debug mode\n" },
- { 'G', debug_get, "G <count> Get data from debug port\n" },
- { 'I', debug_input, "I <count> <addr> Input <count> bytes to target at <addr>\n" },
- { 'O', debug_output, "O <count> <addr> Output <count> bytes to target at <addr>\n" },
- { 'P', debug_put, "P <byte> ... Put data to debug port\n" },
- { 'R', debug_reset, "R Reset target\n" },
+ { 'D', debug_enable, "D Enable debug mode" },
+ { 'G', debug_get, "G <count> Get data from debug port" },
+ { 'I', debug_input, "I <count> <addr> Input <count> bytes to target at <addr>" },
+ { 'O', debug_output, "O <count> <addr> Output <count> bytes to target at <addr>" },
+ { 'P', debug_put, "P <byte> ... Put data to debug port" },
+ { 'R', debug_reset, "R Reset target" },
{ 0, debug_reset, 0 },
};
}
__code struct ao_cmds ao_ee_cmds[] = {
- { 'e', ee_dump, "e <block> Dump a block of EEPROM data\n" },
- { 'w', ee_store, "w <block> <start> <len> <data> ... Write data to EEPROM\n" },
+ { 'e', ee_dump, "e <block> Dump a block of EEPROM data" },
+ { 'w', ee_store, "w <block> <start> <len> <data> ... Write data to EEPROM" },
{ 0, ee_store, NULL },
};
ao_gps_report(void)
{
static __xdata struct ao_log_record gps_log;
- static __xdata struct ao_telemetry gps_telemetry;
static __xdata struct ao_gps_data gps_data;
for (;;) {
gps_log.u.gps_altitude.altitude = gps_data.altitude;
gps_log.u.gps_altitude.unused = 0xffff;
ao_log_data(&gps_log);
- gps_telemetry.type = AO_TELEMETRY_GPS;
- memcpy(&gps_telemetry.u.gps, &gps_data, sizeof (struct ao_gps_data));
- ao_telemetry_send(&gps_telemetry);
}
}
}
__code struct ao_cmds ao_gps_cmds[] = {
- { 'g', gps_dump, "g Display current GPS values\n" },
+ { 'g', gps_dump, "g Display current GPS values" },
{ 0, gps_dump, NULL },
};
log.u.sensor.accel = ao_adc_ring[ao_log_adc_pos].accel;
log.u.sensor.pres = ao_adc_ring[ao_log_adc_pos].pres;
ao_log_data(&log);
- if (ao_log_adc_pos == 0) {
+ if ((ao_log_adc_pos & 0x1f) == 0) {
log.type = AO_LOG_TEMP_VOLT;
log.tick = ao_adc_ring[ao_log_adc_pos].tick;
log.u.temp_volt.temp = ao_adc_ring[ao_log_adc_pos].temp;
}
__code struct ao_cmds ao_log_cmds[] = {
- { 'l', dump_log, "l Dump last flight log\n" },
+ { 'l', dump_log, "l Dump last flight log" },
{ 0, dump_log, NULL },
};
ao_state_names[state]);
if (!(recv.status & PKT_APPEND_STATUS_1_CRC_OK))
printf("CRC INVALID ");
- switch (recv.telemetry.type) {
- case AO_TELEMETRY_SENSOR:
- printf("%5u a: %d p: %d t: %d v: %d d: %d m: %d\n",
- recv.telemetry.u.adc.tick,
- recv.telemetry.u.adc.accel,
- recv.telemetry.u.adc.pres,
- recv.telemetry.u.adc.temp,
- recv.telemetry.u.adc.v_batt,
- recv.telemetry.u.adc.sense_d,
- recv.telemetry.u.adc.sense_m);
- break;
- case AO_TELEMETRY_GPS:
- ao_gps_print(&recv.telemetry.u.gps);
- break;
- }
+ printf("%5u a: %d p: %d t: %d v: %d d: %d m: %d\n",
+ recv.telemetry.adc.tick,
+ recv.telemetry.adc.accel,
+ recv.telemetry.adc.pres,
+ recv.telemetry.adc.temp,
+ recv.telemetry.adc.v_batt,
+ recv.telemetry.adc.sense_d,
+ recv.telemetry.adc.sense_m);
+ ao_gps_print(&recv.telemetry.gps);
ao_usb_flush();
}
}
}
__code struct ao_cmds ao_serial_cmds[] = {
- { 'S', send_serial, "S<data> Send data to serial line\n" },
+ { 'S', send_serial, "S<data> Send data to serial line" },
{ 0, send_serial, NULL },
};
ao_gps_init();
ao_telemetry_init();
ao_radio_init();
+ ao_dbg_init();
ao_start_scheduler();
}
void
ao_telemetry(void)
{
- static __xdata struct ao_radio_recv recv;
+ static __xdata struct ao_telemetry telemetry;
static uint8_t state;
while (ao_flight_state == ao_flight_startup || ao_flight_state == ao_flight_idle)
ao_sleep(DATA_TO_XDATA(&ao_flight_state));
- recv.telemetry.type = AO_TELEMETRY_SENSOR;
for (;;) {
- ao_adc_get(&recv.telemetry.u.adc);
- ao_telemetry_send(&recv.telemetry);
+ ao_adc_get(&telemetry.adc);
+ ao_mutex_get(&ao_gps_mutex);
+ memcpy(&telemetry.gps, &ao_gps_data, sizeof (struct ao_gps_data));
+ ao_mutex_put(&ao_gps_mutex);
+ ao_telemetry_send(&telemetry);
ao_delay(AO_MS_TO_TICKS(1000));
}
}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ */
+
+#define AO_NO_ADC_ISR 1
+#include "ao.h"
+
+void
+main(void)
+{
+ CLKCON = 0;
+ while (!(SLEEP & SLEEP_XOSC_STB))
+ ;
+
+ /* Turn on the red LED until the system is stable */
+ ao_led_init();
+ ao_led_on(AO_LED_RED);
+ ao_timer_init();
+ ao_beep_init();
+ ao_cmd_init();
+ ao_usb_init();
+ ao_serial_init();
+ ao_gps_init();
+ ao_monitor_init();
+ ao_radio_init();
+ ao_dbg_init();
+ ao_start_scheduler();
+}
+
+/* Stub for systems which have no ADC */
+void
+ao_adc_poll(void)
+{
+}
+
+/* Stub to not log GPS data */
+void
+ao_log_data(struct ao_log_record *log)
+{
+ (void) log;
+}
+
ao_usb_init();
ao_monitor_init();
ao_radio_init();
+ ao_dbg_init();
+ /* Bring up the USB link */
+ ao_led_on(AO_LED_GREEN);
ao_start_scheduler();
}
MEM_STACK=`awk '/Stack starts at/ {print $4}' $MEM | nickle`
if [ "$HEADER_STACK" -lt "$MEM_STACK" ]; then
- echo "Set AO_STACK_START to at least $MEM_STACK"
+ MIN=0x`nickle -e "$MEM_STACK # 16"`
+ echo "Set AO_STACK_START to at least $MIN"
exit 1
else
exit 0