Initial Commit - Copy from Altus Metrum AltOS
This commit is contained in:
9
ao-tools/Makefile.am
Normal file
9
ao-tools/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \
|
||||
ao-load ao-telem ao-send-telem ao-sky-flash \
|
||||
ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex \
|
||||
ao-flash ao-usbload ao-test-igniter ao-test-baro \
|
||||
ao-test-flash ao-cal-accel ao-test-gps ao-usbtrng \
|
||||
ao-cal-freq ao-makebin ao-test-pressure
|
||||
if LIBSTLINK
|
||||
SUBDIRS += ao-stmload
|
||||
endif
|
12
ao-tools/ao-bitbang/Makefile.am
Normal file
12
ao-tools/ao-bitbang/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-bitbang
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_BITBANG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_bitbang_DEPENDENCIES = $(AO_BITBANG_LIBS)
|
||||
|
||||
ao_bitbang_LDADD=$(AO_BITBANG_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_bitbang_SOURCES = ao-bitbang.c
|
||||
|
||||
man_MANS=ao-bitbang.1
|
127
ao-tools/ao-bitbang/ao-bitbang.1
Normal file
127
ao-tools/ao-bitbang/ao-bitbang.1
Normal file
@@ -0,0 +1,127 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-BITBANG 1 "ao-bitbang" ""
|
||||
.SH NAME
|
||||
ao-bitbang \- Low-level cc1111 interface diagnostic tool
|
||||
.SH SYNOPSIS
|
||||
.B "ao-bitbang"
|
||||
.SH DESCRIPTION
|
||||
.I ao-bitbang
|
||||
connects through a CP2103 usb-to-serial converter and uses the GPIO
|
||||
pins to communicate with the debug port on a cc1111 device. It
|
||||
provides raw access to the debug pins to help debug the lowest level
|
||||
communication path.
|
||||
.SH USAGE
|
||||
.I ao-bitbang
|
||||
reads a sequence of bit manipulations from stdin, sends them to the
|
||||
device and reports status on stdout.
|
||||
.P
|
||||
Each line on stdin should contain a single letter command for each of
|
||||
the three debug lines on the cc1111 -- clock, data and reset. Each bit
|
||||
can be in one of three states -- on (C, D or R), off (.) or tri-state
|
||||
(-) for input. Empty lines, or lines starting with '#' are
|
||||
ignored. Anything beyond the last bit in a line is also ignored. The
|
||||
bits must be listed in the correct order, and the 'on' values must
|
||||
match the desired bit.
|
||||
.SH EXAMPLE
|
||||
.IP "Reset the target device"
|
||||
.nf
|
||||
# reset
|
||||
C D R
|
||||
C D R
|
||||
C D R
|
||||
C D R
|
||||
.fi
|
||||
.IP "Get Chip ID"
|
||||
.nf
|
||||
#
|
||||
# Debug mode - drive RESET_N low for two clock cycles
|
||||
#
|
||||
C D R
|
||||
. D .
|
||||
C D .
|
||||
. D .
|
||||
C D .
|
||||
. D R
|
||||
|
||||
#
|
||||
# GET_CHIP_ID
|
||||
|
||||
C . R 0
|
||||
. . R
|
||||
C D R 1
|
||||
. D R
|
||||
C D R 1
|
||||
. D R
|
||||
C . R 0
|
||||
. . R
|
||||
|
||||
C D R 1
|
||||
. D R
|
||||
C . R 0
|
||||
. . R
|
||||
C . R 0
|
||||
. . R
|
||||
C . R 0
|
||||
. . R
|
||||
|
||||
#
|
||||
# start reading again
|
||||
#
|
||||
|
||||
C D R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
C - R
|
||||
. - R
|
||||
|
||||
C D R
|
||||
.fi
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
33
ao-tools/ao-bitbang/ao-bitbang.c
Normal file
33
ao-tools/ao-bitbang/ao-bitbang.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "ccdbg.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct ccdbg *dbg;
|
||||
|
||||
dbg = ccdbg_open("BITBANG");
|
||||
if (!dbg)
|
||||
exit (1);
|
||||
|
||||
ccdbg_add_debug(CC_DEBUG_BITBANG);
|
||||
|
||||
ccdbg_manual(dbg, stdin);
|
||||
}
|
7
ao-tools/ao-bm70/Makefile.am
Normal file
7
ao-tools/ao-bm70/Makefile.am
Normal file
@@ -0,0 +1,7 @@
|
||||
bin_PROGRAMS=ao-bm70
|
||||
|
||||
AM_CFLAGS=-O0 -g
|
||||
|
||||
ao_bm70_SOURCES = ao-bm70.c
|
||||
|
||||
man_MANS=ao-bm70.1
|
9
ao-tools/ao-boot-stm32/Makefile.am
Normal file
9
ao-tools/ao-boot-stm32/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
bin_PROGRAMS=ao-chaosread
|
||||
|
||||
AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
|
||||
ao_chaosread_LDADD=$(LIBUSB_LIBS)
|
||||
|
||||
ao_chaosread_SOURCES = ao-chaosread.c
|
||||
|
||||
man_MANS = ao-chaosread.1
|
1
ao-tools/ao-cal-accel/.gitignore
vendored
Normal file
1
ao-tools/ao-cal-accel/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-cal-accel
|
11
ao-tools/ao-cal-accel/Makefile.am
Normal file
11
ao-tools/ao-cal-accel/Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
bin_PROGRAMS=ao-cal-accel
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
|
||||
ao_cal_accel_DEPENDENCIES = $(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_cal_accel_LDADD=$(top_builddir)/ao-tools/lib/libao-tools.a $(LIBUSB_LIBS)
|
||||
|
||||
ao_cal_accel_SOURCES=ao-cal-accel.c
|
||||
|
||||
man_MANS = ao-cal-accel.1
|
58
ao-tools/ao-cal-accel/ao-cal-accel.1
Normal file
58
ao-tools/ao-cal-accel/ao-cal-accel.1
Normal file
@@ -0,0 +1,58 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LOAD 1 "ao-cal-accel" ""
|
||||
.SH NAME
|
||||
ao-cal-accel \- Calibrate AltOS flight computer accelerometers
|
||||
.SH SYNOPSIS
|
||||
.B "ao-cal-accel"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
.SH DESCRIPTION
|
||||
.I ao-cal-accel
|
||||
drives the built-in accelerometer calibration and validates the results.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
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
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMega:2
|
||||
.br
|
||||
TeleMega
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.SH USAGE
|
||||
.I ao-cal-accel
|
||||
opens the target device, executes the accelerometer calibration
|
||||
command, verifies that it executed correctly, then shows the resulting
|
||||
calibration values and saves them to configuration memory.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
233
ao-tools/ao-cal-accel/ao-cal-accel.c
Normal file
233
ao-tools/ao-cal-accel/ao-cal-accel.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright © 2014 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <termios.h>
|
||||
#include "ao-elf.h"
|
||||
#include "ccdbg.h"
|
||||
#include "cc-usb.h"
|
||||
#include "cc.h"
|
||||
#include "ao-verbose.h"
|
||||
|
||||
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' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--verbose=<verbose>] [--device=<device>] [-tty=<tty>]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
done(struct cc_usb *cc, int code)
|
||||
{
|
||||
cc_usb_close(cc);
|
||||
exit (code);
|
||||
}
|
||||
|
||||
static char **
|
||||
tok(char *line) {
|
||||
char **strs = malloc (sizeof (char *)), *str;
|
||||
int n = 0;
|
||||
|
||||
while ((str = strtok(line, " \t"))) {
|
||||
line = NULL;
|
||||
strs = realloc(strs, (n + 2) * sizeof (char *));
|
||||
strs[n] = strdup(str);
|
||||
n++;
|
||||
}
|
||||
strs[n] = '\0';
|
||||
return strs;
|
||||
}
|
||||
|
||||
struct flash {
|
||||
struct flash *next;
|
||||
char line[512];
|
||||
char **strs;
|
||||
};
|
||||
|
||||
static struct flash *
|
||||
flash(struct cc_usb *usb)
|
||||
{
|
||||
struct flash *head = NULL, **tail = &head;
|
||||
cc_usb_printf(usb, "c s\nv\n");
|
||||
for (;;) {
|
||||
char line[512];
|
||||
struct flash *b;
|
||||
|
||||
cc_usb_getline(usb, line, sizeof (line));
|
||||
b = malloc (sizeof (struct flash));
|
||||
strcpy(b->line, line);
|
||||
b->strs = tok(line);
|
||||
b->next = NULL;
|
||||
*tail = b;
|
||||
tail = &b->next;
|
||||
if (strstr(line, "software-version"))
|
||||
break;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
static char **
|
||||
find_flash(struct flash *b, char *word0) {
|
||||
for (;b; b = b->next) {
|
||||
if (strstr(b->line, word0))
|
||||
return b->strs;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
await_key(void)
|
||||
{
|
||||
struct termios termios, termios_save;
|
||||
char buf[512];
|
||||
|
||||
tcgetattr(0, &termios);
|
||||
termios_save = termios;
|
||||
cfmakeraw(&termios);
|
||||
tcsetattr(0, TCSAFLUSH, &termios);
|
||||
read(0, buf, sizeof (buf));
|
||||
tcsetattr(0, TCSAFLUSH, &termios_save);
|
||||
}
|
||||
|
||||
static int
|
||||
do_cal(struct cc_usb *usb) {
|
||||
struct flash *b;
|
||||
char **accel;
|
||||
char line[1024];
|
||||
int l = 0;
|
||||
int running = 0;
|
||||
int worked = 1;
|
||||
|
||||
cc_usb_printf(usb, "E 1\nc a 0\n");
|
||||
|
||||
for (;;) {
|
||||
int c = cc_usb_getchar_timeout(usb, 20*1000);
|
||||
|
||||
if (c == '\n')
|
||||
l = 0;
|
||||
else if (l < sizeof (line) - 1)
|
||||
line[l++] = c;
|
||||
line[l] = '\0';
|
||||
putchar(c); fflush(stdout);
|
||||
if (strstr(line, "press a key...")) {
|
||||
await_key();
|
||||
cc_usb_printf(usb, " ");
|
||||
l = 0;
|
||||
running = 1;
|
||||
}
|
||||
else if (strstr(line, "Invalid"))
|
||||
worked = 0;
|
||||
if (running && strstr(line, ">")) {
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
cc_usb_printf(usb, "E 0\n");
|
||||
|
||||
if (!worked) {
|
||||
printf("Calibration failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = flash(usb);
|
||||
|
||||
accel = find_flash(b, "Accel cal");
|
||||
if (!accel) {
|
||||
printf("no response\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf ("Accel cal +1g: %s -1g: %s\n",
|
||||
accel[3], accel[5]);
|
||||
|
||||
printf ("Saving..."); fflush(stdout);
|
||||
cc_usb_printf (usb, "c w\n");
|
||||
cc_usb_sync(usb);
|
||||
b = flash(usb);
|
||||
printf ("done\n");
|
||||
|
||||
return worked;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *device = NULL;
|
||||
int c;
|
||||
struct cc_usb *cc = NULL;
|
||||
char *tty = NULL;
|
||||
int verbose = 0;
|
||||
int ret = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ao_verbose = verbose;
|
||||
|
||||
if (verbose > 1)
|
||||
ccdbg_add_debug(CC_DEBUG_BITBANG);
|
||||
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "AltosFlash");
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleMega");
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyACM0";
|
||||
|
||||
cc = cc_usb_open(tty);
|
||||
|
||||
if (!cc)
|
||||
exit(1);
|
||||
|
||||
if (!do_cal(cc))
|
||||
ret = 1;
|
||||
done(cc, ret);
|
||||
}
|
1
ao-tools/ao-cal-freq/.gitignore
vendored
Normal file
1
ao-tools/ao-cal-freq/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-cal-freq
|
11
ao-tools/ao-cal-freq/Makefile.am
Normal file
11
ao-tools/ao-cal-freq/Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
bin_PROGRAMS=ao-cal-freq
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
|
||||
ao_cal_freq_DEPENDENCIES = $(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_cal_freq_LDADD=$(top_builddir)/ao-tools/lib/libao-tools.a $(LIBUSB_LIBS) -lm
|
||||
|
||||
ao_cal_freq_SOURCES=ao-cal-freq.c
|
||||
|
||||
man_MANS = ao-cal-freq.1
|
74
ao-tools/ao-cal-freq/ao-cal-freq.1
Normal file
74
ao-tools/ao-cal-freq/ao-cal-freq.1
Normal file
@@ -0,0 +1,74 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LOAD 1 "ao-cal-freq" ""
|
||||
.SH NAME
|
||||
ao-cal-freq \- Calibrate AltOS flight computer frequency
|
||||
.SH SYNOPSIS
|
||||
.B "ao-cal-freq"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\-v] [\--verbose]
|
||||
[\-n] [\--nosave]
|
||||
[\-o \fIcal-value-output-file\fP]
|
||||
[\--output \fIcal-value-output-file\fP]
|
||||
.SH DESCRIPTION
|
||||
.I ao-cal-freq
|
||||
drives the frequency calibration process and saves the result.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
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
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMega:2
|
||||
.br
|
||||
TeleMega
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\-o cal-value-output-file | --output cal-value-output-file
|
||||
Writes the resulting calibration value to the specified file.
|
||||
.TP
|
||||
\-n | --nosave
|
||||
Inhibits saving the calibration value on the device. Necessary for
|
||||
devices which don't have on-board configuration storage.
|
||||
.TP
|
||||
\-v | --verbose
|
||||
Makes
|
||||
.I ao-cal-freq
|
||||
chatty about communication with the target device.
|
||||
.SH USAGE
|
||||
.I ao-cal-freq
|
||||
opens the target device, interactively calibrates the frequency, then
|
||||
shows the resulting calibration values and (optionally) saves them to
|
||||
configuration memory and/or a file.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
296
ao-tools/ao-cal-freq/ao-cal-freq.c
Normal file
296
ao-tools/ao-cal-freq/ao-cal-freq.c
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright © 2014 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <termios.h>
|
||||
#include <math.h>
|
||||
#include "ao-elf.h"
|
||||
#include "ccdbg.h"
|
||||
#include "cc-usb.h"
|
||||
#include "cc.h"
|
||||
#include "ao-verbose.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "verbose", .has_arg = 0, .val = 'v' },
|
||||
{ .name = "output", .has_arg = 1, .val = 'o' },
|
||||
{ .name = "nosave", .has_arg = 0, .val = 'n' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--verbose] [--nosave] [--device=<device>] [-tty=<tty>] [--output=<cal-value-file>]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static char **
|
||||
tok(char *line) {
|
||||
char **strs = malloc (sizeof (char *)), *str;
|
||||
int n = 0;
|
||||
|
||||
while ((str = strtok(line, " \t"))) {
|
||||
line = NULL;
|
||||
strs = realloc(strs, (n + 2) * sizeof (char *));
|
||||
strs[n] = strdup(str);
|
||||
n++;
|
||||
}
|
||||
strs[n] = '\0';
|
||||
return strs;
|
||||
}
|
||||
|
||||
struct flash {
|
||||
struct flash *next;
|
||||
char line[512];
|
||||
char **strs;
|
||||
};
|
||||
|
||||
static struct flash *
|
||||
flash(struct cc_usb *usb)
|
||||
{
|
||||
struct flash *head = NULL, **tail = &head;
|
||||
cc_usb_printf(usb, "c s\nv\n");
|
||||
for (;;) {
|
||||
char line[512];
|
||||
struct flash *b;
|
||||
|
||||
cc_usb_getline(usb, line, sizeof (line));
|
||||
b = malloc (sizeof (struct flash));
|
||||
strcpy(b->line, line);
|
||||
b->strs = tok(line);
|
||||
b->next = NULL;
|
||||
*tail = b;
|
||||
tail = &b->next;
|
||||
if (strstr(line, "software-version"))
|
||||
break;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
static char **
|
||||
find_flash(struct flash *b, char *word0) {
|
||||
for (;b; b = b->next) {
|
||||
if (strstr(b->line, word0))
|
||||
return b->strs;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
do_save(struct cc_usb *usb)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
printf("Saving calibration to device\n");
|
||||
cc_usb_printf(usb, "c w\nv\n");
|
||||
for (;;) {
|
||||
char line[512];
|
||||
|
||||
cc_usb_getline(usb, line, sizeof (line));
|
||||
if (strstr(line, "Nothing to save"))
|
||||
ret = 1;
|
||||
if (strstr(line, "Saved"))
|
||||
ret = 1;
|
||||
if (strstr(line, "software-version"))
|
||||
break;
|
||||
}
|
||||
if (!ret) {
|
||||
printf("Calibration save failed\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
do_output(char *output, int cur_cal)
|
||||
{
|
||||
printf ("Saving calibration value to file \"%s\"\n", output);
|
||||
|
||||
FILE *out = fopen(output, "w");
|
||||
int ret = 1;
|
||||
|
||||
if (!out) {
|
||||
perror(output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fprintf(out, "%d\n", cur_cal) < 0) {
|
||||
perror("fprintf");
|
||||
ret = 0;
|
||||
}
|
||||
if (fflush(out) != 0) {
|
||||
perror("fflush");
|
||||
ret = 0;
|
||||
}
|
||||
if (fclose(out) != 0) {
|
||||
perror("fclose");
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
do_cal(char *tty, int save, char *output)
|
||||
{
|
||||
struct cc_usb *usb = NULL;
|
||||
struct flash *b;
|
||||
char line[1024];
|
||||
double measured_freq;
|
||||
char **cur_freq_words;
|
||||
char **cur_cal_words;
|
||||
char *line_end;
|
||||
int cur_freq;
|
||||
int cur_cal;
|
||||
int new_cal;
|
||||
int ret = 1;
|
||||
int changed = 0;
|
||||
|
||||
for(;;) {
|
||||
usb = cc_usb_open(tty);
|
||||
|
||||
if (!usb) {
|
||||
fprintf(stderr, "failed to open device\n");
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
cc_usb_printf(usb, "E 0\n");
|
||||
|
||||
b = flash(usb);
|
||||
|
||||
cur_cal_words = find_flash(b, "Radio cal:");
|
||||
cur_freq_words = find_flash(b, "Frequency:");
|
||||
|
||||
if (!cur_cal_words || !cur_freq_words) {
|
||||
fprintf(stderr, "no response\n");
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
cur_cal = atoi(cur_cal_words[2]);
|
||||
cur_freq = atoi(cur_freq_words[1]);
|
||||
|
||||
printf ("Current radio calibration %d\n", cur_cal);
|
||||
printf ("Current radio frequency: %7.3f\n", cur_freq / 1000.0);
|
||||
|
||||
cc_usb_sync(usb);
|
||||
cc_usb_printf(usb, "C 1\n");
|
||||
cc_usb_sync(usb);
|
||||
|
||||
printf("Generating RF carrier. Please enter measured frequency [enter for done]: ");
|
||||
fflush(stdout);
|
||||
fgets(line, sizeof (line) - 1, stdin);
|
||||
cc_usb_printf(usb, "C 0\n");
|
||||
cc_usb_sync(usb);
|
||||
|
||||
measured_freq = strtod(line, &line_end);
|
||||
if (line_end == line)
|
||||
break;
|
||||
|
||||
new_cal = floor ((((double) cur_freq / 1000.0) / measured_freq) * cur_cal + 0.5);
|
||||
|
||||
if (new_cal == cur_cal) {
|
||||
printf("Calibration value %d unchanged\n", cur_cal);
|
||||
} else {
|
||||
printf ("Setting cal value %d\n", new_cal);
|
||||
|
||||
cc_usb_printf (usb, "c f %d\n", new_cal);
|
||||
changed = 1;
|
||||
cc_usb_sync(usb);
|
||||
}
|
||||
cc_usb_close(usb);
|
||||
}
|
||||
if (usb) {
|
||||
if (ret && save) {
|
||||
if (changed) {
|
||||
if (!do_save(usb))
|
||||
ret = 0;
|
||||
} else {
|
||||
printf("Calibration unchanged, not saving\n");
|
||||
}
|
||||
}
|
||||
if (ret && output) {
|
||||
if (!do_output(output, cur_cal))
|
||||
ret = 0;
|
||||
}
|
||||
cc_usb_close(usb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *device = NULL;
|
||||
int c;
|
||||
char *tty = NULL;
|
||||
int verbose = 0;
|
||||
int save = 1;
|
||||
int ret = 0;
|
||||
char *output = NULL;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "vnT:D:o:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'n':
|
||||
save = 0;
|
||||
break;
|
||||
case 'o':
|
||||
output = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ao_verbose = verbose;
|
||||
if (verbose)
|
||||
ccdbg_add_debug(CC_DEBUG_BITBANG);
|
||||
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "AltosFlash");
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleMega");
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyACM0";
|
||||
|
||||
if (!do_cal(tty, save, output))
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
1
ao-tools/ao-dbg/.gitignore
vendored
Normal file
1
ao-tools/ao-dbg/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
s51
|
12
ao-tools/ao-dbg/Makefile.am
Normal file
12
ao-tools/ao-dbg/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-dbg
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_DBG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
man_MANS = ao-dbg.1
|
||||
|
||||
ao_dbg_DEPENDENCIES = $(AO_DBG_LIBS)
|
||||
|
||||
ao_dbg_LDADD=$(AO_DBG_LIBS) $(LIBUSB_LIBS) $(LIBREADLINE)
|
||||
|
||||
ao_dbg_SOURCES = ao-dbg-parse.c ao-dbg-command.c ao-dbg-main.c
|
652
ao-tools/ao-dbg/ao-dbg-command.c
Normal file
652
ao-tools/ao-dbg/ao-dbg-command.c
Normal file
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* Copyright © 2008 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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-dbg.h"
|
||||
|
||||
static uint16_t start_address;
|
||||
|
||||
static enum command_result
|
||||
parse_int(char *value, int *result)
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
*result = strtol(value, &endptr, 0);
|
||||
if (endptr == value)
|
||||
return command_syntax;
|
||||
return command_success;
|
||||
}
|
||||
|
||||
static enum command_result
|
||||
parse_uint16(char *value, uint16_t *uint16)
|
||||
{
|
||||
int v;
|
||||
enum command_result result;
|
||||
|
||||
result = parse_int(value, &v);
|
||||
if (result != command_success)
|
||||
return command_error;
|
||||
if (v < 0 || v > 0xffff)
|
||||
return command_error;
|
||||
*uint16 = v;
|
||||
return command_success;
|
||||
}
|
||||
|
||||
static enum command_result
|
||||
parse_uint8(char *value, uint8_t *uint8)
|
||||
{
|
||||
int v;
|
||||
enum command_result result;
|
||||
|
||||
result = parse_int(value, &v);
|
||||
if (result != command_success)
|
||||
return command_error;
|
||||
if (v < 0 || v > 0xff)
|
||||
return command_error;
|
||||
*uint8 = v;
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_quit (int argc, char **argv)
|
||||
{
|
||||
ccdbg_reset(s51_dbg);
|
||||
exit(0);
|
||||
return command_error;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_bytes(uint8_t *memory, int length, uint16_t start, char *format)
|
||||
{
|
||||
int group, i;
|
||||
|
||||
for (group = 0; group < length; group += 8) {
|
||||
s51_printf(format, start + group);
|
||||
for (i = group; i < length && i < group + 8; i++)
|
||||
s51_printf("%02x ", memory[i]);
|
||||
for (; i < group + 8; i++)
|
||||
s51_printf(" ");
|
||||
for (i = group; i < length && i < group + 8; i++) {
|
||||
if (isascii(memory[i]) && isprint(memory[i]))
|
||||
s51_printf("%c", memory[i]);
|
||||
else
|
||||
s51_printf(".");
|
||||
}
|
||||
s51_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_di (int argc, char **argv)
|
||||
{
|
||||
uint16_t start, end;
|
||||
uint8_t memory[65536];
|
||||
uint8_t status;
|
||||
int length;
|
||||
|
||||
if (argc != 3)
|
||||
return command_error;
|
||||
if (parse_uint16(argv[1], &start) != command_success)
|
||||
return command_error;
|
||||
if (parse_uint16(argv[2], &end) != command_success)
|
||||
return command_error;
|
||||
length = (int) end - (int) start + 1;
|
||||
status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
|
||||
(void) status;
|
||||
dump_bytes(memory, length, start, "0x%02x ");
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_ds (int argc, char **argv)
|
||||
{
|
||||
uint8_t start, end;
|
||||
uint8_t memory[0x100];
|
||||
uint8_t status;
|
||||
int length;
|
||||
|
||||
if (argc != 3)
|
||||
return command_error;
|
||||
if (parse_uint8(argv[1], &start) != command_success)
|
||||
return command_error;
|
||||
if (parse_uint8(argv[2], &end) != command_success)
|
||||
return command_error;
|
||||
length = (int) end - (int) start + 1;
|
||||
status = ccdbg_read_sfr(s51_dbg, start, memory, length);
|
||||
(void) status;
|
||||
dump_bytes(memory, length, start, "0x%02x ");
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_dx (int argc, char **argv)
|
||||
{
|
||||
uint16_t start, end;
|
||||
uint8_t memory[65536];
|
||||
uint8_t status;
|
||||
int length;
|
||||
|
||||
if (argc != 3)
|
||||
return command_error;
|
||||
if (parse_uint16(argv[1], &start) != command_success)
|
||||
return command_error;
|
||||
if (parse_uint16(argv[2], &end) != command_success)
|
||||
return command_error;
|
||||
length = (int) end - (int) start + 1;
|
||||
status = ccdbg_read_memory(s51_dbg, start, memory, length);
|
||||
(void) status;
|
||||
dump_bytes(memory, length, start, "0x%04x ");
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_set (int argc, char **argv)
|
||||
{
|
||||
uint16_t address;
|
||||
uint8_t *data;
|
||||
int len = argc - 3;
|
||||
int i;
|
||||
enum command_result ret = command_success;
|
||||
|
||||
if (len < 0)
|
||||
return command_error;
|
||||
if (parse_uint16(argv[2], &address) != command_success)
|
||||
return command_error;
|
||||
if (len == 0)
|
||||
return command_success;
|
||||
data = malloc(len);
|
||||
if (!data)
|
||||
return command_error;
|
||||
for (i = 0; i < len; i++)
|
||||
if (parse_uint8(argv[i+3], &data[i]) != command_success)
|
||||
return command_error;
|
||||
|
||||
if (strcmp(argv[1], "xram") == 0) {
|
||||
ccdbg_write_memory(s51_dbg, address, data, len);
|
||||
} else if (strcmp(argv[1], "iram") == 0) {
|
||||
ccdbg_write_memory(s51_dbg, address + 0xff00, data, len);
|
||||
} else if (strcmp(argv[1], "sfr") == 0) {
|
||||
ccdbg_write_sfr(s51_dbg, (uint8_t) address, data, len);
|
||||
} else
|
||||
ret = command_error;
|
||||
free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_dump (int argc, char **argv)
|
||||
{
|
||||
if (argv[1]) {
|
||||
if (strcmp(argv[1], "rom") == 0 ||
|
||||
strcmp(argv[1], "xram") == 0)
|
||||
return command_dx(argc-1, argv+1);
|
||||
if (strcmp(argv[1], "iram") == 0)
|
||||
return command_di(argc-1, argv+1);
|
||||
if (strcmp(argv[1], "sfr") == 0)
|
||||
return command_ds(argc-1, argv+1);
|
||||
}
|
||||
return command_error;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_file (int argc, char **argv)
|
||||
{
|
||||
struct ao_hex_file *hex;
|
||||
struct ao_hex_image *image;
|
||||
FILE *file;
|
||||
|
||||
if (argc != 2)
|
||||
return command_error;
|
||||
file = fopen (argv[1], "r");
|
||||
if (!file)
|
||||
return command_error;
|
||||
hex = ao_hex_file_read(file, argv[1]);
|
||||
fclose(file);
|
||||
if (!hex)
|
||||
return command_error;
|
||||
if (hex->nrecord == 0) {
|
||||
ao_hex_file_free(hex);
|
||||
return command_error;
|
||||
}
|
||||
image = ao_hex_image_create(hex);
|
||||
ao_hex_file_free(hex);
|
||||
start_address = image->address;
|
||||
ccdbg_set_rom(s51_dbg, image);
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_pc (int argc, char **argv)
|
||||
{
|
||||
uint16_t pc;
|
||||
if (argv[1]) {
|
||||
enum command_result result;
|
||||
result = parse_uint16(argv[1], &pc);
|
||||
if (result != command_success)
|
||||
return result;
|
||||
ccdbg_set_pc(s51_dbg, pc);
|
||||
} else {
|
||||
pc = ccdbg_get_pc(s51_dbg);
|
||||
s51_printf(" 0x%04x 00\n", pc);
|
||||
}
|
||||
return command_success;
|
||||
}
|
||||
|
||||
struct cc_break {
|
||||
int enabled;
|
||||
int temporary;
|
||||
uint16_t address;
|
||||
};
|
||||
|
||||
#define CC_NUM_BREAKPOINTS 4
|
||||
|
||||
static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
|
||||
|
||||
static void
|
||||
disable_breakpoint(int b)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
|
||||
if (status != 0x00 && status != 0xff)
|
||||
s51_printf("disable_breakpoint status 0x%02x\n", status);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_breakpoint(int b)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
|
||||
if (status != 0xff)
|
||||
s51_printf("enable_breakpoint status 0x%02x\n", status);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_breakpoints(void)
|
||||
{
|
||||
int b;
|
||||
for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
|
||||
if (breakpoints[b].enabled)
|
||||
enable_breakpoint(b);
|
||||
}
|
||||
|
||||
static enum command_result
|
||||
set_breakpoint(uint16_t address, int temporary)
|
||||
{
|
||||
int b;
|
||||
for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
|
||||
if (breakpoints[b].enabled == 0)
|
||||
break;
|
||||
if (breakpoints[b].address == address)
|
||||
break;
|
||||
}
|
||||
if (b == CC_NUM_BREAKPOINTS) {
|
||||
s51_printf("Error: too many breakpoints requested\n");
|
||||
return command_success;
|
||||
}
|
||||
if (breakpoints[b].enabled == 0) {
|
||||
breakpoints[b].address = address;
|
||||
enable_breakpoint(b);
|
||||
}
|
||||
++breakpoints[b].enabled;
|
||||
s51_printf("Breakpoint %d at 0x%04x\n", b, address);
|
||||
breakpoints[b].temporary += temporary;
|
||||
return command_success;
|
||||
}
|
||||
|
||||
static enum command_result
|
||||
clear_breakpoint(uint16_t address, int temporary)
|
||||
{
|
||||
int b;
|
||||
|
||||
for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
|
||||
if (breakpoints[b].enabled != 0 &&
|
||||
((breakpoints[b].temporary != 0) == (temporary != 0)) &&
|
||||
breakpoints[b].address == address)
|
||||
break;
|
||||
}
|
||||
if (b == CC_NUM_BREAKPOINTS) {
|
||||
s51_printf("Error: no matching breakpoint found\n");
|
||||
return command_success;
|
||||
}
|
||||
--breakpoints[b].enabled;
|
||||
breakpoints[b].temporary -= temporary;
|
||||
if (breakpoints[b].enabled == 0) {
|
||||
disable_breakpoint(b);
|
||||
breakpoints[b].address = -1;
|
||||
}
|
||||
return command_success;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
find_breakpoint(uint16_t address)
|
||||
{
|
||||
int b;
|
||||
|
||||
for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
|
||||
if (breakpoints[b].enabled && breakpoints[b].address == address)
|
||||
break;
|
||||
if (b == CC_NUM_BREAKPOINTS)
|
||||
return -1;
|
||||
return b;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_break (int argc, char **argv)
|
||||
{
|
||||
int b;
|
||||
uint16_t address;
|
||||
enum command_result result;
|
||||
|
||||
if (argc == 1) {
|
||||
for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
|
||||
if (breakpoints[b].enabled)
|
||||
s51_printf("Breakpoint %d 0x%04x\n",
|
||||
b, breakpoints[b].address);
|
||||
return command_success;
|
||||
}
|
||||
if (argc != 2)
|
||||
return command_error;
|
||||
result = parse_uint16(argv[1], &address);
|
||||
if (result != command_success)
|
||||
return result;
|
||||
|
||||
return set_breakpoint(address, 0);
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_clear (int argc, char **argv)
|
||||
{
|
||||
uint16_t address;
|
||||
enum command_result result;
|
||||
|
||||
if (argc != 2)
|
||||
return command_error;
|
||||
result = parse_uint16(argv[1], &address);
|
||||
if (result != command_success)
|
||||
return result;
|
||||
return clear_breakpoint(address, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_stopped(uint8_t status)
|
||||
{
|
||||
uint16_t pc;
|
||||
int b;
|
||||
int code;
|
||||
char *reason;
|
||||
|
||||
pc = ccdbg_get_pc(s51_dbg);
|
||||
if (status & CC_STATUS_CPU_HALTED) {
|
||||
if ((status & CC_STATUS_HALT_STATUS) != 0) {
|
||||
pc = pc - 1;
|
||||
code = 104;
|
||||
reason = "Breakpoint";
|
||||
b = find_breakpoint(pc);
|
||||
if (b != -1 && breakpoints[b].temporary)
|
||||
clear_breakpoint(pc, 1);
|
||||
ccdbg_set_pc(s51_dbg, pc);
|
||||
} else {
|
||||
code = 105;
|
||||
reason = "Interrupt";
|
||||
}
|
||||
s51_printf("Stop at 0x%04x: (%d) %s\n",
|
||||
pc, code, reason);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cc_step(uint16_t pc)
|
||||
{
|
||||
int b;
|
||||
uint8_t status;
|
||||
|
||||
b = find_breakpoint(pc);
|
||||
if (b != -1)
|
||||
disable_breakpoint(b);
|
||||
status = ccdbg_step_instr(s51_dbg);
|
||||
if (b != -1)
|
||||
enable_breakpoint(b);
|
||||
return status;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_run (int argc, char **argv)
|
||||
{
|
||||
uint16_t start, end;
|
||||
enum command_result result;
|
||||
uint16_t pc;
|
||||
uint8_t status;
|
||||
int b;
|
||||
|
||||
if (argv[1]) {
|
||||
result = parse_uint16(argv[1], &start);
|
||||
if (result != command_success)
|
||||
return result;
|
||||
if (argv[2]) {
|
||||
result = parse_uint16(argv[2], &end);
|
||||
if (result != command_success)
|
||||
return result;
|
||||
}
|
||||
if (start_address && start == 0) {
|
||||
start = start_address;
|
||||
s51_printf("Starting at 0x%04x\n", start);
|
||||
}
|
||||
ccdbg_set_pc(s51_dbg, start);
|
||||
}
|
||||
else
|
||||
start = ccdbg_get_pc(s51_dbg);
|
||||
s51_printf("Resume at 0x%04x\n", start);
|
||||
pc = start;
|
||||
b = find_breakpoint(pc);
|
||||
if (b != -1) {
|
||||
cc_step(pc);
|
||||
pc = ccdbg_get_pc(s51_dbg);
|
||||
if (find_breakpoint(pc) != -1) {
|
||||
status = ccdbg_read_status(s51_dbg);
|
||||
cc_stopped(status);
|
||||
return command_success;
|
||||
}
|
||||
}
|
||||
ccdbg_resume(s51_dbg);
|
||||
result = cc_wait();
|
||||
return result;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_next (int argc, char **argv)
|
||||
{
|
||||
return command_step(argc, argv);
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_step (int argc, char **argv)
|
||||
{
|
||||
uint16_t pc;
|
||||
uint8_t opcode;
|
||||
uint8_t a;
|
||||
|
||||
a = cc_step(ccdbg_get_pc(s51_dbg));
|
||||
s51_printf(" ACC= 0x%02x\n", a);
|
||||
pc = ccdbg_get_pc(s51_dbg);
|
||||
ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
|
||||
s51_printf(" ? 0x%04x %02x\n", pc, opcode);
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_load (int argc, char **argv)
|
||||
{
|
||||
char *filename = argv[1];
|
||||
FILE *file;
|
||||
struct ao_hex_file *hex;
|
||||
struct ao_hex_image *image;
|
||||
|
||||
if (!filename)
|
||||
return command_error;
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
perror(filename);
|
||||
return command_error;
|
||||
}
|
||||
hex = ao_hex_file_read(file, filename);
|
||||
fclose(file);
|
||||
if (!hex) {
|
||||
return command_error;
|
||||
}
|
||||
image = ao_hex_image_create(hex);
|
||||
ao_hex_file_free(hex);
|
||||
if (!image) {
|
||||
fprintf(stderr, "image create failed\n");
|
||||
return command_error;
|
||||
}
|
||||
if (image->address >= 0xf000) {
|
||||
printf("Loading %d bytes to RAM at 0x%04x\n",
|
||||
image->length, image->address);
|
||||
ccdbg_write_hex_image(s51_dbg, image, 0);
|
||||
} else {
|
||||
fprintf(stderr, "Can only load to RAM\n");
|
||||
}
|
||||
ao_hex_image_free(image);
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_halt (int argc, char **argv)
|
||||
{
|
||||
uint16_t pc;
|
||||
ccdbg_halt(s51_dbg);
|
||||
pc = ccdbg_get_pc(s51_dbg);
|
||||
s51_printf("Halted at 0x%04x\n", pc);
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_stop (int argc, char **argv)
|
||||
{
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_reset (int argc, char **argv)
|
||||
{
|
||||
ccdbg_debug_mode(s51_dbg);
|
||||
ccdbg_halt(s51_dbg);
|
||||
enable_breakpoints();
|
||||
return command_success;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_status(int argc, char **argv)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
status = ccdbg_read_status(s51_dbg);
|
||||
if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
|
||||
s51_printf("\tChip erase in progress\n");
|
||||
if (status & CC_STATUS_PCON_IDLE)
|
||||
s51_printf("\tCPU is idle (clock gated)\n");
|
||||
if (status & CC_STATUS_CPU_HALTED)
|
||||
s51_printf("\tCPU halted\n");
|
||||
else
|
||||
s51_printf("\tCPU running\n");
|
||||
if ((status & CC_STATUS_POWER_MODE_0) == 0)
|
||||
s51_printf("\tPower Mode 1-3 selected\n");
|
||||
if (status & CC_STATUS_HALT_STATUS)
|
||||
s51_printf("\tHalted by software or hw breakpoint\n");
|
||||
else
|
||||
s51_printf("\tHalted by debug command\n");
|
||||
if (status & CC_STATUS_DEBUG_LOCKED)
|
||||
s51_printf("\tDebug interface is locked\n");
|
||||
if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
|
||||
s51_printf("\tOscillators are not stable\n");
|
||||
if (status & CC_STATUS_STACK_OVERFLOW)
|
||||
s51_printf("\tStack overflow\n");
|
||||
return command_success;
|
||||
}
|
||||
|
||||
static enum command_result
|
||||
info_breakpoints(int argc, char **argv)
|
||||
{
|
||||
int b;
|
||||
|
||||
if (argc == 1) {
|
||||
s51_printf("Num Type Disp Hit Cnt Address What\n");
|
||||
for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
|
||||
if (breakpoints[b].enabled) {
|
||||
s51_printf("%-3d fetch %s 1 1 0x%04x uc::disass() unimplemented\n",
|
||||
b,
|
||||
breakpoints[b].temporary ? "del " : "keep",
|
||||
breakpoints[b].address);
|
||||
}
|
||||
return command_success;
|
||||
}
|
||||
return command_syntax;
|
||||
}
|
||||
|
||||
static enum command_result
|
||||
info_help(int argc, char **argv);
|
||||
|
||||
static struct command_function infos[] = {
|
||||
{ "breakpoints", "b", info_breakpoints, "[b]reakpoints",
|
||||
"List current breakpoints\n" },
|
||||
{ "help", "?", info_help, "help",
|
||||
"Print this list\n" },
|
||||
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
static enum command_result
|
||||
info_help(int argc, char **argv)
|
||||
{
|
||||
return command_function_help(infos, argc, argv);
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_info(int argc, char **argv)
|
||||
{
|
||||
struct command_function *func;
|
||||
|
||||
if (argc < 2)
|
||||
return command_error;
|
||||
func = command_string_to_function(infos, argv[1]);
|
||||
if (!func)
|
||||
return command_syntax;
|
||||
return (*func->func)(argc-1, argv+1);
|
||||
}
|
||||
|
||||
enum command_result
|
||||
cc_wait(void)
|
||||
{
|
||||
for(;;) {
|
||||
uint8_t status;
|
||||
status = ccdbg_read_status(s51_dbg);
|
||||
if (status & CC_STATUS_CPU_HALTED) {
|
||||
cc_stopped(status);
|
||||
return command_success;
|
||||
}
|
||||
if (s51_interrupted || s51_check_input()) {
|
||||
|
||||
ccdbg_halt(s51_dbg);
|
||||
status = ccdbg_read_status(s51_dbg);
|
||||
cc_stopped(status);
|
||||
return command_interrupt;
|
||||
}
|
||||
}
|
||||
}
|
256
ao-tools/ao-dbg/ao-dbg-main.c
Normal file
256
ao-tools/ao-dbg/ao-dbg-main.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright © 2008 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "ao-dbg.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <poll.h>
|
||||
#include <getopt.h>
|
||||
|
||||
static int s51_port = 0;
|
||||
static char *cpu = "8051";
|
||||
static double freq = 11059200;
|
||||
char *s51_prompt = "> ";
|
||||
struct ccdbg *s51_dbg;
|
||||
int s51_interrupted = 0;
|
||||
int s51_monitor = 0;
|
||||
char *s51_tty = NULL;
|
||||
char *s51_device = NULL;
|
||||
|
||||
static FILE *s51_input;
|
||||
static FILE *s51_output;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "You're doing it wrong.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
s51_sigint(int signum)
|
||||
{
|
||||
s51_interrupted = 1;
|
||||
}
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
char *endptr;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "PVvHhmt:X:c:r:Z:s:S:p:T:", options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 't':
|
||||
cpu = optarg;
|
||||
break;
|
||||
case 'X':
|
||||
freq = strtod(optarg, &endptr);
|
||||
if (endptr == optarg)
|
||||
usage();
|
||||
if (endptr[0] != '\0') {
|
||||
if (!strcmp(endptr, "k"))
|
||||
freq *= 1000;
|
||||
else if (!strcmp(endptr, "M") )
|
||||
freq *= 1000000;
|
||||
else
|
||||
usage ();
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
break;
|
||||
case 'r':
|
||||
case 'Z':
|
||||
s51_port = strtol(optarg, &endptr, 0);
|
||||
if (endptr == optarg || strlen(endptr) != 0)
|
||||
usage();
|
||||
break;
|
||||
case 's':
|
||||
break;
|
||||
case 'S':
|
||||
break;
|
||||
case 'p':
|
||||
s51_prompt = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
s51_prompt = NULL;
|
||||
break;
|
||||
case 'V':
|
||||
break;
|
||||
case 'v':
|
||||
break;
|
||||
case 'H':
|
||||
exit (0);
|
||||
break;
|
||||
case 'h':
|
||||
usage ();
|
||||
break;
|
||||
case 'm':
|
||||
s51_monitor = 1;
|
||||
break;
|
||||
case 'T':
|
||||
s51_tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
s51_device = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (s51_port) {
|
||||
int l, r, one = 1;
|
||||
int s;
|
||||
struct sockaddr_in in;
|
||||
|
||||
l = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (l < 0) {
|
||||
perror ("socket");
|
||||
exit(1);
|
||||
}
|
||||
r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
|
||||
if (r) {
|
||||
perror("setsockopt");
|
||||
exit(1);
|
||||
}
|
||||
in.sin_family = AF_INET;
|
||||
in.sin_port = htons(s51_port);
|
||||
in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
r = bind(l, (struct sockaddr *) &in, sizeof (in));
|
||||
if (r) {
|
||||
perror("bind");
|
||||
exit(1);
|
||||
}
|
||||
r = listen(l, 5);
|
||||
if (r) {
|
||||
perror("listen");
|
||||
exit(1);
|
||||
}
|
||||
for (;;) {
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t client_len = sizeof (struct sockaddr_in);
|
||||
|
||||
s = accept(l, (struct sockaddr *)
|
||||
&client_addr, &client_len);
|
||||
if (s < 0) {
|
||||
perror("accept");
|
||||
exit(1);
|
||||
}
|
||||
s51_input = fdopen(s, "r");
|
||||
s51_output = fdopen(s, "w");
|
||||
if (!s51_input || !s51_output) {
|
||||
perror("fdopen");
|
||||
exit(1);
|
||||
}
|
||||
signal(SIGINT, SIG_IGN);
|
||||
command_read();
|
||||
signal(SIGINT, SIG_DFL);
|
||||
fclose(s51_input);
|
||||
fclose(s51_output);
|
||||
}
|
||||
} else {
|
||||
s51_input = stdin;
|
||||
s51_output = stdout;
|
||||
signal(SIGINT, s51_sigint);
|
||||
command_read();
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
s51_printf(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vfprintf(s51_output, format, ap);
|
||||
if (s51_monitor)
|
||||
vfprintf(stdout, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
s51_putc(int c)
|
||||
{
|
||||
putc(c, s51_output);
|
||||
}
|
||||
|
||||
#if HAVE_LIBREADLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
s51_read_line(char *line, int len)
|
||||
{
|
||||
int ret;
|
||||
#if HAVE_LIBREADLINE
|
||||
if (s51_output == stdout && s51_input == stdin && s51_prompt) {
|
||||
char *r;
|
||||
|
||||
r = readline(s51_prompt);
|
||||
if (r == NULL)
|
||||
return 0;
|
||||
strncpy (line, r, len);
|
||||
line[len-1] = '\0';
|
||||
add_history(r);
|
||||
return 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (s51_prompt)
|
||||
s51_printf("%s", s51_prompt);
|
||||
else
|
||||
s51_putc('\0');
|
||||
fflush(s51_output);
|
||||
ret = fgets(line, len, s51_input) != NULL;
|
||||
if (s51_monitor)
|
||||
printf("> %s", line);
|
||||
fflush(stdout);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
s51_check_input(void)
|
||||
{
|
||||
struct pollfd input;
|
||||
int r;
|
||||
|
||||
input.fd = fileno(s51_input);
|
||||
input.events = POLLIN;
|
||||
r = poll(&input, 1, 0);
|
||||
if (r > 0) {
|
||||
char line[256];
|
||||
(void) s51_read_line(line, sizeof (line));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
209
ao-tools/ao-dbg/ao-dbg-parse.c
Normal file
209
ao-tools/ao-dbg/ao-dbg-parse.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright © 2008 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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-dbg.h"
|
||||
|
||||
static struct command_function functions[] = {
|
||||
{ "help", "?", command_help, "help", "Print this list\n" },
|
||||
{ "quit", "q", command_quit, "[q]uit", "Quit\n" },
|
||||
{ "di", "di", command_di, "di <start> <end>",
|
||||
"Dump imem\n" },
|
||||
{ "ds", "ds", command_ds, "ds <start> <end>",
|
||||
"Dump sprs\n" },
|
||||
{ "dx", "dx", command_dx, "dx <start> <end>",
|
||||
"Dump xaddr\n" },
|
||||
{ "set", "t", command_set, "se[t] mem <prefix> <address> <data> ...",
|
||||
"Set mem {xram|rom|iram|sfr}\n"
|
||||
"set bit <addr>\n" },
|
||||
{ "dump", "d", command_dump, "[d]ump <prefix> <start> <end>",
|
||||
"Dump {xram|rom|iram|sfr} <start> <end>\n" },
|
||||
{ "file", "file", command_file, "file <filename>",
|
||||
"Pretend to load executable from <filename>\n" },
|
||||
{ "pc", "p", command_pc, "[p]c [addr]",
|
||||
"Get or set pc value\n" },
|
||||
{ "break", "b", command_break,"[b]reak <addr>",
|
||||
"Set break point\n" },
|
||||
{ "clear", "c", command_clear,"[c]lear <addr>",
|
||||
"Clear break point\n" },
|
||||
{ "run", "r", command_run, "[r]un [start] [stop]",
|
||||
"Run with optional start and temp breakpoint addresses\n" },
|
||||
{ "go", "g", command_run, "[g]o [start] [stop]",
|
||||
"Run with optional start and temp breakpoint addresses\n" },
|
||||
{ "next", "n", command_next, "[n]ext",
|
||||
"Step over one instruction, past any call\n" },
|
||||
{ "step", "s", command_step, "[s]tep",
|
||||
"Single step\n" },
|
||||
{ "load", "l", command_load, "[l]oad <file>",
|
||||
"Load a hex file into memory or flash" },
|
||||
{ "halt", "h", command_halt, "[h]alt",
|
||||
"Halt the processor\n" },
|
||||
{ "reset","res",command_reset, "[res]et",
|
||||
"Reset the CPU\n" },
|
||||
{ "status","status",command_status, "status",
|
||||
"Display CC1111 debug status\n" },
|
||||
{ "info", "i", command_info, "[i]info",
|
||||
"Get information\n" },
|
||||
{ "stop", "stop", command_stop, "stop",
|
||||
"Ignored\n" },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
struct command_function *
|
||||
command_string_to_function(struct command_function *functions, char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; functions[i].name; i++)
|
||||
if (!strcmp(name, functions[i].name) ||
|
||||
!strcmp(name, functions[i].alias))
|
||||
return &functions[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_function_help(struct command_function *functions, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
struct command_function *func;
|
||||
|
||||
if (argc == 1) {
|
||||
for (i = 0; functions[i].name; i++)
|
||||
s51_printf("%-10s%s\n", functions[i].name,
|
||||
functions[i].usage);
|
||||
} else {
|
||||
for (i = 1; i < argc; i++) {
|
||||
func = command_string_to_function(functions, argv[i]);
|
||||
if (!func) {
|
||||
s51_printf("%-10s unknown command\n", argv[i]);
|
||||
return command_syntax;
|
||||
}
|
||||
s51_printf("%-10s %s\n%s", func->name,
|
||||
func->usage, func->help);
|
||||
}
|
||||
}
|
||||
return command_debug;
|
||||
}
|
||||
|
||||
static int
|
||||
command_split_into_words(char *line, char **argv)
|
||||
{
|
||||
char quotechar;
|
||||
int argc;
|
||||
|
||||
argc = 0;
|
||||
while (*line) {
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
if (!*line)
|
||||
break;
|
||||
if (*line == '"') {
|
||||
quotechar = *line++;
|
||||
*argv++ = line;
|
||||
argc++;
|
||||
while (*line && *line != quotechar)
|
||||
line++;
|
||||
if (*line)
|
||||
*line++ = '\0';
|
||||
} else {
|
||||
*argv++ = line;
|
||||
argc++;
|
||||
while (*line && !isspace(*line))
|
||||
line++;
|
||||
if (*line)
|
||||
*line++ = '\0';
|
||||
}
|
||||
}
|
||||
*argv = 0;
|
||||
return argc;
|
||||
}
|
||||
|
||||
enum command_result
|
||||
command_help(int argc, char **argv)
|
||||
{
|
||||
return command_function_help(functions, argc, argv);
|
||||
}
|
||||
|
||||
void
|
||||
command_syntax_error(int argc, char **argv)
|
||||
{
|
||||
s51_printf("Syntax error in:");
|
||||
while (*argv)
|
||||
s51_printf(" %s", *argv++);
|
||||
s51_printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
command_read (void)
|
||||
{
|
||||
int argc;
|
||||
char line[1024];
|
||||
char *argv[20];
|
||||
enum command_result result;
|
||||
struct command_function *func;
|
||||
|
||||
if (!s51_tty) {
|
||||
if (!s51_device)
|
||||
s51_device = getenv("AO_DBG_DEVICE");
|
||||
s51_tty = cc_usbdevs_find_by_arg(s51_device, "TeleDongle");
|
||||
}
|
||||
s51_dbg = ccdbg_open (s51_tty);
|
||||
if (!s51_dbg)
|
||||
exit(1);
|
||||
ccdbg_debug_mode(s51_dbg);
|
||||
ccdbg_halt(s51_dbg);
|
||||
s51_printf("Welcome to the non-simulated processor\n");
|
||||
for (;;) {
|
||||
if (s51_read_line (line, sizeof line) == 0)
|
||||
break;
|
||||
s51_interrupted = 0;
|
||||
argc = command_split_into_words(line, argv);
|
||||
if (argc > 0) {
|
||||
func = command_string_to_function(functions, argv[0]);
|
||||
if (!func)
|
||||
command_syntax_error(argc, argv);
|
||||
else
|
||||
{
|
||||
result = (*func->func)(argc, argv);
|
||||
if (s51_interrupted)
|
||||
result = command_interrupt;
|
||||
switch (result) {
|
||||
case command_syntax:
|
||||
command_syntax_error(argc, argv);
|
||||
break;
|
||||
case command_error:
|
||||
s51_printf("Error\n");
|
||||
break;
|
||||
case command_success:
|
||||
break;
|
||||
case command_interrupt:
|
||||
ccdbg_halt(s51_dbg);
|
||||
s51_printf("Interrupted\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ccdbg_close(s51_dbg);
|
||||
s51_printf("...\n");
|
||||
}
|
235
ao-tools/ao-dbg/ao-dbg.1
Normal file
235
ao-tools/ao-dbg/ao-dbg.1
Normal file
@@ -0,0 +1,235 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-DBG 1 "ao-dbg" ""
|
||||
.SH NAME
|
||||
ao-dbg \- hex debugger for cc1111 processors
|
||||
.SH SYNOPSIS
|
||||
.B "ao-dbg"
|
||||
[\-t \fIcpu-type\fP]
|
||||
[\-X \fIfrequency\fP]
|
||||
[\-c]
|
||||
[\-r \fIlisten-port\fP]
|
||||
[\-Z \fIlisten-port\fP]
|
||||
[\-s]
|
||||
[\-S]
|
||||
[\-p \fIprompt\fP]
|
||||
[\-V]
|
||||
[\-v]
|
||||
[\-H]
|
||||
[\-h]
|
||||
[\-m]
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
.SH DESCRIPTION
|
||||
.I ao-dbg
|
||||
connects to a cc1111 processor through either a suitable cc1111 board
|
||||
or a cp2103 usb to serial converter board, using the GPIO pins
|
||||
available on that chip. It provides an interface compatible with the
|
||||
8051 emulator from sdcc called s51, but communicating with the real
|
||||
chip instead of an emulation. Using a modified version of the SDCC
|
||||
debugger (sdcdb), you can control program execution on the target
|
||||
machine at source-level.
|
||||
|
||||
.SH OPTIONS
|
||||
The command line options are designed to be compatible with the 8051
|
||||
emulator so that it can be used with sdcdb. As such, they're all one letter
|
||||
long.
|
||||
.IP "\-t \fIcpu-type\fP"
|
||||
The 8051 emulator can operate as one of several different chips. Oddly, the
|
||||
real hardware cannot, so this option is ignored.
|
||||
.IP "\-X \fIfrequency\fP"
|
||||
Similarly, the emulator can pretend to run at an arbitrary frequency
|
||||
which the real hardware cannot do. Ignored.
|
||||
.IP "\-c"
|
||||
.IP "\-s"
|
||||
.IP "\-S"
|
||||
.IP "\-v"
|
||||
.IP "\-V"
|
||||
All ignored.
|
||||
.IP "\-r \fIlisten-port\fP, -Z \fIlisten-port\fP"
|
||||
The emulator and sdcdb communicate through a network socket. This option
|
||||
switches the debugger from communicating through stdin/stdout to listening
|
||||
on a specific network port instead. Once a connection is made, the debugger
|
||||
continues on, using that network port for command input and output. The
|
||||
debugger uses port 9756, and attempts to connect before launching ao-dbg, so if
|
||||
ao-dbg is listening on this port before sdcdb is started, sdcdb will end up
|
||||
talking to the existing ao-dbg instance. That's often useful for debugging ao-dbg
|
||||
itself.
|
||||
.IP "\-p \fIprompt\fP"
|
||||
This sets the command prompt to the specified string.
|
||||
.IP "\-P"
|
||||
This sets the command prompt to a single NUL character. This is for use by
|
||||
sdcdb.
|
||||
.IP "\-h"
|
||||
This should print a usage message, but does nothing useful currently.
|
||||
.IP "\-m"
|
||||
This option is not present in the original 8051 emulator, and causes ao-dbg to
|
||||
dump all commands and replies that are received from and sent to sdcdb.
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
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
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMetrum:2
|
||||
.br
|
||||
TeleMetrum
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.SH COMMANDS
|
||||
Once started, ao-dbg connects to the cc1111 and then reads and
|
||||
executes commands, either from stdin, or the network connection to
|
||||
sdcdb.
|
||||
.PP
|
||||
Unlike the command line, ao-dbg contains built-in help for each of these
|
||||
commands, via the 'help' command. Most of the commands are available in a
|
||||
long form and a single character short form. Below, the short form follows
|
||||
the long form after a comma.
|
||||
.IP "help, ? {command}"
|
||||
Without arguments, prints a list of available commands. With an argument
|
||||
prints more detail about the specific command
|
||||
.IP "quit, q"
|
||||
Terminates the application, without changing the state of the target
|
||||
processor.
|
||||
.IP "di [start] [end]"
|
||||
Dumps imem (256 bytes of "internal" memory) from start to end (inclusive).
|
||||
.IP "ds [start] [end]"
|
||||
Dumps sprs from start to end (inclusive). Note that while most sprs are
|
||||
visible in the global address space, some are not, so use this command
|
||||
instead of "dx" to read them.
|
||||
.IP "dx [start] [end]"
|
||||
Dump external (global) memory from start to end (inclusive).
|
||||
.IP "set, t <prefix> [start] {data ...}"
|
||||
Store to the memory space specified by prefix where prefix is one of "xram",
|
||||
"rom", "iram", or "sfr". Store bytes starting at start.
|
||||
.IP "dump, d <prefix> [start] [end]"
|
||||
Dump from the memory space specified by prefix, where prefix is one of
|
||||
"xram", "rom", "iram" or "sfr". Dumps from start to end (inclusive).
|
||||
.IP "file [filename]"
|
||||
Specifies an intel-format hex file (ihx) that contains the contents of the
|
||||
rom area loaded into the cc1111. This is used to respond to requests to dump
|
||||
rom memory contents without getting them from the cc1111 (which is slow).
|
||||
.IP "pc, p {address}"
|
||||
If the address argument is given, this sets the program counter to the
|
||||
specified value. Otherwise, the current program counter value is displayed.
|
||||
.IP "break, b [address]"
|
||||
Sets a breakpoint at the specified address. This uses the built-in hardware
|
||||
breakpoint support in the cc1111. As a result, it supports no more than four
|
||||
breakpoints at once. You must therefore use a modified version of sdcdb which
|
||||
changes how program execution is controlled to work within this limit.
|
||||
.IP "clear, c [address]"
|
||||
Clear a breakpoint from the specified address.
|
||||
.IP "run, r, go, g {start} {stop}"
|
||||
Resumes execution of the program. If the start argument is present, then it
|
||||
begins at that address, otherwise it continues running at the current pc. If
|
||||
a stop argument is present, then a temporary breakpoint is set at that
|
||||
address. This temporary breakpoint will be removed when execution hits it.
|
||||
.IP "next, n"
|
||||
Step one instruction. In the original s51 program this would ignore
|
||||
subroutines, but as sdcdb doesn't require this functionality, it's not
|
||||
available here.
|
||||
.IP "step, s"
|
||||
Step one instruction.
|
||||
.IP "load, l [filename]"
|
||||
This is not implemented, but it is supposed to load a hex file into flash.
|
||||
Use the ccload program instead.
|
||||
.IP "halt, h"
|
||||
Halt the processor. This is the only command which can be sent while the
|
||||
program is running. It is ignored at other times.
|
||||
.IP "reset, res"
|
||||
Reset the processor. This pulls the reset pin low and re-enables debug mode.
|
||||
Check the cc1111 documentation to see precisely what this does.
|
||||
.IP "status"
|
||||
This dumps the cc1111 debug status register.
|
||||
.IP "info, i breakpoints, b"
|
||||
List the current breakpoints.
|
||||
.IP "info, i help, ?"
|
||||
List the things you can get info on.
|
||||
.IP "stop"
|
||||
This doesn't do anything and is present only to retain compatibility with
|
||||
the original 8051 emulator.
|
||||
.SH "BOARD BRINGUP DEBUGGING"
|
||||
.PP
|
||||
While the original purpose for this program was to connect the source
|
||||
debugger with the hardware, it can also be used as a low-level hex debugger
|
||||
all on its own. In particular, all of the cc1111 peripherals can be
|
||||
manipulated directly from the ao-dbg command line.
|
||||
.IP "Starting ao-dbg"
|
||||
First ensure that the target cc1111 device and intermediate cp2103 or
|
||||
cc111 board are all hooked up correctly.
|
||||
.IP
|
||||
$ ao-dbg
|
||||
.br
|
||||
Welcome to the non-simulated processor
|
||||
.br
|
||||
> status
|
||||
.br
|
||||
CPU halted
|
||||
.br
|
||||
Halted by debug command
|
||||
.br
|
||||
>
|
||||
.IP "Turning on LEDs"
|
||||
Two of the cc1111 GPIO pins, P1_0 and P1_1 are capable of driving external
|
||||
LEDs. To control these, set the Port 1 direction bits to make these output
|
||||
pins and then change the Port 1 data to set them high or low:
|
||||
.IP
|
||||
> set sfr 0xfe 0x02 # set P1DIR to 0x2
|
||||
.br
|
||||
> set sfr 0x90 0x02 # set P1_1 to high
|
||||
.br
|
||||
> set sfr 0x90 0x00 # set P1_1 to low
|
||||
.IP "Reading the A/D converters"
|
||||
The six A/D converter inputs can each be connected to any of the P0 pins,
|
||||
ground, the A/D voltage reference, an internal temperature sensor or VDD/3.
|
||||
To read one of these values, select an A/D converter to use then start the
|
||||
conversion process. The cc1111 manual has the table for selecting the input
|
||||
on page 144.
|
||||
.IP
|
||||
To configure one of the P0 pins for use by the A/D unit, we program the
|
||||
ADCCFG register, setting the bits in that which match the pins desired:
|
||||
.IP
|
||||
> set sfr 0xf2 0x3f # enable all 6 A/D inputs
|
||||
.IP
|
||||
To trigger a single conversion, we ask the A/D unit to perform an 'extra'
|
||||
conversion, which means to do a single conversion not a whole sequence of
|
||||
conversions. This is controlled by the ADCCON3 register at 0xB6:
|
||||
.IP
|
||||
> set sfr 0xb6 0xb2 # sample P0_2 using 12 bits of precision
|
||||
.br
|
||||
> ds 0xba 0xbb # dump the ADC data low and high regs
|
||||
.br
|
||||
> set sfr 0xb6 0xbe # sample internal temperature sensor
|
||||
.br
|
||||
> ds 0xba 0xbb # dump the ADC data low and high regs
|
||||
.SH "SEE ALSO"
|
||||
sdcdb(1), ccload(1)
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
127
ao-tools/ao-dbg/ao-dbg.h
Normal file
127
ao-tools/ao-dbg/ao-dbg.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright © 2008 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <ccdbg.h>
|
||||
#include <cc.h>
|
||||
#include <ctype.h>
|
||||
|
||||
extern char *s51_prompt;
|
||||
extern struct ccdbg *s51_dbg;
|
||||
extern int s51_interrupted;
|
||||
extern int s51_monitor;
|
||||
extern char *s51_tty;
|
||||
extern char *s51_device;
|
||||
|
||||
enum command_result {
|
||||
command_success, command_debug, command_syntax, command_interrupt, command_error,
|
||||
};
|
||||
|
||||
struct command_function {
|
||||
char *name;
|
||||
char *alias;
|
||||
enum command_result (*func)(int argc, char **argv);
|
||||
char *usage;
|
||||
char *help;
|
||||
};
|
||||
|
||||
struct command_function *
|
||||
command_string_to_function(struct command_function *functions, char *name);
|
||||
|
||||
enum command_result
|
||||
command_function_help(struct command_function *functions, int argc, char **argv);
|
||||
|
||||
void
|
||||
command_syntax_error(int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_quit (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_help (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_stop (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_di (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_ds (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_dx (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_set (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_dump (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_file (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_pc (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_break (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_clear (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_run (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_next (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_step (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_load (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_halt (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_reset (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_status (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
command_info (int argc, char **argv);
|
||||
|
||||
enum command_result
|
||||
cc_wait(void);
|
||||
|
||||
void
|
||||
command_read (void);
|
||||
|
||||
void
|
||||
s51_printf(char *format, ...);
|
||||
|
||||
void
|
||||
s51_putc(int c);
|
||||
|
||||
int
|
||||
s51_check_input(void);
|
||||
|
||||
int
|
||||
s51_read_line(char *line, int len);
|
60
ao-tools/ao-dbg/commands
Normal file
60
ao-tools/ao-dbg/commands
Normal file
@@ -0,0 +1,60 @@
|
||||
Listens on port 9756 for a command stream.
|
||||
|
||||
Dump commands:
|
||||
di <start> <end> - dump imem
|
||||
ds <start> <end> - dump sprs
|
||||
dx <start> <end> - dump xaddr
|
||||
|
||||
Returns a string of hex pairs, each preceded by a space,
|
||||
with 8 pairs per line
|
||||
|
||||
Memory access commands:
|
||||
set mem <prefix> <start> <end>
|
||||
dump <prefix> <start> <end>
|
||||
|
||||
<prefix> is one of:
|
||||
|
||||
xram - external ram or external stack
|
||||
rom - code space
|
||||
iram - internal ram or stack
|
||||
sfr - special function register
|
||||
|
||||
|
||||
dump <addr>
|
||||
set bit <addr>
|
||||
|
||||
bit addressable space
|
||||
|
||||
Set PC:
|
||||
|
||||
pc <addr>
|
||||
|
||||
Sets PC to specified address
|
||||
|
||||
pc
|
||||
|
||||
Returns current PC
|
||||
|
||||
Breakpoints
|
||||
|
||||
break <addr>
|
||||
clear <addr>
|
||||
|
||||
Load a file
|
||||
|
||||
file "<filename>"
|
||||
|
||||
Execution control:
|
||||
|
||||
run <start> - run starting at <start>
|
||||
run <start> <stop> - set temporary bp at <stop>
|
||||
run - continue
|
||||
next - step over calls(?)
|
||||
step - step one instruction
|
||||
|
||||
reset - reset the simulator
|
||||
res - synonym?
|
||||
|
||||
Error messages:
|
||||
|
||||
start with "Error:"
|
12
ao-tools/ao-dump-up/Makefile.am
Normal file
12
ao-tools/ao-dump-up/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-dump-up
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) $(GNOME_CFLAGS)
|
||||
AO_DUMP_LOG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_dump_up_DEPENDENCIES = $(AO_DUMP_LOG_LIBS)
|
||||
|
||||
ao_dump_up_LDADD=$(AO_DUMP_LOG_LIBS) $(LIBUSB_LIBS) $(GNOME_LIBS)
|
||||
|
||||
ao_dump_up_SOURCES = ao-dump-up.c
|
||||
|
||||
man_MANS = ao-dump-up.1
|
49
ao-tools/ao-dump-up/ao-dump-up.1
Normal file
49
ao-tools/ao-dump-up/ao-dump-up.1
Normal file
@@ -0,0 +1,49 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-DUMPLOG 1 "ao-dump-up" ""
|
||||
.SH NAME
|
||||
ao-dump-up \- Dump flight log from MicroPeak flight computer
|
||||
.SH SYNOPSIS
|
||||
.B "ao-dump-up"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\--wait]
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
This selects which tty device ao-dump-up uses to communicate with
|
||||
the target device.
|
||||
.TP
|
||||
\-D AltOS-device | --device AltOS-device
|
||||
Search for a connected device. This forces the program to look
|
||||
for a specific USB device name.
|
||||
.TP
|
||||
\--wait
|
||||
Wait for a device to appear instead of exiting when no device is found.
|
||||
.SH DESCRIPTION
|
||||
.I ao-dump-up
|
||||
downloads a MicroPeak flight log from a connected MicroPeak USB adapter.
|
||||
.SH USAGE
|
||||
.I ao-dump-up
|
||||
connects to the specified target device and dumps the stored flight
|
||||
log.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
229
ao-tools/ao-dump-up/ao-dump-up.c
Normal file
229
ao-tools/ao-dump-up/ao-dump-up.c
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include "cc-usb.h"
|
||||
#include "cc.h"
|
||||
|
||||
#define NUM_BLOCK 512
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "wait", .has_arg = 0, .val = 'w' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--wait]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int get_nonwhite(struct cc_usb *cc, int timeout)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (;;) {
|
||||
c = cc_usb_getchar_timeout(cc, timeout);
|
||||
putchar(c);
|
||||
if (!isspace(c))
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t test_data[] = {
|
||||
0xfc, 0xfd, 0xfe, 0xff, 0xf8, 0xf9, 0xfa, 0xfb, 0x40, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
|
||||
0x17, 0x08,
|
||||
};
|
||||
|
||||
static bool test_failed;
|
||||
static int test_pos;
|
||||
|
||||
static void
|
||||
check_test(uint8_t b)
|
||||
{
|
||||
if (test_pos >= sizeof (test_data) || test_data[test_pos++] != b)
|
||||
test_failed = true;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
get_hexc(struct cc_usb *cc)
|
||||
{
|
||||
int c = get_nonwhite(cc, 1000);
|
||||
|
||||
if ('0' <= c && c <= '9')
|
||||
return c - '0';
|
||||
if ('a' <= c && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
if ('A' <= c && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
fprintf(stderr, "Non-hex char '%c'\n", c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int file_crc;
|
||||
|
||||
static const int POLY = 0x8408;
|
||||
|
||||
static int
|
||||
log_crc(int crc, int b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (((crc & 0x0001) ^ (b & 0x0001)) != 0)
|
||||
crc = (crc >> 1) ^ POLY;
|
||||
else
|
||||
crc = crc >> 1;
|
||||
b >>= 1;
|
||||
}
|
||||
return crc & 0xffff;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
get_hex(struct cc_usb *cc)
|
||||
{
|
||||
int a = get_hexc(cc);
|
||||
int b = get_hexc(cc);
|
||||
int h = (a << 4) + b;
|
||||
|
||||
file_crc = log_crc(file_crc, h);
|
||||
check_test(h);
|
||||
return h;
|
||||
}
|
||||
|
||||
static int get_32(struct cc_usb *cc)
|
||||
{
|
||||
int v = 0;
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
v += get_hex(cc) << (i * 8);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static int get_16(struct cc_usb *cc)
|
||||
{
|
||||
int v = 0;
|
||||
int i;
|
||||
for (i = 0; i < 2; i++) {
|
||||
v += get_hex(cc) << (i * 8);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static int swap16(int i)
|
||||
{
|
||||
return ((i << 8) & 0xff00) | ((i >> 8) & 0xff);
|
||||
}
|
||||
|
||||
static int find_header(struct cc_usb *cc)
|
||||
{
|
||||
for (;;) {
|
||||
if (get_nonwhite(cc, -1) == 'M' && get_nonwhite(cc, 1000) == 'P')
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct cc_usb *cc;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
int c;
|
||||
int nsamples;
|
||||
int i;
|
||||
int crc;
|
||||
int current_crc;
|
||||
int wait = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "wT:D:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'w':
|
||||
wait = 1;
|
||||
break;
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tty) {
|
||||
for (;;) {
|
||||
tty = cc_usbdevs_find_by_arg(device, "FT230X Basic UART");
|
||||
if (tty) {
|
||||
if (wait) {
|
||||
printf("tty is %s\n", tty);
|
||||
sleep(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!wait)
|
||||
break;
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyUSB0";
|
||||
cc = cc_usb_open(tty);
|
||||
if (!cc)
|
||||
exit(1);
|
||||
find_header(cc);
|
||||
file_crc = 0xffff;
|
||||
get_32(cc); /* ground pressure */
|
||||
get_32(cc); /* min pressure */
|
||||
nsamples = get_16(cc); /* nsamples */
|
||||
for (i = 0; i < nsamples; i++)
|
||||
get_16(cc); /* sample i */
|
||||
current_crc = swap16(~file_crc & 0xffff);
|
||||
crc = get_16(cc); /* crc */
|
||||
putchar ('\n');
|
||||
if (crc == current_crc) {
|
||||
if (!test_failed)
|
||||
printf("\033[32mValid MicroTest Data\033[39m\n");
|
||||
else
|
||||
printf("CRC valid\n");
|
||||
}
|
||||
else
|
||||
printf("CRC invalid\n");
|
||||
cc_usb_close(cc);
|
||||
exit (0);
|
||||
}
|
1
ao-tools/ao-dumpflash/.gitignore
vendored
Normal file
1
ao-tools/ao-dumpflash/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-dumpflash
|
12
ao-tools/ao-dumpflash/Makefile.am
Normal file
12
ao-tools/ao-dumpflash/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-dumpflash
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_DUMPLOG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_dumpflash_DEPENDENCIES = $(AO_DUMPLOG_LIBS)
|
||||
|
||||
ao_dumpflash_LDADD=$(AO_DUMPLOG_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_dumpflash_SOURCES = ao-dumpflash.c
|
||||
|
||||
man_MANS = ao-dumpflash.1
|
71
ao-tools/ao-dumpflash/ao-dumpflash.1
Normal file
71
ao-tools/ao-dumpflash/ao-dumpflash.1
Normal file
@@ -0,0 +1,71 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-DUMPFLASH 1 "ao-dumpflash" ""
|
||||
.SH NAME
|
||||
ao-dumpflash \- Fetch flash memory contents from AltOS device
|
||||
.SH SYNOPSIS
|
||||
.B "ao-dumpflash"
|
||||
[\--tty \fItty-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\--output \fIoutput-file\fP]
|
||||
[\--remote\fP]
|
||||
[\--frequency \fIfrequency\fP]
|
||||
[\--call \fIcallsign\fP]
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
This selects which tty device ao-dumpflash uses to communicate with
|
||||
the target device.
|
||||
.TP
|
||||
\-D AltOS-device | --device AltOS-device
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMetrum:2
|
||||
.br
|
||||
TeleMetrum
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\-o output-file | --output output-file
|
||||
Write flash contents to the specified file rather than stdout.
|
||||
.TP
|
||||
\-R | --remote
|
||||
This uses the command radio link to download the flash from TeleMetrum
|
||||
through a TeleDongle.
|
||||
.TP
|
||||
\-F frequency | --frequency frequency
|
||||
Specifies the radio frequency to use for remote communications in
|
||||
kHz. Default is 434550.
|
||||
.TP
|
||||
\-C callsign | --call callsign
|
||||
Specifies the callsign to use for remote communications. Default is N0CALL.
|
||||
.SH DESCRIPTION
|
||||
.I ao-dumpflash
|
||||
downloads the entire flash memory contents from a connected AltOS device and writes
|
||||
it to either stdout or the specified output file.
|
||||
.SH USAGE
|
||||
.I ao-dumpflash
|
||||
connects to the specified target device and dumps the flash.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
168
ao-tools/ao-dumpflash/ao-dumpflash.c
Normal file
168
ao-tools/ao-dumpflash/ao-dumpflash.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include "cc-usb.h"
|
||||
#include "cc.h"
|
||||
|
||||
#define NUM_BLOCK 512
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "remote", .has_arg = 0, .val = 'R' },
|
||||
{ .name = "frequency", .has_arg = 1, .val = 'F' },
|
||||
{ .name = "call", .has_arg = 1, .val = 'C' },
|
||||
{ .name = "output", .has_arg = 1, .val = 'o' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--remote] [--frequency <radio-frequency>] [--call <radio-callsign>]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct cc_usb *cc;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
int c;
|
||||
char line[8192];
|
||||
FILE *out;
|
||||
int serial_number = 0;
|
||||
int freq = 434550;
|
||||
char *call = "N0CALL";
|
||||
int block;
|
||||
int addr;
|
||||
int received_addr;
|
||||
int data[8];
|
||||
int i;
|
||||
int remote = 0;
|
||||
int storage_size = 0;
|
||||
char *out_name = NULL;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "T:D:F:C:o:R", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
remote = 1;
|
||||
break;
|
||||
case 'F':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'C':
|
||||
call = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
out_name = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tty) {
|
||||
if (remote)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleDongle");
|
||||
else
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleMetrum");
|
||||
}
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyACM0";
|
||||
|
||||
cc = cc_usb_open(tty);
|
||||
if (!cc)
|
||||
exit(1);
|
||||
if (remote)
|
||||
cc_usb_open_remote(cc, freq, call);
|
||||
|
||||
if (out_name) {
|
||||
out = fopen(out_name, "w");
|
||||
if (!out) {
|
||||
perror(out_name);
|
||||
cc_usb_close(cc);
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
out = stdout;
|
||||
|
||||
/* send a 'version' command followed by a 'flash' command */
|
||||
cc_usb_printf(cc, "f\nv\n");
|
||||
for (;;) {
|
||||
cc_usb_getline(cc, line, sizeof (line));
|
||||
if (sscanf(line, "serial-number %u", &serial_number) == 1)
|
||||
continue;
|
||||
if (sscanf(line, "Storage size: %u", &storage_size) == 1)
|
||||
continue;
|
||||
if (!strncmp(line, "software-version", 16))
|
||||
break;
|
||||
}
|
||||
if (!serial_number) {
|
||||
fprintf(stderr, "no serial number found\n");
|
||||
cc_usb_close(cc);
|
||||
exit(1);
|
||||
}
|
||||
if (!storage_size) {
|
||||
fprintf(stderr, "no storage size found\n");
|
||||
cc_usb_close(cc);
|
||||
exit(1);
|
||||
}
|
||||
printf ("Serial number: %d\n", serial_number);
|
||||
printf ("Storage size: %d\n", storage_size);
|
||||
fprintf (stderr, "%7d of %7d", 0, storage_size/256);
|
||||
for (block = 0; block < storage_size / 256; block++) {
|
||||
cc_usb_printf(cc, "e %x\n", block);
|
||||
fprintf (stderr, "\r%7d of %7d", block + 1, storage_size/256); fflush(stderr);
|
||||
for (addr = 0; addr < 0x100;) {
|
||||
cc_usb_getline(cc, line, sizeof (line));
|
||||
if (sscanf(line, "00%x %x %x %x %x %x %x %x %x",
|
||||
&received_addr,
|
||||
&data[0], &data[1], &data[2], &data[3],
|
||||
&data[4], &data[5], &data[6], &data[7]) == 9)
|
||||
{
|
||||
if (received_addr != addr)
|
||||
fprintf(stderr, "data out of sync at 0x%x\n",
|
||||
block * 256 + received_addr);
|
||||
|
||||
fprintf (out, "%08x", block * 256 + addr);
|
||||
for (i = 0; i < 8; i++)
|
||||
fprintf (out, " %02x", data[i]);
|
||||
fprintf (out, "\n");
|
||||
|
||||
addr += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
cc_usb_close(cc);
|
||||
exit (0);
|
||||
}
|
12
ao-tools/ao-dumplog/Makefile.am
Normal file
12
ao-tools/ao-dumplog/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-dumplog
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) $(GNOME_CFLAGS)
|
||||
AO_DUMPLOG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_dumplog_DEPENDENCIES = $(AO_DUMPLOG_LIBS)
|
||||
|
||||
ao_dumplog_LDADD=$(AO_DUMPLOG_LIBS) $(LIBUSB_LIBS) $(GNOME_LIBS)
|
||||
|
||||
ao_dumplog_SOURCES = ao-dumplog.c
|
||||
|
||||
man_MANS = ao-dumplog.1
|
74
ao-tools/ao-dumplog/ao-dumplog.1
Normal file
74
ao-tools/ao-dumplog/ao-dumplog.1
Normal file
@@ -0,0 +1,74 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-DUMPLOG 1 "ao-dumplog" ""
|
||||
.SH NAME
|
||||
ao-dumplog \- Store flight log from TeleMetrum device
|
||||
.SH SYNOPSIS
|
||||
.B "ao-dumplog"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\--R\fP]
|
||||
[\--remote\fP]
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
This selects which tty device ao-dumplog uses to communicate with
|
||||
the target device.
|
||||
.TP
|
||||
\-D AltOS-device | --device AltOS-device
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMetrum:2
|
||||
.br
|
||||
TeleMetrum
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\-R | --remote
|
||||
This uses the command radio link to download the log from TeleMetrum
|
||||
through a TeleDongle.
|
||||
.SH DESCRIPTION
|
||||
.I ao-dumplog
|
||||
downloads the flight log from a connected TeleMetrum device and stores
|
||||
it to the configured flight log directory using a name of the form
|
||||
.IP
|
||||
\fIyyyy\fP-\fImm\fP-\fIdd\fP-serialP-\fIsss\fP-flight-\fIfff\fP.eeprom
|
||||
.PP
|
||||
\fIyyyy\fP is the current year
|
||||
.br
|
||||
\fImm\fP is the current month
|
||||
.br
|
||||
\fIdd\fP is the current day
|
||||
.br
|
||||
\fIsss\fP is the device serial number
|
||||
.br
|
||||
\fIfff\fP is a flight sequence number (to make filenames unique)
|
||||
.SH USAGE
|
||||
.I ao-dumplog
|
||||
connects to the specified target device and dumps the stored flight
|
||||
log.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
230
ao-tools/ao-dumplog/ao-dumplog.c
Normal file
230
ao-tools/ao-dumplog/ao-dumplog.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include "cc-usb.h"
|
||||
#include "cc.h"
|
||||
|
||||
#define NUM_BLOCK 512
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "remote", .has_arg = 0, .val = 'R' },
|
||||
{ .name = "channel", .has_arg = 1, .val = 'C' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--remote] [--channel <radio-channel>]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
log_checksum(int d[8])
|
||||
{
|
||||
uint8_t sum = 0x5a;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
sum += (uint8_t) d[i];
|
||||
return -sum;
|
||||
}
|
||||
|
||||
static const char *state_names[] = {
|
||||
"startup",
|
||||
"idle",
|
||||
"pad",
|
||||
"boost",
|
||||
"fast",
|
||||
"coast",
|
||||
"drogue",
|
||||
"main",
|
||||
"landed",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct cc_usb *cc;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
int c;
|
||||
char line[8192];
|
||||
FILE *out;
|
||||
char *filename;
|
||||
int serial_number = 0;
|
||||
int channel = 0;
|
||||
int flight = 0;
|
||||
char cmd;
|
||||
int tick, a, b;
|
||||
int block;
|
||||
int addr;
|
||||
int received_addr;
|
||||
int data[8];
|
||||
int done;
|
||||
int column;
|
||||
int remote = 0;
|
||||
int any_valid;
|
||||
int invalid;
|
||||
char serial_line[8192];
|
||||
unsigned storage_size;
|
||||
int blocks;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "T:D:C:R", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
remote = 1;
|
||||
break;
|
||||
case 'C':
|
||||
channel = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tty) {
|
||||
if (remote)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleDongle");
|
||||
else
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleMetrum");
|
||||
}
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyACM0";
|
||||
cc = cc_usb_open(tty);
|
||||
if (!cc)
|
||||
exit(1);
|
||||
if (remote)
|
||||
cc_usb_open_remote(cc, channel);
|
||||
/* send a 'version' command followed by a 'log' command */
|
||||
cc_usb_printf(cc, "v\n");
|
||||
out = NULL;
|
||||
for (;;) {
|
||||
cc_usb_getline(cc, line, sizeof (line));
|
||||
if (sscanf(line, "serial-number %u", &serial_number) == 1)
|
||||
strcpy(serial_line, line);
|
||||
if (!strncmp(line, "software-version", 16))
|
||||
break;
|
||||
}
|
||||
if (!serial_number) {
|
||||
fprintf(stderr, "no serial number found\n");
|
||||
cc_usb_close(cc);
|
||||
exit(1);
|
||||
}
|
||||
cc_usb_printf(cc, "f\n");
|
||||
storage_size = 0;
|
||||
for (;;) {
|
||||
cc_usb_getline(cc, line, sizeof(line));
|
||||
if (sscanf(line, "Storage size: %u", &storage_size) == 1)
|
||||
break;
|
||||
}
|
||||
printf ("Serial number: %d Storage size: %u\n", serial_number, storage_size);
|
||||
if (storage_size)
|
||||
blocks = storage_size / 256;
|
||||
else
|
||||
blocks = 511;
|
||||
done = 0;
|
||||
column = 0;
|
||||
for (block = 0; !done && block < blocks; block++) {
|
||||
cc_usb_printf(cc, "e %x\n", block);
|
||||
if (column == 64) {
|
||||
putchar('\n');
|
||||
column = 0;
|
||||
}
|
||||
putchar('.'); fflush(stdout); column++;
|
||||
any_valid = 0;
|
||||
for (addr = 0; addr < 0x100;) {
|
||||
cc_usb_getline(cc, line, sizeof (line));
|
||||
if (sscanf(line, "00%x %x %x %x %x %x %x %x %x",
|
||||
&received_addr,
|
||||
&data[0], &data[1], &data[2], &data[3],
|
||||
&data[4], &data[5], &data[6], &data[7]) == 9)
|
||||
{
|
||||
if (received_addr != addr)
|
||||
fprintf(stderr, "data out of sync at 0x%x\n",
|
||||
block * 256 + received_addr);
|
||||
|
||||
if (log_checksum(data) != 0)
|
||||
fprintf (stderr, "invalid checksum at 0x%x\n",
|
||||
block * 256 + received_addr);
|
||||
else
|
||||
any_valid = 1;
|
||||
|
||||
cmd = data[0];
|
||||
tick = data[2] + (data[3] << 8);
|
||||
a = data[4] + (data[5] << 8);
|
||||
b = data[6] + (data[7] << 8);
|
||||
if (cmd == 'F') {
|
||||
flight = b;
|
||||
filename = cc_make_filename(serial_number, flight, "eeprom");
|
||||
printf ("Flight: %d\n", flight);
|
||||
printf ("File name: %s\n", filename);
|
||||
out = fopen (filename, "w");
|
||||
if (!out) {
|
||||
perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(out, "%s\n", serial_line);
|
||||
}
|
||||
|
||||
if (cmd == 'S' && a <= 8) {
|
||||
if (column) putchar('\n');
|
||||
printf("%s\n", state_names[a]);
|
||||
column = 0;
|
||||
}
|
||||
if (out) {
|
||||
fprintf(out, "%c %4x %4x %4x\n",
|
||||
cmd, tick, a, b);
|
||||
if (cmd == 'S' && a == 8) {
|
||||
fclose(out);
|
||||
out = NULL;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
addr += 8;
|
||||
}
|
||||
}
|
||||
if (!any_valid) {
|
||||
fclose(out);
|
||||
out = NULL;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
if (column)
|
||||
putchar('\n');
|
||||
if (out)
|
||||
fclose (out);
|
||||
cc_usb_close(cc);
|
||||
exit (0);
|
||||
}
|
12
ao-tools/ao-edit-telem/Makefile.am
Normal file
12
ao-tools/ao-edit-telem/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-edit-telem
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_edit_telem_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS)
|
||||
|
||||
ao_edit_telem_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_edit_telem_SOURCES = ao-edit-telem.c
|
||||
|
||||
man_MANS = ao-edit-telem.1
|
33
ao-tools/ao-edit-telem/ao-edit-telem.1
Normal file
33
ao-tools/ao-edit-telem/ao-edit-telem.1
Normal file
@@ -0,0 +1,33 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-EDIT-TELEM 1 "ao-edit-telem" ""
|
||||
.SH NAME
|
||||
ao-edit-telem \- Edit telemetry file, creating new telemetry stream
|
||||
.SH SYNOPSIS
|
||||
.B "ao-edit-telem"
|
||||
[\--lat=<pad-lat>]
|
||||
[\--lon=<pad-lon>]
|
||||
{flight.telem}
|
||||
.SH DESCRIPTION
|
||||
.I ao-edit-telem
|
||||
reads the specified telemetry log and produces a new telemetry log,
|
||||
changed as directed by the options provided.
|
||||
output.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
187
ao-tools/ao-edit-telem/ao-edit-telem.c
Normal file
187
ao-tools/ao-edit-telem/ao-edit-telem.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright © 2013 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "cc.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "lat", .has_arg = 1, .val = 'L' },
|
||||
{ .name = "lon", .has_arg = 1, .val = 'l' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--lat <pad-lat>] [--lon <pad-lon>]\n"
|
||||
"\t{flight-log} ...\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define bool(b) ((b) ? "true" : "false")
|
||||
|
||||
struct telem_ent {
|
||||
struct telem_ent *next;
|
||||
union ao_telemetry_all telem;
|
||||
};
|
||||
|
||||
static struct telem_ent *pad, **last = &pad;
|
||||
|
||||
static void
|
||||
save_telem(union ao_telemetry_all *telem)
|
||||
{
|
||||
struct telem_ent *t = malloc (sizeof *t);
|
||||
t->telem = *telem;
|
||||
t->next = NULL;
|
||||
*last = t;
|
||||
last = &t->next;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_telem(union ao_telemetry_all *telem)
|
||||
{
|
||||
char s[CC_TELEMETRY_BUFSIZE];
|
||||
|
||||
cc_telemetry_unparse(telem, s);
|
||||
printf("%s\n", s);
|
||||
}
|
||||
|
||||
double pad_lat = 0, pad_lon = 0;
|
||||
double target_pad_lat = 0, target_pad_lon = 0;
|
||||
double lat_off = 0, lon_off = 0;
|
||||
int pending = 1;
|
||||
|
||||
static void
|
||||
dump_saved(void);
|
||||
|
||||
static void
|
||||
doit(union ao_telemetry_all *telem)
|
||||
{
|
||||
double lat, lon;
|
||||
|
||||
switch (telem->generic.type) {
|
||||
case AO_TELEMETRY_SENSOR_TELEMETRUM:
|
||||
case AO_TELEMETRY_SENSOR_TELEMINI:
|
||||
case AO_TELEMETRY_SENSOR_TELENANO:
|
||||
if (telem->sensor.state > ao_flight_pad && pad) {
|
||||
pending = 0;
|
||||
if (target_pad_lat)
|
||||
lat_off = target_pad_lat - pad_lat;
|
||||
if (target_pad_lon)
|
||||
lon_off = target_pad_lon - pad_lon;
|
||||
dump_saved();
|
||||
}
|
||||
break;
|
||||
case AO_TELEMETRY_LOCATION: {
|
||||
lat = telem->location.latitude / 1.0e7;
|
||||
lon = telem->location.longitude / 1.0e7;
|
||||
if (pending) {
|
||||
if (telem->location.flags & (1 << 4)) {
|
||||
if (pad_lat) {
|
||||
pad_lat = pad_lat - pad_lat / 32 + lat / 32.0;
|
||||
pad_lon = pad_lon - pad_lon / 32 + lon / 32.0;
|
||||
} else {
|
||||
pad_lat = lat;
|
||||
pad_lon = lon;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lat += lat_off;
|
||||
lon += lon_off;
|
||||
if (lat > 90)
|
||||
lat = 90;
|
||||
if (lat < -90)
|
||||
lat = -90;
|
||||
while (lon > 180)
|
||||
lon -= 360;
|
||||
while (lon < -180)
|
||||
lon += 360;
|
||||
telem->location.latitude = lat * 1.0e7;
|
||||
telem->location.longitude = lon * 1.0e7;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_saved(void)
|
||||
{
|
||||
struct telem_ent *t, *n;
|
||||
|
||||
for (t = pad; t; t = n) {
|
||||
n = t->next;
|
||||
doit(&t->telem);
|
||||
dump_telem(&t->telem);
|
||||
free(t);
|
||||
}
|
||||
pad = NULL;
|
||||
last = &pad;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char line[80];
|
||||
int c, i, ret = 0;
|
||||
FILE *file;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "l:L:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'L':
|
||||
target_pad_lat = strtod(optarg, NULL);
|
||||
break;
|
||||
case 'l':
|
||||
target_pad_lon = strtod(optarg, NULL);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (!file) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
while (fgets(line, sizeof (line), file)) {
|
||||
union ao_telemetry_all telem;
|
||||
|
||||
if (cc_telemetry_parse(line, &telem)) {
|
||||
if ((telem.generic.status & (1 << 7)) == 0) {
|
||||
dump_telem(&telem);
|
||||
continue;
|
||||
}
|
||||
doit (&telem);
|
||||
if (pending)
|
||||
save_telem(&telem);
|
||||
else
|
||||
dump_telem(&telem);
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
12
ao-tools/ao-eeprom/Makefile.am
Normal file
12
ao-tools/ao-eeprom/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-eeprom
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_EEPROM_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_eeprom_DEPENDENCIES = $(AO_EEPROM_LIBS)
|
||||
|
||||
ao_eeprom_LDADD=$(AO_EEPROM_LIBS) -ljson-c -lm
|
||||
|
||||
ao_eeprom_SOURCES = ao-eeprom.c
|
||||
|
||||
man_MANS = ao-eeprom.1
|
49
ao-tools/ao-eeprom/ao-eeprom.1
Normal file
49
ao-tools/ao-eeprom/ao-eeprom.1
Normal file
@@ -0,0 +1,49 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-EEPROM 1 "ao-eeprom" ""
|
||||
.SH NAME
|
||||
ao-eeprom \- Analyze an eeprom log
|
||||
.SH SYNOPSIS
|
||||
.B "ao-eeprom"
|
||||
[\--raw]
|
||||
[\--csum]
|
||||
[\--verbose]
|
||||
[\--len <record-len>]
|
||||
{flight.eeprom} ...
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-r | --raw
|
||||
This option makes ao-eeprom dump the raw bytes of each
|
||||
log record in hex format.
|
||||
.TP
|
||||
\-c | --csum
|
||||
This option makes ao-eeprom dump records that have checksum errors. By default,
|
||||
ao-eeprom skips such records.
|
||||
\-v | --verbose
|
||||
This option makes ao-eeprom report when records are skipped due to
|
||||
checksum errors.
|
||||
\-l <record-len> | --len <record-len
|
||||
Specify the eeprom record length rather than letting ao-eeprom
|
||||
automatically determine it based on the file contents.
|
||||
.SH DESCRIPTION
|
||||
.I ao-eeprom
|
||||
reads the specified eeprom log and display the contents of each
|
||||
record.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
753
ao-tools/ao-eeprom/ao-eeprom.c
Normal file
753
ao-tools/ao-eeprom/ao-eeprom.c
Normal file
@@ -0,0 +1,753 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <ao-eeprom-read.h>
|
||||
#include <ao-atmosphere.h>
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "raw", .has_arg = 0, .val = 'r' },
|
||||
{ .name = "csum", .has_arg = 0, .val = 'c' },
|
||||
{ .name = "verbose", .has_arg = 0, .val = 'v' },
|
||||
{ .name = "len", .has_arg = 1, .val = 'l' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--raw] [--csum] [--verbose] [--len <record-len>] {flight.eeprom} ...\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static bool
|
||||
ao_csum_valid(uint8_t *d, int len)
|
||||
{
|
||||
uint8_t sum = 0x5a;
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
sum += d[i];
|
||||
return sum == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ao_ms5607(uint32_t pres, uint32_t temp, struct ao_eeprom *eeprom, bool is_ms5611)
|
||||
{
|
||||
struct ao_ms5607_sample ms5607_sample = { .pres = pres, .temp = temp };
|
||||
struct ao_ms5607_value ms5607_value;
|
||||
|
||||
ao_ms5607_convert(&ms5607_sample, &ms5607_value,
|
||||
&eeprom->ms5607_prom, is_ms5611);
|
||||
printf(" pres %9u %7.3f kPa %7.1f m temp %9u %6.2f °C",
|
||||
pres,
|
||||
ms5607_value.pres / 1000.0,
|
||||
ao_pressure_to_altitude(ms5607_value.pres),
|
||||
temp,
|
||||
ms5607_value.temp / 100.0);
|
||||
}
|
||||
|
||||
#define GRAVITY 9.80665
|
||||
|
||||
static void
|
||||
ao_accel(int16_t accel, struct ao_eeprom *eeprom)
|
||||
{
|
||||
double accel_2g = eeprom->config.accel_minus_g - eeprom->config.accel_plus_g;
|
||||
double accel_scale = GRAVITY * 2.0 / accel_2g;
|
||||
printf(" accel %6d %7.2f m/s²",
|
||||
accel, (eeprom->config.accel_plus_g - accel) * accel_scale);
|
||||
}
|
||||
|
||||
static const char *state_names[] = {
|
||||
"startup",
|
||||
"idle",
|
||||
"pad",
|
||||
"boost",
|
||||
"fast",
|
||||
"coast",
|
||||
"drogue",
|
||||
"main",
|
||||
"landed",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
#define NUM_STATE (sizeof state_names/sizeof state_names[0])
|
||||
|
||||
static const char *
|
||||
ao_state_name(uint16_t state)
|
||||
{
|
||||
if (state < NUM_STATE)
|
||||
return state_names[state];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
static void
|
||||
ao_state(uint16_t state, uint16_t reason)
|
||||
{
|
||||
printf(" state %5u %s reason %5u",
|
||||
state, ao_state_name(state), reason);
|
||||
}
|
||||
|
||||
static double
|
||||
ao_adc_to_volts(int16_t value, int16_t max_adc, double ref, double r1, double r2)
|
||||
{
|
||||
return ref * ((double) value / max_adc) * (r1 + r2) / r2;
|
||||
}
|
||||
|
||||
static void
|
||||
ao_volts(const char *name, int16_t value, int16_t max_adc, double ref, double r1, double r2)
|
||||
{
|
||||
printf(" %s %5d",
|
||||
name, value);
|
||||
if (r1 && r2 && ref)
|
||||
printf(" %6.3f V", ao_adc_to_volts(value, max_adc, ref, r1, r2));
|
||||
}
|
||||
|
||||
static double lb_to_n(double lb)
|
||||
{
|
||||
return lb / 0.22480894;
|
||||
}
|
||||
|
||||
static double psi_to_pa(double psi)
|
||||
{
|
||||
return psi * 6894.76;
|
||||
}
|
||||
|
||||
static double
|
||||
ao_volts_to_newtons(double volts)
|
||||
{
|
||||
/* this is a total guess */
|
||||
return lb_to_n(volts * 57.88645 * GRAVITY);
|
||||
}
|
||||
|
||||
static void
|
||||
ao_thrust(int16_t value, int16_t max_adc, double ref, double r1, double r2)
|
||||
{
|
||||
printf(" thrust %5d", value);
|
||||
if (r1 && r2 && ref) {
|
||||
double volts = ao_adc_to_volts(value, max_adc, ref, r1, r2);
|
||||
printf(" %6.3f V %8.1f N", volts, ao_volts_to_newtons(volts));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ao_pressure(int16_t value, int16_t max_adc, double ref, double r1, double r2, double sensor_range)
|
||||
{
|
||||
printf(" pressure %5d", value);
|
||||
if (r1 && r2 && ref) {
|
||||
double volts = ao_adc_to_volts(value, max_adc, ref, r1, r2);
|
||||
if (volts < 0.5) volts = 0.5;
|
||||
if (volts > 4.5) volts = 4.5;
|
||||
|
||||
double psi = (volts - 0.5) / 4.0 * sensor_range;
|
||||
double pa = psi_to_pa(psi);
|
||||
printf(" %9.3f kPa", pa / 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static uint16_t
|
||||
uint16(uint8_t *bytes, int off)
|
||||
{
|
||||
return (uint16_t) bytes[off] | (((uint16_t) bytes[off+1]) << 8);
|
||||
}
|
||||
|
||||
static int16_t
|
||||
int16(uint8_t *bytes, int off)
|
||||
{
|
||||
return (int16_t) uint16(bytes, off);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
uint32(uint8_t *bytes, int off)
|
||||
{
|
||||
return (uint32_t) bytes[off] | (((uint32_t) bytes[off+1]) << 8) |
|
||||
(((uint32_t) bytes[off+2]) << 16) |
|
||||
(((uint32_t) bytes[off+3]) << 24);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
int32(uint8_t *bytes, int off)
|
||||
{
|
||||
return (int32_t) uint32(bytes, off);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t
|
||||
uint24(uint8_t *bytes, int off)
|
||||
{
|
||||
return (uint32_t) bytes[off] | (((uint32_t) bytes[off+1]) << 8) |
|
||||
(((uint32_t) bytes[off+2]) << 16);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
int24(uint8_t *bytes, int off)
|
||||
{
|
||||
return (int32_t) uint24(bytes, off);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct ao_eeprom *eeprom;
|
||||
FILE *file;
|
||||
int c;
|
||||
bool raw = false;
|
||||
bool csum = false;
|
||||
bool verbose = false;
|
||||
int arg_len = 0;
|
||||
char *end;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "rcvl:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'r':
|
||||
raw = true;
|
||||
break;
|
||||
case 'c':
|
||||
csum = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'l':
|
||||
arg_len = strtol(optarg, &end, 0);
|
||||
if (!*optarg || *end)
|
||||
usage(argv[0]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (!file) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
eeprom = ao_eeprom_read(file);
|
||||
fclose(file);
|
||||
if (!eeprom) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
int len = 0;
|
||||
bool is_ms5611 = false;
|
||||
|
||||
int64_t current_tick = 0;
|
||||
int64_t first_tick = 0x7fffffffffffffffLL;
|
||||
|
||||
double sense_r1 = 0.0, sense_r2 = 0.0;
|
||||
double batt_r1 = 0.0, batt_r2 = 0.0;
|
||||
double adc_ref = 0.0;
|
||||
double pressure_sensor = 0.0;
|
||||
int16_t max_adc = 0;
|
||||
|
||||
switch (eeprom->log_format) {
|
||||
case AO_LOG_FORMAT_TELEMEGA_OLD:
|
||||
len = 32;
|
||||
break;
|
||||
case AO_LOG_FORMAT_EASYMINI1:
|
||||
len = 16;
|
||||
max_adc = 32767;
|
||||
if (eeprom->serial_number < 1000)
|
||||
adc_ref = 3.0;
|
||||
else
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = sense_r1 = 100e3;
|
||||
batt_r2 = sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMETRUM:
|
||||
len = 16;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 100e3;
|
||||
sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMINI2:
|
||||
len = 16;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEGPS:
|
||||
len = 32;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMEGA:
|
||||
len = 32;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 100e3;
|
||||
sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_DETHERM:
|
||||
len = 16;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMINI3:
|
||||
len = 16;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 100e3;
|
||||
sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEFIRETWO:
|
||||
len = 32;
|
||||
pressure_sensor = 2500.0;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
sense_r1 = batt_r1 = 5600;
|
||||
sense_r2 = batt_r2 = 10000;
|
||||
break;
|
||||
case AO_LOG_FORMAT_EASYMINI2:
|
||||
len = 16;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = sense_r1 = 100e3;
|
||||
batt_r2 = sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMEGA_3:
|
||||
len = 32;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 100e3;
|
||||
sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_EASYMEGA_2:
|
||||
len = 32;
|
||||
max_adc = 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 100e3;
|
||||
sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELESTATIC:
|
||||
len = 32;
|
||||
break;
|
||||
case AO_LOG_FORMAT_MICROPEAK2:
|
||||
len = 2;
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMEGA_4:
|
||||
case AO_LOG_FORMAT_TELEMEGA_5:
|
||||
case AO_LOG_FORMAT_TELEMEGA_6:
|
||||
len = 32;
|
||||
max_adc= 4095;
|
||||
adc_ref = 3.3;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 100e3;
|
||||
sense_r2 = 27e3;
|
||||
break;
|
||||
case AO_LOG_FORMAT_EASYMOTOR:
|
||||
len = 16;
|
||||
max_adc = 32767;
|
||||
adc_ref = 3.3;
|
||||
pressure_sensor = 1600.0;
|
||||
batt_r1 = 5600;
|
||||
batt_r2 = 10000;
|
||||
sense_r1 = 5600;
|
||||
sense_r2 = 10000;
|
||||
break;
|
||||
}
|
||||
if (arg_len)
|
||||
len = arg_len;
|
||||
if (len == 0) {
|
||||
fprintf(stderr, "Unknown eeprom format %d and no specified length\n",
|
||||
eeprom->log_format);
|
||||
exit(1);
|
||||
}
|
||||
if (verbose)
|
||||
printf("config major %d minor %d log format %d total %u len %d\n",
|
||||
eeprom->config.major,
|
||||
eeprom->config.minor,
|
||||
eeprom->log_format,
|
||||
eeprom->len,
|
||||
len);
|
||||
|
||||
uint32_t pos;
|
||||
for (pos = 0; pos < eeprom->len; pos += len) {
|
||||
int i;
|
||||
if (raw) {
|
||||
printf("%9u", pos);
|
||||
for (i = 0; i < len; i++)
|
||||
printf(" %02x", eeprom->data[pos + i]);
|
||||
} else {
|
||||
struct ao_log_mega *log_mega;
|
||||
struct ao_log_mini *log_mini;
|
||||
struct ao_log_metrum *log_metrum;
|
||||
struct ao_log_gps *log_gps;
|
||||
struct ao_log_firetwo *log_firetwo;
|
||||
struct ao_log_motor *log_motor;
|
||||
|
||||
if (!csum && !ao_csum_valid(&eeprom->data[pos], len)) {
|
||||
if (verbose)
|
||||
printf("\tchecksum error at %d\n", pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct ao_log_header *log_header = (struct ao_log_header *) &eeprom->data[pos];
|
||||
|
||||
if (first_tick == 0x7fffffffffffffffLL) {
|
||||
current_tick = first_tick = log_header->tick;
|
||||
} else {
|
||||
int16_t diff = (int16_t) (log_header->tick - (uint16_t) current_tick);
|
||||
|
||||
current_tick += diff;
|
||||
}
|
||||
printf("type %c tick %5u %6.2f S", log_header->type, log_header->tick, (current_tick - first_tick) / 100.0);
|
||||
|
||||
switch (eeprom->log_format) {
|
||||
case AO_LOG_FORMAT_TELEMEGA_OLD:
|
||||
case AO_LOG_FORMAT_TELEMEGA:
|
||||
case AO_LOG_FORMAT_TELEMEGA_3:
|
||||
case AO_LOG_FORMAT_EASYMEGA_2:
|
||||
case AO_LOG_FORMAT_TELEMEGA_4:
|
||||
case AO_LOG_FORMAT_TELEMEGA_5:
|
||||
case AO_LOG_FORMAT_TELEMEGA_6:
|
||||
log_mega = (struct ao_log_mega *) &eeprom->data[pos];
|
||||
switch (log_mega->type) {
|
||||
case AO_LOG_FLIGHT:
|
||||
printf(" serial %5u flight %5u ground_accel %6d ground_pres %9u kPa %7.1f %7.1f m",
|
||||
eeprom->serial_number,
|
||||
log_mega->u.flight.flight,
|
||||
log_mega->u.flight.ground_accel,
|
||||
log_mega->u.flight.ground_pres,
|
||||
log_mega->u.flight.ground_pres / 1000.0,
|
||||
ao_pressure_to_altitude(log_mega->u.flight.ground_pres));
|
||||
|
||||
printf(" along %6d aross %6d through %6d",
|
||||
log_mega->u.flight.ground_accel_along,
|
||||
log_mega->u.flight.ground_accel_across,
|
||||
log_mega->u.flight.ground_accel_through);
|
||||
printf(" roll %6d pitch %6d yaw %6d",
|
||||
log_mega->u.flight.ground_roll,
|
||||
log_mega->u.flight.ground_pitch,
|
||||
log_mega->u.flight.ground_yaw);
|
||||
break;
|
||||
case AO_LOG_STATE:
|
||||
ao_state(log_mega->u.state.state,
|
||||
log_mega->u.state.reason);
|
||||
break;
|
||||
case AO_LOG_SENSOR:
|
||||
ao_ms5607(log_mega->u.sensor.pres,
|
||||
log_mega->u.sensor.temp,
|
||||
eeprom, is_ms5611);
|
||||
printf(" accel_x %6d accel_y %6d accel_z %6d",
|
||||
log_mega->u.sensor.accel_x,
|
||||
log_mega->u.sensor.accel_y,
|
||||
log_mega->u.sensor.accel_z);
|
||||
printf (" gyro_x %6d gyro_y %6d gyro_z %6d",
|
||||
log_mega->u.sensor.gyro_x,
|
||||
log_mega->u.sensor.gyro_y,
|
||||
log_mega->u.sensor.gyro_z);
|
||||
printf (" mag_x %6d mag_y %6d mag_z %6d",
|
||||
log_mega->u.sensor.mag_x,
|
||||
log_mega->u.sensor.mag_y,
|
||||
log_mega->u.sensor.mag_z);
|
||||
ao_accel(log_mega->u.sensor.accel, eeprom);
|
||||
break;
|
||||
case AO_LOG_TEMP_VOLT:
|
||||
ao_volts("v_batt",
|
||||
log_mega->u.volt.v_batt,
|
||||
max_adc,
|
||||
adc_ref,
|
||||
batt_r1, batt_r2);
|
||||
ao_volts("v_pbatt",
|
||||
log_mega->u.volt.v_pbatt,
|
||||
max_adc,
|
||||
adc_ref,
|
||||
sense_r1, sense_r2);
|
||||
printf(" n_sense %1d",
|
||||
log_mega->u.volt.n_sense);
|
||||
for (i = 0; i < log_mega->u.volt.n_sense; i++) {
|
||||
char name[10];
|
||||
sprintf(name, "sense%d", i);
|
||||
ao_volts(name,
|
||||
log_mega->u.volt.sense[i],
|
||||
max_adc,
|
||||
adc_ref,
|
||||
sense_r1, sense_r2);
|
||||
}
|
||||
printf(" pyro %04x", log_mega->u.volt.pyro);
|
||||
break;
|
||||
case AO_LOG_GPS_TIME:
|
||||
printf(" lat %10.7f ° lon %10.7f ° alt %8d m",
|
||||
log_mega->u.gps.latitude / 10000000.0,
|
||||
log_mega->u.gps.longitude/ 10000000.0,
|
||||
(int32_t) (log_mega->u.gps.altitude_low |
|
||||
(log_mega->u.gps.altitude_high << 16)));
|
||||
printf(" time %02d:%02d:%02d %04d-%02d-%02d flags %02x",
|
||||
log_mega->u.gps.hour,
|
||||
log_mega->u.gps.minute,
|
||||
log_mega->u.gps.second,
|
||||
log_mega->u.gps.year + 2000,
|
||||
log_mega->u.gps.month,
|
||||
log_mega->u.gps.day,
|
||||
log_mega->u.gps.flags);
|
||||
printf(" course %3d ground_speed %5u climb_rate %6d pdop %3d hdop %3d vdop %3d mode %3d",
|
||||
log_mega->u.gps.course,
|
||||
log_mega->u.gps.ground_speed,
|
||||
log_mega->u.gps.climb_rate,
|
||||
log_mega->u.gps.pdop,
|
||||
log_mega->u.gps.hdop,
|
||||
log_mega->u.gps.vdop,
|
||||
log_mega->u.gps.mode);
|
||||
break;
|
||||
case AO_LOG_GPS_SAT:
|
||||
printf(" channels %2d",
|
||||
log_mega->u.gps_sat.channels);
|
||||
for (i = 0; i < 12; i++) {
|
||||
printf(" svid %3d c_n %2d",
|
||||
log_mega->u.gps_sat.sats[i].svid,
|
||||
log_mega->u.gps_sat.sats[i].c_n);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AO_LOG_FORMAT_EASYMINI1:
|
||||
case AO_LOG_FORMAT_EASYMINI2:
|
||||
case AO_LOG_FORMAT_TELEMINI2:
|
||||
case AO_LOG_FORMAT_TELEMINI3:
|
||||
log_mini = (struct ao_log_mini *) &eeprom->data[pos];
|
||||
switch (log_mini->type) {
|
||||
case AO_LOG_FLIGHT:
|
||||
printf(" serial %5u flight %5u ground_pres %9u kPa %7.1f %7.1f m",
|
||||
eeprom->serial_number,
|
||||
log_mini->u.flight.flight,
|
||||
log_mini->u.flight.ground_pres,
|
||||
log_mini->u.flight.ground_pres / 1000.0,
|
||||
ao_pressure_to_altitude(log_mini->u.flight.ground_pres));
|
||||
break;
|
||||
case AO_LOG_STATE:
|
||||
ao_state(log_mini->u.state.state,
|
||||
log_mini->u.state.reason);
|
||||
break;
|
||||
case AO_LOG_SENSOR:
|
||||
ao_ms5607(int24(log_mini->u.sensor.pres, 0),
|
||||
int24(log_mini->u.sensor.temp, 0),
|
||||
eeprom, is_ms5611);
|
||||
ao_volts("sense_a",
|
||||
log_mini->u.sensor.sense_a, max_adc,
|
||||
adc_ref, sense_r1, sense_r2);
|
||||
ao_volts("sense_m",
|
||||
log_mini->u.sensor.sense_m, max_adc,
|
||||
adc_ref, sense_r1, sense_r2);
|
||||
ao_volts("v_batt",
|
||||
log_mini->u.sensor.v_batt, max_adc,
|
||||
adc_ref, batt_r1, batt_r2);
|
||||
break;
|
||||
} /* */
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEMETRUM:
|
||||
log_metrum = (struct ao_log_metrum *) &eeprom->data[pos];
|
||||
switch (log_metrum->type) {
|
||||
case AO_LOG_FLIGHT:
|
||||
printf(" serial %5u flight %5u ground_accel %6d ground_pres %9u kPa %7.1f %7.1f m ground_temp %9u",
|
||||
eeprom->serial_number,
|
||||
log_metrum->u.flight.flight,
|
||||
log_metrum->u.flight.ground_accel,
|
||||
log_metrum->u.flight.ground_pres,
|
||||
log_metrum->u.flight.ground_pres / 1000.0,
|
||||
ao_pressure_to_altitude(log_metrum->u.flight.ground_pres),
|
||||
log_metrum->u.flight.ground_temp);
|
||||
break;
|
||||
case AO_LOG_SENSOR:
|
||||
ao_ms5607(log_metrum->u.sensor.pres,
|
||||
log_metrum->u.sensor.temp,
|
||||
eeprom, is_ms5611);
|
||||
ao_accel(log_metrum->u.sensor.accel, eeprom);
|
||||
break;
|
||||
case AO_LOG_TEMP_VOLT:
|
||||
ao_volts("v_batt",
|
||||
log_metrum->u.volt.v_batt, max_adc,
|
||||
adc_ref, batt_r1, batt_r2);
|
||||
ao_volts("sense_a",
|
||||
log_metrum->u.volt.sense_a, max_adc,
|
||||
adc_ref, sense_r1, sense_r2);
|
||||
ao_volts("sense_m",
|
||||
log_metrum->u.volt.sense_m, max_adc,
|
||||
adc_ref, sense_r1, sense_r2);
|
||||
break;
|
||||
case AO_LOG_DEPLOY:
|
||||
break;
|
||||
case AO_LOG_STATE:
|
||||
ao_state(log_metrum->u.state.state,
|
||||
log_metrum->u.state.reason);
|
||||
break;
|
||||
case AO_LOG_GPS_TIME:
|
||||
printf(" time %02d:%02d:%02d 20%02d-%02d-%02d flags %02x pdop %3u",
|
||||
log_metrum->u.gps_time.hour,
|
||||
log_metrum->u.gps_time.minute,
|
||||
log_metrum->u.gps_time.second,
|
||||
log_metrum->u.gps_time.year,
|
||||
log_metrum->u.gps_time.month,
|
||||
log_metrum->u.gps_time.day,
|
||||
log_metrum->u.gps_time.flags,
|
||||
log_metrum->u.gps_time.pdop);
|
||||
break;
|
||||
case AO_LOG_GPS_SAT:
|
||||
printf(" channels %2d more %1d",
|
||||
log_metrum->u.gps_sat.channels,
|
||||
log_metrum->u.gps_sat.more);
|
||||
for (i = 0; i < 4; i++) {
|
||||
printf(" svid %3d c_n %2d",
|
||||
log_metrum->u.gps_sat.sats[i].svid,
|
||||
log_metrum->u.gps_sat.sats[i].c_n);
|
||||
}
|
||||
break;
|
||||
case AO_LOG_GPS_POS:
|
||||
printf(" lat %10.7f° lon %10.7f° alt %8d m",
|
||||
log_metrum->u.gps.latitude / 10000000.0,
|
||||
log_metrum->u.gps.longitude/ 10000000.0,
|
||||
(int32_t) (log_metrum->u.gps.altitude_low |
|
||||
(log_metrum->u.gps.altitude_high << 16)));
|
||||
break;
|
||||
default:
|
||||
printf(" unknown");
|
||||
}
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEFIRETWO:
|
||||
log_firetwo = (struct ao_log_firetwo *) &eeprom->data[pos];
|
||||
switch (log_firetwo->type) {
|
||||
case AO_LOG_FLIGHT:
|
||||
printf(" serial %5u flight %5u",
|
||||
eeprom->serial_number,
|
||||
log_firetwo->u.flight.flight);
|
||||
break;
|
||||
case AO_LOG_STATE:
|
||||
ao_state(log_firetwo->u.state.state,
|
||||
log_firetwo->u.state.reason);
|
||||
break;
|
||||
case AO_LOG_SENSOR:
|
||||
ao_pressure(log_firetwo->u.sensor.pressure,
|
||||
max_adc, adc_ref,
|
||||
sense_r1, sense_r2,
|
||||
pressure_sensor);
|
||||
ao_thrust(log_firetwo->u.sensor.thrust,
|
||||
max_adc, adc_ref,
|
||||
sense_r1, sense_r2);
|
||||
for (i = 0; i < 4; i++) {
|
||||
char name[20];
|
||||
sprintf(name, "thermistor%d", i);
|
||||
ao_volts(name,
|
||||
log_firetwo->u.sensor.thermistor[i],
|
||||
max_adc, adc_ref,
|
||||
sense_r1, sense_r2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AO_LOG_FORMAT_TELEGPS:
|
||||
log_gps = (struct ao_log_gps *) &eeprom->data[pos];
|
||||
switch (log_gps->type) {
|
||||
case AO_LOG_GPS_TIME:
|
||||
printf(" lat %10.7f ° lon %10.7f ° alt %8d m",
|
||||
log_gps->u.gps.latitude / 10000000.0,
|
||||
log_gps->u.gps.longitude/ 10000000.0,
|
||||
(int32_t) (log_gps->u.gps.altitude_low |
|
||||
(log_gps->u.gps.altitude_high << 16)));
|
||||
printf(" time %02d:%02d:%02d %04d-%02d-%02d flags %02x",
|
||||
log_gps->u.gps.hour,
|
||||
log_gps->u.gps.minute,
|
||||
log_gps->u.gps.second,
|
||||
log_gps->u.gps.year + 2000,
|
||||
log_gps->u.gps.month,
|
||||
log_gps->u.gps.day,
|
||||
log_gps->u.gps.flags);
|
||||
printf(" course %3d ground_speed %5u climb_rate %6d pdop %3d hdop %3d vdop %3d mode %3d",
|
||||
log_gps->u.gps.course,
|
||||
log_gps->u.gps.ground_speed,
|
||||
log_gps->u.gps.climb_rate,
|
||||
log_gps->u.gps.pdop,
|
||||
log_gps->u.gps.hdop,
|
||||
log_gps->u.gps.vdop,
|
||||
log_gps->u.gps.mode);
|
||||
break;
|
||||
case AO_LOG_GPS_SAT:
|
||||
printf(" channels %2d",
|
||||
log_gps->u.gps_sat.channels);
|
||||
for (i = 0; i < 12; i++) {
|
||||
printf(" svid %3d c_n %2d",
|
||||
log_gps->u.gps_sat.sats[i].svid,
|
||||
log_gps->u.gps_sat.sats[i].c_n);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf (" unknown");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AO_LOG_FORMAT_EASYMOTOR:
|
||||
log_motor = (struct ao_log_motor *) &eeprom->data[pos];
|
||||
switch (log_motor->type) {
|
||||
case AO_LOG_FLIGHT:
|
||||
printf(" serial %5u flight %5u ground_accel %6d",
|
||||
eeprom->serial_number,
|
||||
log_motor->u.flight.flight,
|
||||
log_motor->u.flight.ground_accel);
|
||||
printf(" along %6d aross %6d through %6d",
|
||||
log_motor->u.flight.ground_accel_along,
|
||||
log_motor->u.flight.ground_accel_across,
|
||||
log_motor->u.flight.ground_accel_through);
|
||||
ao_volts("ground pressure",
|
||||
log_motor->u.flight.ground_motor_pressure,
|
||||
max_adc, adc_ref,
|
||||
sense_r1, sense_r2);
|
||||
break;
|
||||
case AO_LOG_STATE:
|
||||
ao_state(log_motor->u.state.state,
|
||||
log_motor->u.state.reason);
|
||||
break;
|
||||
case AO_LOG_SENSOR:
|
||||
ao_volts("pressure",
|
||||
log_motor->u.sensor.pressure,
|
||||
max_adc, adc_ref,
|
||||
sense_r1, sense_r2);
|
||||
ao_volts("v_batt",
|
||||
log_motor->u.sensor.v_batt,
|
||||
max_adc,
|
||||
adc_ref, batt_r1, batt_r2);
|
||||
printf(" accel %6d",
|
||||
log_motor->u.sensor.accel);
|
||||
printf(" along %6d aross %6d through %6d",
|
||||
log_motor->u.sensor.accel_along,
|
||||
log_motor->u.sensor.accel_across,
|
||||
log_motor->u.sensor.accel_through);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AO_LOG_FORMAT_DETHERM:
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
12
ao-tools/ao-elftohex/Makefile.am
Normal file
12
ao-tools/ao-elftohex/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-elftohex
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_ELFTOHEX_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_elftohex_DEPENDENCIES = $(AO_ELFTOHEX_LIBS)
|
||||
|
||||
ao_elftohex_LDADD=$(AO_ELFTOHEX_LIBS) -lelf
|
||||
|
||||
ao_elftohex_SOURCES=ao-elftohex.c
|
||||
|
||||
man_MANS = ao-elftohex.1
|
43
ao-tools/ao-elftohex/ao-elftohex.1
Normal file
43
ao-tools/ao-elftohex/ao-elftohex.1
Normal file
@@ -0,0 +1,43 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LOAD 1 "ao-elftohex" ""
|
||||
.SH NAME
|
||||
ao-elftohex \- convert programs to IHX format
|
||||
.SH SYNOPSIS
|
||||
.B "ao-elftohex"
|
||||
[\--output-\fIoutput.ihx\fP]
|
||||
[\--verbose]
|
||||
\fIinput.elf ...\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-elftohex
|
||||
reads the specified .elf files and writes out a .ihx version.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\--output=\fIoutput.ihx\fP
|
||||
This specifies the output file (default is stdout)
|
||||
.TP
|
||||
\--verbose
|
||||
Dumps some debug information.
|
||||
.TP
|
||||
\--nosym
|
||||
Excluded symbol table information from the resulting file. This
|
||||
information is a non-standard extension supported by the Altus Metrum
|
||||
tools.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
134
ao-tools/ao-elftohex/ao-elftohex.c
Normal file
134
ao-tools/ao-elftohex/ao-elftohex.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright © 2013 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "ao-hex.h"
|
||||
#include "ao-elf.h"
|
||||
#include "ao-verbose.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "verbose", .has_arg = 1, .val = 'v' },
|
||||
{ .name = "output", .has_arg = 1, .val = 'o' },
|
||||
{ .name = "nosym", .has_arg = 0, .val = 'n' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--verbose=<level>] [--output=<output.ihx>] <input.elf>\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
ends_with(char *whole, char *suffix)
|
||||
{
|
||||
int whole_len = strlen(whole);
|
||||
int suffix_len = strlen(suffix);
|
||||
|
||||
if (suffix_len > whole_len)
|
||||
return 0;
|
||||
return strcmp(whole + whole_len - suffix_len, suffix) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *input = NULL;
|
||||
char *output = NULL;
|
||||
struct ao_hex_image *full_image = NULL;
|
||||
struct ao_sym *file_symbols = NULL;
|
||||
int num_file_symbols;
|
||||
FILE *file;
|
||||
int c;
|
||||
int i;
|
||||
int nosym = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "nv:o:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'o':
|
||||
output = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
ao_verbose = (int) strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'n':
|
||||
nosym = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
usage(argv[0]);
|
||||
|
||||
for (i = optind; i < argc; i++) {
|
||||
struct ao_hex_image *image;
|
||||
|
||||
input = argv[i];
|
||||
|
||||
free(file_symbols);
|
||||
num_file_symbols = 0;
|
||||
if (ends_with (input, ".ihx"))
|
||||
image = ao_hex_load(input, &file_symbols, &num_file_symbols);
|
||||
else
|
||||
image = ao_load_elf(input, &file_symbols, &num_file_symbols);
|
||||
|
||||
if (!image) {
|
||||
fprintf(stderr, "Failed to load %s\n", input);
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (nosym) {
|
||||
free(file_symbols);
|
||||
file_symbols = NULL;
|
||||
num_file_symbols = 0;
|
||||
}
|
||||
|
||||
if (full_image) {
|
||||
full_image = ao_hex_image_cat(full_image, image);
|
||||
if (!full_image) {
|
||||
fprintf(stderr, "Can't merge image %s\n", input);
|
||||
usage(argv[0]);
|
||||
}
|
||||
} else
|
||||
full_image = image;
|
||||
}
|
||||
|
||||
if (!output)
|
||||
file = stdout;
|
||||
else {
|
||||
file = fopen(output, "w");
|
||||
if (!file) {
|
||||
perror(output);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ao_hex_save(file, full_image, file_symbols, num_file_symbols)) {
|
||||
fprintf(stderr, "%s: failed to write hex file\n", output ? output : "<stdout>");
|
||||
if (output)
|
||||
unlink(output);
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
3
ao-tools/ao-flash/Makefile.am
Normal file
3
ao-tools/ao-flash/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
bin_SCRIPTS=ao-flash-stm ao-flash-lpc ao-flash-stm32f0x ao-reset-lpc ao-flash-samd21 ao-flash-stm32f1
|
||||
|
||||
man_MANS = ao-flash-stm.1 ao-flash-lpc.1 ao-flash-stm32f0x.1 ao-reset-lpc.1 ao-flash-samd21.1 ao-flash-stm32f1.1
|
17
ao-tools/ao-flash/ao-flash-lpc
Executable file
17
ao-tools/ao-flash/ao-flash-lpc
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
case "$#" in
|
||||
0)
|
||||
echo "usage: $0 <filename> ..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
cmds=/tmp/flash$$
|
||||
trap "rm $cmds" 0 1 15
|
||||
file="$1"
|
||||
echo "program $file reset" > $cmds
|
||||
openocd \
|
||||
-f interface/stlink-v2.cfg \
|
||||
-f target/lpc11xx.cfg \
|
||||
-c 'adapter speed 1000' \
|
||||
-f $cmds \
|
||||
-c shutdown
|
36
ao-tools/ao-flash/ao-flash-lpc.1
Normal file
36
ao-tools/ao-flash/ao-flash-lpc.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-FLASH-LPC 1 "ao-flash-lpc" ""
|
||||
.SH NAME
|
||||
ao-flash-lpc \- flash a program to an LPC11U14-based AltOS device using openocd
|
||||
.SH SYNOPSIS
|
||||
.B "ao-flash-lpc"
|
||||
\fIfile.elf\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-flash-lpc
|
||||
loads the specified .elf file into the target device flash memory.
|
||||
.SH USAGE
|
||||
.I ao-flash-lpc
|
||||
is a simple script that passes the correct arguments to openocd to
|
||||
load a file into the target device via a connected STlink
|
||||
debugging dongle.
|
||||
.SH "SEE ALSO"
|
||||
openocd(1)
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
19
ao-tools/ao-flash/ao-flash-samd21
Executable file
19
ao-tools/ao-flash/ao-flash-samd21
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
case "$#" in
|
||||
1)
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 <filename> ..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
openocd -f interface/stlink.cfg \
|
||||
-c 'transport select hla_swd' \
|
||||
-c 'set CHIPNAME at91samd21g18' \
|
||||
-c 'set CPUTAPID 0x0bc11477' \
|
||||
-f target/at91samdXX.cfg \
|
||||
-c init \
|
||||
-c 'reset halt' \
|
||||
-c 'at91samd bootloader 0' \
|
||||
-c "program $1 verify reset" \
|
||||
-c "shutdown"
|
36
ao-tools/ao-flash/ao-flash-samd21.1
Normal file
36
ao-tools/ao-flash/ao-flash-samd21.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.\"
|
||||
.\" Copyright © 2022 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-FLASH-LPC 1 "ao-flash-samd21" ""
|
||||
.SH NAME
|
||||
ao-flash-samd21 \- flash a program to an SAMD21-based AltOS device using openocd
|
||||
.SH SYNOPSIS
|
||||
.B "ao-flash-samd21"
|
||||
\fIfile.elf\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-flash-samd21
|
||||
loads the specified .elf file into the target device flash memory.
|
||||
.SH USAGE
|
||||
.I ao-flash-samd21
|
||||
is a simple script that passes the correct arguments to openocd to
|
||||
load a file into the target device via a connected STlink
|
||||
debugging dongle.
|
||||
.SH "SEE ALSO"
|
||||
openocd(1)
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
16
ao-tools/ao-flash/ao-flash-stm
Executable file
16
ao-tools/ao-flash/ao-flash-stm
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
case "$#" in
|
||||
0)
|
||||
echo "usage: $0 <filename> ..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
cmds=/tmp/flash$$
|
||||
trap "rm $cmds" 0 1 15
|
||||
file="$1"
|
||||
echo "program $file reset" > $cmds
|
||||
openocd \
|
||||
-f interface/stlink-v2.cfg \
|
||||
-f target/stm32l1.cfg \
|
||||
-f $cmds \
|
||||
-c shutdown
|
38
ao-tools/ao-flash/ao-flash-stm.1
Normal file
38
ao-tools/ao-flash/ao-flash-stm.1
Normal file
@@ -0,0 +1,38 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-FLASH-STM 1 "ao-flash-stm" ""
|
||||
.SH NAME
|
||||
ao-flash-stm \- flash a program to an STM32-based AltOS device using st-flash
|
||||
.SH SYNOPSIS
|
||||
.B "ao-flash-stm"
|
||||
\fIfile.elf\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-flash-stm
|
||||
loads the specified .elf file into the target device flash memory.
|
||||
.SH USAGE
|
||||
.I ao-flash-stm
|
||||
converts the specified .elf file into a raw binary file and then uses
|
||||
st-flash to load it into the target device via a connected STlink
|
||||
debugging dongle. If st-flash is not available,
|
||||
.I ao-flash-stm
|
||||
will emit an error message and terminate.
|
||||
.SH "SEE ALSO"
|
||||
st-flash(1)
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
16
ao-tools/ao-flash/ao-flash-stm32f0x
Executable file
16
ao-tools/ao-flash/ao-flash-stm32f0x
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
case "$#" in
|
||||
0)
|
||||
echo "usage: $0 <filename> ..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
cmds=/tmp/flash$$
|
||||
trap "rm $cmds" 0 1 15
|
||||
file="$1"
|
||||
echo "program $file verify reset" > $cmds
|
||||
openocd \
|
||||
-f interface/stlink.cfg \
|
||||
-f target/stm32f0x.cfg \
|
||||
-f $cmds \
|
||||
-c shutdown
|
36
ao-tools/ao-flash/ao-flash-stm32f0x.1
Normal file
36
ao-tools/ao-flash/ao-flash-stm32f0x.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-FLASH-LPC 1 "ao-flash-stm32f0x" ""
|
||||
.SH NAME
|
||||
ao-flash-stm32f0x \- flash a program to a STM32F0x-based AltOS device using openocd
|
||||
.SH SYNOPSIS
|
||||
.B "ao-flash-stm32f0x"
|
||||
\fIfile.elf\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-flash-stm32f0x
|
||||
loads the specified .elf file into the target device flash memory.
|
||||
.SH USAGE
|
||||
.I ao-flash-stm32f0x
|
||||
is a simple script that passes the correct arguments to openocd to
|
||||
load a file into the target device via a connected STlink
|
||||
debugging dongle.
|
||||
.SH "SEE ALSO"
|
||||
openocd(1)
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
15
ao-tools/ao-flash/ao-flash-stm32f1
Executable file
15
ao-tools/ao-flash/ao-flash-stm32f1
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
case "$#" in
|
||||
0)
|
||||
echo "usage: $0 <filename> ..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
openocd \
|
||||
-f interface/stlink.cfg \
|
||||
-c 'transport select hla_swd' \
|
||||
-f target/stm32f1x.cfg \
|
||||
-c init \
|
||||
-c 'reset halt' \
|
||||
-c "program $1 verify reset" \
|
||||
-c 'shutdown'
|
36
ao-tools/ao-flash/ao-flash-stm32f1.1
Normal file
36
ao-tools/ao-flash/ao-flash-stm32f1.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.\"
|
||||
.\" Copyright © 2022 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-FLASH-LPC 1 "ao-flash-stm32f1" ""
|
||||
.SH NAME
|
||||
ao-flash-stm32f1 \- flash a program to an STM32F1x-based AltOS device using openocd
|
||||
.SH SYNOPSIS
|
||||
.B "ao-flash-stm32f1"
|
||||
\fIfile.elf\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-flash-stm32f1
|
||||
loads the specified .elf file into the target device flash memory.
|
||||
.SH USAGE
|
||||
.I ao-flash-stm32f1
|
||||
is a simple script that passes the correct arguments to openocd to
|
||||
load a file into the target device via a connected STlink
|
||||
debugging dongle.
|
||||
.SH "SEE ALSO"
|
||||
openocd(1)
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
9
ao-tools/ao-flash/ao-reset-lpc
Executable file
9
ao-tools/ao-flash/ao-reset-lpc
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
cmds=/tmp/flash$$
|
||||
trap "rm $cmds" 0 1 15
|
||||
echo "reset" > $cmds
|
||||
openocd \
|
||||
-f interface/stlink-v2.cfg \
|
||||
-f target/lpc11xx.cfg \
|
||||
-f $cmds \
|
||||
-c shutdown
|
35
ao-tools/ao-flash/ao-reset-lpc.1
Normal file
35
ao-tools/ao-flash/ao-reset-lpc.1
Normal file
@@ -0,0 +1,35 @@
|
||||
.\"
|
||||
.\" Copyright © 2018 Bdale Garbee <bdale@gag.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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-RESET-LPC 1 "ao-reset-lpc" ""
|
||||
.SH NAME
|
||||
ao-reset-lpc \- reset an LPC11U14-based AltOS device using openocd
|
||||
.SH SYNOPSIS
|
||||
.B "ao-reset-lpc"
|
||||
.SH DESCRIPTION
|
||||
.I ao-reset-lpc
|
||||
resets the target device.
|
||||
.SH USAGE
|
||||
.I ao-reset-lpc
|
||||
is a simple script that passes the correct arguments to openocd to
|
||||
reset the target device via a connected STlink debugging dongle.
|
||||
.SH "SEE ALSO"
|
||||
openocd(1)
|
||||
.SH AUTHOR
|
||||
Bdale Garbee
|
||||
|
12
ao-tools/ao-list/Makefile.am
Normal file
12
ao-tools/ao-list/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-list
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_LIST_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_list_DEPENDENCIES = $(AO_LIST_LIBS)
|
||||
|
||||
ao_list_LDADD=$(AO_LIST_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_list_SOURCES = ao-list.c
|
||||
|
||||
man_MANS = ao-list.1
|
32
ao-tools/ao-list/ao-list.1
Normal file
32
ao-tools/ao-list/ao-list.1
Normal file
@@ -0,0 +1,32 @@
|
||||
/.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LIST 1 "ao-list" ""
|
||||
.SH NAME
|
||||
ao-list \- List connected AltOS devices
|
||||
.SH SYNOPSIS
|
||||
.B "ao-list"
|
||||
.SH DESCRIPTION
|
||||
.I ao-list
|
||||
scans the attached USB devices, locates those running AltOS and
|
||||
displays their product name and serial number along with the tty
|
||||
device associated with the serial port over USB provided by AltOS.
|
||||
.SH USAGE
|
||||
.I ao-list
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
42
ao-tools/ao-list/ao-list.c
Normal file
42
ao-tools/ao-list/ao-list.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "cc.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct cc_usbdevs *devs;
|
||||
struct cc_usbdev *dev;
|
||||
int i;
|
||||
|
||||
devs = cc_usbdevs_scan(TRUE);
|
||||
if (devs) {
|
||||
for (i = 0; i < devs->ndev; i++) {
|
||||
dev = devs->dev[i];
|
||||
printf ("%-20.20s %6d %s\n",
|
||||
dev->product, dev->serial, dev->tty ? dev->tty : "(none)");
|
||||
}
|
||||
cc_usbdevs_free(devs);
|
||||
}
|
||||
return 0;
|
||||
}
|
12
ao-tools/ao-load/Makefile.am
Normal file
12
ao-tools/ao-load/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-load
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_LOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_load_DEPENDENCIES = $(AO_LOAD_LIBS)
|
||||
|
||||
ao_load_LDADD=$(AO_LOAD_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_load_SOURCES = ao-load.c
|
||||
|
||||
man_MANS = ao-load.1
|
73
ao-tools/ao-load/ao-load.1
Normal file
73
ao-tools/ao-load/ao-load.1
Normal file
@@ -0,0 +1,73 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LOAD 1 "ao-load" ""
|
||||
.SH NAME
|
||||
ao-load \- flash a program to a AltOS device
|
||||
.SH SYNOPSIS
|
||||
.B "ao-load"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\--cal \fIradio-calibration\fP]
|
||||
\fIfile.ihx\fP
|
||||
\fIdevice serial number\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-load
|
||||
loads the specified .ihx file into the target device flash memory,
|
||||
customizing the AltOS image with the specified serial number.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
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
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMetrum:2
|
||||
.br
|
||||
TeleMetrum
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\-c radio-calibration | --cal radio-calibration
|
||||
This programs the radio calibration value into the image for hardware
|
||||
which doesn't have any eeprom storage for this value. The value here
|
||||
can be computed given the current radio calibration value, the
|
||||
measured frequency and the desired frequency:
|
||||
.IP
|
||||
cal' = cal * (desired/measured)
|
||||
.IP
|
||||
The default calibration value is 1186611.
|
||||
.SH USAGE
|
||||
.I ao-load
|
||||
reads the specified .ihx file into memory, locates the matching .map
|
||||
file and edits the image to customize it using the specified serial
|
||||
number. It then connects to the specified target device and writes the
|
||||
program to the target device flash memory.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
286
ao-tools/ao-load/ao-load.c
Normal file
286
ao-tools/ao-load/ao-load.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright © 2008 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "ccdbg.h"
|
||||
#include "cc.h"
|
||||
|
||||
#define AO_USB_DESC_STRING 3
|
||||
|
||||
static struct sym {
|
||||
unsigned addr;
|
||||
char *name;
|
||||
int required;
|
||||
} ao_symbols[] = {
|
||||
{ 0, "_ao_serial_number", 1 },
|
||||
#define AO_SERIAL_NUMBER (ao_symbols[0].addr)
|
||||
{ 0, "_ao_usb_descriptors", 0 },
|
||||
#define AO_USB_DESCRIPTORS (ao_symbols[1].addr)
|
||||
{ 0, "_ao_radio_cal", 1 },
|
||||
#define AO_RADIO_CAL (ao_symbols[2].addr)
|
||||
};
|
||||
|
||||
#define NUM_SYMBOLS 3
|
||||
#define NUM_REQUIRED_SYMBOLS 2
|
||||
|
||||
static int
|
||||
find_symbols(FILE *map)
|
||||
{
|
||||
char line[2048];
|
||||
char *addr, *addr_end;
|
||||
char *name;
|
||||
char *save;
|
||||
char *colon;
|
||||
unsigned long a;
|
||||
int s;
|
||||
int required = 0;
|
||||
|
||||
while (fgets(line, sizeof(line), map) != NULL) {
|
||||
line[sizeof(line)-1] = '\0';
|
||||
addr = strtok_r(line, " \t\n", &save);
|
||||
if (!addr)
|
||||
continue;
|
||||
name = strtok_r(NULL, " \t\n", &save);
|
||||
if (!name)
|
||||
continue;
|
||||
colon = strchr (addr, ':');
|
||||
if (!colon)
|
||||
continue;
|
||||
a = strtoul(colon+1, &addr_end, 16);
|
||||
if (a == ULONG_MAX || addr_end == addr)
|
||||
continue;
|
||||
for (s = 0; s < NUM_SYMBOLS; s++)
|
||||
if (!strcmp(ao_symbols[s].name, name)) {
|
||||
ao_symbols[s].addr = (unsigned) a;
|
||||
if (ao_symbols[s].required)
|
||||
++required;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return required >= NUM_REQUIRED_SYMBOLS;
|
||||
}
|
||||
|
||||
static int
|
||||
rewrite(struct ao_hex_image *image, unsigned addr, char *data, int len)
|
||||
{
|
||||
int i;
|
||||
if (addr < image->address || image->address + image->length < addr + len)
|
||||
return 0;
|
||||
printf("rewrite %04x:", addr);
|
||||
for (i = 0; i < len; i++)
|
||||
printf (" %02x", image->data[addr - image->address + i]);
|
||||
printf(" ->");
|
||||
for (i = 0; i < len; i++)
|
||||
printf (" %02x", data[i]);
|
||||
printf("\n");
|
||||
memcpy(image->data + addr - image->address, data, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "cal", .has_arg = 1, .val = 'c' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--tty=<tty-name>] [--device=<device-name>] [--cal=<radio-cal>] file.ihx serial-number\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct ccdbg *dbg;
|
||||
struct ao_hex_file *hex;
|
||||
struct ao_hex_image *image;
|
||||
char *filename;
|
||||
FILE *file;
|
||||
FILE *map;
|
||||
char *serial_string;
|
||||
unsigned int serial;
|
||||
char *mapname, *dot;
|
||||
char *serial_ucs2;
|
||||
int serial_ucs2_len;
|
||||
char serial_int[2];
|
||||
unsigned int s;
|
||||
int i;
|
||||
int string_num;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
uint32_t cal = 0;
|
||||
char cal_int[4];
|
||||
char *cal_end;
|
||||
int c;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "T:D:c:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
cal = strtoul(optarg, &cal_end, 10);
|
||||
if (cal_end == optarg || *cal_end != '\0')
|
||||
usage(argv[0]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
filename = argv[optind];
|
||||
if (filename == NULL)
|
||||
usage(argv[0]);
|
||||
mapname = strdup(filename);
|
||||
dot = strrchr(mapname, '.');
|
||||
if (!dot || strcmp(dot, ".ihx") != 0)
|
||||
usage(argv[0]);
|
||||
strcpy(dot, ".map");
|
||||
|
||||
serial_string = argv[optind + 1];
|
||||
if (serial_string == NULL)
|
||||
usage(argv[0]);
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
map = fopen(mapname, "r");
|
||||
if (!map) {
|
||||
perror(mapname);
|
||||
exit(1);
|
||||
}
|
||||
if (!find_symbols(map)) {
|
||||
fprintf(stderr, "Cannot find symbols in \"%s\"\n", mapname);
|
||||
exit(1);
|
||||
}
|
||||
fclose(map);
|
||||
|
||||
hex = ao_hex_file_read(file, filename);
|
||||
fclose(file);
|
||||
if (!hex) {
|
||||
perror(filename);
|
||||
exit (1);
|
||||
}
|
||||
image = ao_hex_image_create(hex);
|
||||
if (!image) {
|
||||
fprintf(stderr, "image create failed\n");
|
||||
exit (1);
|
||||
}
|
||||
ao_hex_file_free(hex);
|
||||
|
||||
serial = strtoul(serial_string, NULL, 0);
|
||||
if (!serial)
|
||||
usage(argv[0]);
|
||||
|
||||
serial_int[0] = serial & 0xff;
|
||||
serial_int[1] = (serial >> 8) & 0xff;
|
||||
|
||||
if (!rewrite(image, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) {
|
||||
fprintf(stderr, "Cannot rewrite serial integer at %04x\n",
|
||||
AO_SERIAL_NUMBER);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (AO_USB_DESCRIPTORS) {
|
||||
unsigned usb_descriptors;
|
||||
usb_descriptors = AO_USB_DESCRIPTORS - image->address;
|
||||
string_num = 0;
|
||||
while (image->data[usb_descriptors] != 0 && usb_descriptors < image->length) {
|
||||
if (image->data[usb_descriptors+1] == AO_USB_DESC_STRING) {
|
||||
++string_num;
|
||||
if (string_num == 4)
|
||||
break;
|
||||
}
|
||||
usb_descriptors += image->data[usb_descriptors];
|
||||
}
|
||||
if (usb_descriptors >= image->length || image->data[usb_descriptors] == 0 ) {
|
||||
fprintf(stderr, "Cannot rewrite serial string at %04x\n", AO_USB_DESCRIPTORS);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
serial_ucs2_len = image->data[usb_descriptors] - 2;
|
||||
serial_ucs2 = malloc(serial_ucs2_len);
|
||||
if (!serial_ucs2) {
|
||||
fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len);
|
||||
exit(1);
|
||||
}
|
||||
s = serial;
|
||||
for (i = serial_ucs2_len / 2; i; i--) {
|
||||
serial_ucs2[i * 2 - 1] = 0;
|
||||
serial_ucs2[i * 2 - 2] = (s % 10) + '0';
|
||||
s /= 10;
|
||||
}
|
||||
if (!rewrite(image, usb_descriptors + 2 + image->address, serial_ucs2, serial_ucs2_len))
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (cal) {
|
||||
cal_int[0] = cal & 0xff;
|
||||
cal_int[1] = (cal >> 8) & 0xff;
|
||||
cal_int[2] = (cal >> 16) & 0xff;
|
||||
cal_int[3] = (cal >> 24) & 0xff;
|
||||
if (!AO_RADIO_CAL) {
|
||||
fprintf(stderr, "Cannot find radio calibration location in image\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!rewrite(image, AO_RADIO_CAL, cal_int, sizeof (cal_int))) {
|
||||
fprintf(stderr, "Cannot rewrite radio calibration at %04x\n", AO_RADIO_CAL);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TIDongle");
|
||||
dbg = ccdbg_open(tty);
|
||||
if (!dbg)
|
||||
exit (1);
|
||||
|
||||
ccdbg_add_debug(CC_DEBUG_FLASH);
|
||||
|
||||
ccdbg_debug_mode(dbg);
|
||||
ccdbg_halt(dbg);
|
||||
if (image->address == 0xf000) {
|
||||
printf("Loading %d bytes to execute from RAM\n",
|
||||
image->length);
|
||||
ccdbg_write_hex_image(dbg, image, 0);
|
||||
} else if (image->address == 0x0000) {
|
||||
printf("Loading %d bytes to execute from FLASH\n",
|
||||
image->length);
|
||||
ccdbg_flash_hex_image(dbg, image);
|
||||
} else {
|
||||
printf("Cannot load code to 0x%04x\n",
|
||||
image->address);
|
||||
ao_hex_image_free(image);
|
||||
ccdbg_close(dbg);
|
||||
exit(1);
|
||||
}
|
||||
ccdbg_set_pc(dbg, image->address);
|
||||
ccdbg_resume(dbg);
|
||||
ccdbg_close(dbg);
|
||||
exit (0);
|
||||
}
|
1
ao-tools/ao-makebin/.gitignore
vendored
Normal file
1
ao-tools/ao-makebin/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-makebin
|
12
ao-tools/ao-makebin/Makefile.am
Normal file
12
ao-tools/ao-makebin/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-makebin
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_ELFTOHEX_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_makebin_DEPENDENCIES = $(AO_ELFTOHEX_LIBS)
|
||||
|
||||
ao_makebin_LDADD=$(AO_ELFTOHEX_LIBS) -lelf
|
||||
|
||||
ao_makebin_SOURCES=ao-makebin.c
|
||||
|
||||
man_MANS = ao-makebin.1
|
47
ao-tools/ao-makebin/ao-makebin.1
Normal file
47
ao-tools/ao-makebin/ao-makebin.1
Normal file
@@ -0,0 +1,47 @@
|
||||
.\"
|
||||
.\" Copyright © 2013 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LOAD 1 "ao-makebin" ""
|
||||
.SH NAME
|
||||
ao-makebin \- construct raw binary file or DFU image from collection of ELF files
|
||||
.SH SYNOPSIS
|
||||
.B "ao-makebin"
|
||||
[\--base=\fIbase-address\fP]
|
||||
[\--output=\fIoutput.bin\fP]
|
||||
[\--dfu]
|
||||
[\--verbose]
|
||||
\fIinput.elf ...\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-makebin
|
||||
reads the specified .elf files and writes out a raw binary flash image
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\--base=\fIbase-address\fP
|
||||
This specifies the target address for the first byte of the file (default is 0)
|
||||
.TP
|
||||
\--output=\fIoutput.bin\fP
|
||||
This specifies the output file (default is stdout)
|
||||
.TP
|
||||
\--dfu
|
||||
Creates a DFU file (as documented by ST's UM0391 user manual) instead
|
||||
of a raw binary file.
|
||||
.TP
|
||||
\--verbose
|
||||
Dumps some debug information.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
173
ao-tools/ao-makebin/ao-makebin.c
Normal file
173
ao-tools/ao-makebin/ao-makebin.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright © 2016 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "ao-hex.h"
|
||||
#include "ao-elf.h"
|
||||
#include "ao-dfu.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "verbose", .has_arg = 0, .val = 'v' },
|
||||
{ .name = "output", .has_arg = 1, .val = 'o' },
|
||||
{ .name = "base", .has_arg = 1, .val = 'b' },
|
||||
{ .name = "align", .has_arg = 1, .val = 'a' },
|
||||
{ .name = "dfu", .has_arg = 0, .val = 'd' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--verbose=<level>] [--output=<output.bin>] [--base=<base-address>] [--align=<align>] [--dfu] <input.elf> ...\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
ends_with(char *whole, char *suffix)
|
||||
{
|
||||
int whole_len = strlen(whole);
|
||||
int suffix_len = strlen(suffix);
|
||||
|
||||
if (suffix_len > whole_len)
|
||||
return 0;
|
||||
return strcmp(whole + whole_len - suffix_len, suffix) == 0;
|
||||
}
|
||||
|
||||
static struct ao_dfu_info dfu_info = {
|
||||
.bcdDevice = 0x0000,
|
||||
.idProduct = 0xdf11,
|
||||
.idVendor = 0x0483,
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *output = NULL;
|
||||
struct ao_hex_image *image = NULL;
|
||||
struct ao_sym *file_symbols;
|
||||
int num_file_symbols;
|
||||
FILE *file;
|
||||
int c;
|
||||
uint32_t base = 0xffffffff;
|
||||
uint32_t align = 0;
|
||||
uint32_t length;
|
||||
int verbose = 0;
|
||||
int dfu = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "dvo:b:a:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'o':
|
||||
output = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'b':
|
||||
base = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'a':
|
||||
align = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'd':
|
||||
dfu = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (argv[optind]) {
|
||||
char *input = argv[optind];
|
||||
struct ao_hex_image *tmp;
|
||||
|
||||
if (ends_with (input, ".ihx"))
|
||||
tmp = ao_hex_load(input, &file_symbols, &num_file_symbols);
|
||||
else
|
||||
tmp = ao_load_elf(input, &file_symbols, &num_file_symbols);
|
||||
|
||||
if (!tmp)
|
||||
usage(argv[0]);
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "%s: 0x%x %d\n", input, tmp->address, tmp->length);
|
||||
|
||||
if (image) {
|
||||
image = ao_hex_image_cat(image, tmp);
|
||||
if (!image)
|
||||
usage(argv[0]);
|
||||
} else
|
||||
image = tmp;
|
||||
optind++;
|
||||
}
|
||||
|
||||
if (base != 0xffffffff && base > image->address) {
|
||||
fprintf(stderr, "requested base 0x%x is after image address 0x%x\n",
|
||||
base, image->address);
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "%s: base 0x%x length %d\n", output ? output : "<stdout>", image->address, image->length);
|
||||
|
||||
if (!output)
|
||||
file = stdout;
|
||||
else {
|
||||
file = fopen(output, "w");
|
||||
if (!file) {
|
||||
perror(output);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (dfu) {
|
||||
if (!ao_dfu_write(file, &dfu_info, 1, image)) {
|
||||
fprintf(stderr, "%s: dfu_write failed: %s\n", output, strerror(errno));
|
||||
if (output)
|
||||
unlink(output);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
while (base < image->address) {
|
||||
fputc(0xff, file);
|
||||
base++;
|
||||
}
|
||||
|
||||
if (fwrite(image->data, 1, image->length, file) != image->length) {
|
||||
fprintf(stderr, "%s: failed to write bin file\n", output ? output : "<stdout>");
|
||||
if (output)
|
||||
unlink(output);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (align) {
|
||||
length = image->length;
|
||||
|
||||
while (length % align) {
|
||||
fputc(0xff, file);
|
||||
length++;
|
||||
}
|
||||
}
|
||||
fflush(file);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
1
ao-tools/ao-mega/.gitignore
vendored
Normal file
1
ao-tools/ao-mega/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-mega
|
12
ao-tools/ao-mega/Makefile.am
Normal file
12
ao-tools/ao-mega/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-mega
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_mega_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS)
|
||||
|
||||
ao_mega_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_mega_SOURCES = ao-mega.c
|
||||
|
||||
man_MANS = ao-mega.1
|
30
ao-tools/ao-mega/ao-mega.1
Normal file
30
ao-tools/ao-mega/ao-mega.1
Normal file
@@ -0,0 +1,30 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-TELEM 1 "ao-mega" ""
|
||||
.SH NAME
|
||||
ao-mega \- Dump a mega flight log (eeprom only)
|
||||
.SH SYNOPSIS
|
||||
.B "ao-mega"
|
||||
{flight.mega}
|
||||
.SH DESCRIPTION
|
||||
.I ao-mega
|
||||
reads the specified flight log and dumps it in human readable format.
|
||||
output.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
143
ao-tools/ao-mega/ao-mega.c
Normal file
143
ao-tools/ao-mega/ao-mega.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright © 2011 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "cc.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s\n"
|
||||
"\t{flight.mega} ...\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define bool(b) ((b) ? "true" : "false")
|
||||
|
||||
static const char *state_names[] = {
|
||||
"startup",
|
||||
"idle",
|
||||
"pad",
|
||||
"boost",
|
||||
"fast",
|
||||
"coast",
|
||||
"drogue",
|
||||
"main",
|
||||
"landed",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
|
||||
#define NUM_STATE (sizeof state_names/sizeof state_names[0])
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char line[256];
|
||||
int c, i, ret, j;
|
||||
char *s;
|
||||
FILE *file;
|
||||
int serial;
|
||||
const char *state;
|
||||
while ((c = getopt_long(argc, argv, "", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (!file) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
s = strstr(argv[i], "-serial-");
|
||||
if (s)
|
||||
serial = atoi(s + 8);
|
||||
else
|
||||
serial = 0;
|
||||
while (fgets(line, sizeof (line), file)) {
|
||||
struct ao_log_mega log;
|
||||
|
||||
if (cc_mega_parse(line, &log)) {
|
||||
if (log.is_config) {
|
||||
printf ("config %2d %s", log.u.config_int.kind, line);
|
||||
} else {
|
||||
printf ("tick %5d ", log.tick);
|
||||
switch (log.type) {
|
||||
case AO_LOG_FLIGHT:
|
||||
printf ("flight %5u ground_accel %d ground_pres %u\n",
|
||||
log.u.flight.flight,
|
||||
log.u.flight.ground_accel,
|
||||
log.u.flight.ground_pres);
|
||||
break;
|
||||
case AO_LOG_STATE:
|
||||
if (log.u.state.state < NUM_STATE)
|
||||
state = state_names[log.u.state.state];
|
||||
else
|
||||
state = "invalid";
|
||||
printf ("state %d (%s)\n", log.u.state.state, state);
|
||||
break;
|
||||
case AO_LOG_SENSOR:
|
||||
printf ("p %9u t %9u ax %6d ay %6d az %6d gx %6d gy %6d gz %6d mx %6d my %6d mz %6d a %6d\n",
|
||||
log.u.sensor.pres,
|
||||
log.u.sensor.temp,
|
||||
log.u.sensor.accel_x,
|
||||
log.u.sensor.accel_y,
|
||||
log.u.sensor.accel_z,
|
||||
log.u.sensor.gyro_x,
|
||||
log.u.sensor.gyro_y,
|
||||
log.u.sensor.gyro_z,
|
||||
log.u.sensor.mag_x,
|
||||
log.u.sensor.mag_y,
|
||||
log.u.sensor.mag_z,
|
||||
log.u.sensor.accel);
|
||||
break;
|
||||
case AO_LOG_TEMP_VOLT:
|
||||
printf ("batt %6d pbatt %6d n_sense %d",
|
||||
log.u.volt.v_batt,
|
||||
log.u.volt.v_pbatt,
|
||||
log.u.volt.n_sense);
|
||||
for (j = 0; j < log.u.volt.n_sense; j++) {
|
||||
printf (" s%d %6d",
|
||||
j, log.u.volt.sense[j]);
|
||||
}
|
||||
printf (" pyro %04x\n", log.u.volt.pyro);
|
||||
break;
|
||||
default:
|
||||
printf ("type %c\n", log.type, log.tick);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
12
ao-tools/ao-postflight/Makefile.am
Normal file
12
ao-tools/ao-postflight/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-postflight
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) $(GNOME_CFLAGS) $(PLPLOT_CFLAGS)
|
||||
AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_postflight_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS)
|
||||
|
||||
ao_postflight_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS) $(GNOME_LIBS) $(PLPLOT_LIBS)
|
||||
|
||||
ao_postflight_SOURCES = ao-postflight.c
|
||||
|
||||
man_MANS = ao-postflight.1
|
61
ao-tools/ao-postflight/ao-postflight.1
Normal file
61
ao-tools/ao-postflight/ao-postflight.1
Normal file
@@ -0,0 +1,61 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-POSTFLIGHT 1 "ao-postflight" ""
|
||||
.SH NAME
|
||||
ao-postflight \- Analyse a flight log (either telemetry or eeprom)
|
||||
.SH SYNOPSIS
|
||||
.B "ao-postflight"
|
||||
[\-s <summary-file>]
|
||||
[\--summary=<summary-file>]
|
||||
[\-d <detail-file>]
|
||||
[\--detail=<detail-file>]
|
||||
[\-r <raw-file>]
|
||||
[\--raw=<raw-file>]
|
||||
[\-p <plot-file>]
|
||||
[\--plot=<plot-file>]
|
||||
[\-g <gps-file]
|
||||
[\--gps=<gps-file]
|
||||
[\-k <kml-file]
|
||||
[\--kml=<kml-file]
|
||||
{flight.eeprom|flight.telem}
|
||||
.SH DESCRIPTION
|
||||
.I ao-postflight
|
||||
reads the specified flight log and produces several different kinds of
|
||||
output.
|
||||
.IP Summary
|
||||
By default, summary information is shown on stdout. With the --summary
|
||||
option, it can be redirected to a file.
|
||||
.IP Detail
|
||||
When requested with the --detail option, a filtered version of the
|
||||
flight position, speed and acceleration are written to the specified
|
||||
file.
|
||||
.IP Raw
|
||||
The --raw option writes the unfiltered, but converted acceleration
|
||||
and height data to the specified file.
|
||||
.IP Plot
|
||||
The --plot option writes plots of height, speed and acceleration to
|
||||
the specified file in .svg format
|
||||
.IP GPS
|
||||
The --gps option writes the recorded GPS data to the specified file in
|
||||
three columns.
|
||||
.IP KML
|
||||
The --kml option writes the recorded GPS data to the specified file in
|
||||
Keyhole Markup Language format, which can be displayed in Googleearth.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
827
ao-tools/ao-postflight/ao-postflight.c
Normal file
827
ao-tools/ao-postflight/ao-postflight.c
Normal file
@@ -0,0 +1,827 @@
|
||||
/*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "cc-usb.h"
|
||||
#include "cc.h"
|
||||
#include <plplot/plplot.h>
|
||||
|
||||
static const char *state_names[] = {
|
||||
"startup",
|
||||
"idle",
|
||||
"pad",
|
||||
"boost",
|
||||
"fast",
|
||||
"coast",
|
||||
"drogue",
|
||||
"main",
|
||||
"landed",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
static const char *kml_state_colours[] = {
|
||||
"FF000000",
|
||||
"FF000000",
|
||||
"FF000000",
|
||||
"FF0000FF",
|
||||
"FF4080FF",
|
||||
"FF00FFFF",
|
||||
"FFFF0000",
|
||||
"FF00FF00",
|
||||
"FF000000",
|
||||
"FFFFFFFF"
|
||||
};
|
||||
|
||||
static int plot_colors[3][3] = {
|
||||
{ 0, 0x90, 0 }, /* height */
|
||||
{ 0xa0, 0, 0 }, /* speed */
|
||||
{ 0, 0, 0xc0 }, /* accel */
|
||||
};
|
||||
|
||||
#define PLOT_HEIGHT 0
|
||||
#define PLOT_SPEED 1
|
||||
#define PLOT_ACCEL 2
|
||||
|
||||
static void
|
||||
plot_perioddata(struct cc_perioddata *d, char *axis_label, char *plot_label,
|
||||
double min_time, double max_time, int plot_type)
|
||||
{
|
||||
double *times;
|
||||
double ymin, ymax;
|
||||
int ymin_i, ymax_i;
|
||||
int i;
|
||||
int start, stop;
|
||||
|
||||
if (!cc_perioddata_limits(d, min_time, max_time, &start, &stop))
|
||||
return;
|
||||
|
||||
times = calloc(stop - start + 1, sizeof (double));
|
||||
for (i = start; i <= stop; i++)
|
||||
times[i-start] = i * d->step / 100.0;
|
||||
|
||||
ymin_i = cc_perioddata_min(d, min_time, max_time);
|
||||
ymax_i = cc_perioddata_max(d, min_time, max_time);
|
||||
ymin = d->data[ymin_i];
|
||||
ymax = d->data[ymax_i];
|
||||
plscol0(1, 0, 0, 0);
|
||||
plscol0(2, plot_colors[plot_type][0], plot_colors[plot_type][1], plot_colors[plot_type][2]);
|
||||
plcol0(1);
|
||||
plenv(times[0], times[stop-start],
|
||||
ymin, ymax, 0, 2);
|
||||
pllab("Time", axis_label, plot_label);
|
||||
plcol0(2);
|
||||
plline(stop - start + 1, times, d->data + start);
|
||||
free(times);
|
||||
}
|
||||
|
||||
static void
|
||||
plot_timedata(struct cc_timedata *d, char *axis_label, char *plot_label,
|
||||
double min_time, double max_time, int plot_type)
|
||||
{
|
||||
double *times;
|
||||
double *values;
|
||||
double ymin, ymax;
|
||||
int ymin_i, ymax_i;
|
||||
int i;
|
||||
int start = -1, stop = -1;
|
||||
double start_time = 0, stop_time = 0;
|
||||
int num;
|
||||
|
||||
for (i = 0; i < d->num; i++) {
|
||||
if (start < 0 && d->data[i].time >= min_time) {
|
||||
start_time = d->data[i].time;
|
||||
start = i;
|
||||
}
|
||||
if (d->data[i].time <= max_time) {
|
||||
stop_time = d->data[i].time;
|
||||
stop = i;
|
||||
}
|
||||
}
|
||||
|
||||
times = calloc(stop - start + 1, sizeof (double));
|
||||
values = calloc(stop - start + 1, sizeof (double));
|
||||
|
||||
ymin_i = cc_timedata_min(d, min_time, max_time);
|
||||
ymax_i = cc_timedata_max(d, min_time, max_time);
|
||||
ymin = d->data[ymin_i].value;
|
||||
ymax = d->data[ymax_i].value;
|
||||
for (i = start; i <= stop; i++) {
|
||||
times[i-start] = (d->data[i].time - start_time)/100.0;
|
||||
values[i-start] = d->data[i].value;
|
||||
}
|
||||
plscol0(1, 0, 0, 0);
|
||||
plscol0(2, plot_colors[plot_type][0], plot_colors[plot_type][1], plot_colors[plot_type][2]);
|
||||
plcol0(1);
|
||||
plenv(times[0], times[stop-start], ymin, ymax, 0, 2);
|
||||
pllab("Time", axis_label, plot_label);
|
||||
plcol0(2);
|
||||
plline(stop - start + 1, times, values);
|
||||
free(times);
|
||||
free(values);
|
||||
}
|
||||
|
||||
static struct cc_perioddata *
|
||||
merge_data(struct cc_perioddata *first, struct cc_perioddata *last, double split_time)
|
||||
{
|
||||
int i;
|
||||
struct cc_perioddata *pd;
|
||||
int num;
|
||||
double start_time, stop_time;
|
||||
double t;
|
||||
|
||||
pd = calloc(1, sizeof (struct cc_perioddata));
|
||||
start_time = first->start;
|
||||
stop_time = last->start + last->step * last->num;
|
||||
num = (stop_time - start_time) / first->step;
|
||||
pd->num = num;
|
||||
pd->data = calloc(num, sizeof (double));
|
||||
pd->start = first->start;
|
||||
pd->step = first->step;
|
||||
for (i = 0; i < num; i++) {
|
||||
t = pd->start + i * pd->step;
|
||||
if (t <= split_time) {
|
||||
pd->data[i] = first->data[i];
|
||||
} else {
|
||||
int j;
|
||||
|
||||
j = (t - last->start) / last->step;
|
||||
if (j < 0 || j >= last->num)
|
||||
pd->data[i] = 0;
|
||||
else
|
||||
pd->data[i] = last->data[j];
|
||||
}
|
||||
}
|
||||
return pd;
|
||||
}
|
||||
|
||||
static const char kml_header_start[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
|
||||
"<Document>\n"
|
||||
" <name>%s</name>\n"
|
||||
" <description>\n";
|
||||
static const char kml_header_end[] =
|
||||
" </description>\n"
|
||||
" <open>0</open>\n";
|
||||
|
||||
static const char kml_style_start[] =
|
||||
" <Style id=\"ao-flightstate-%s\">\n"
|
||||
" <LineStyle><color>%s</color><width>4</width></LineStyle>\n"
|
||||
" <BalloonStyle>\n"
|
||||
" <text>\n";
|
||||
static const char kml_style_end[] =
|
||||
" </text>\n"
|
||||
" </BalloonStyle>\n"
|
||||
" </Style>\n";
|
||||
|
||||
static const char kml_placemark_start[] =
|
||||
" <Placemark>\n"
|
||||
" <name>%s</name>\n"
|
||||
" <styleUrl>#ao-flightstate-%s</styleUrl>\n"
|
||||
" <LineString>\n"
|
||||
" <tessellate>1</tessellate>\n"
|
||||
" <altitudeMode>absolute</altitudeMode>\n"
|
||||
" <coordinates>\n";
|
||||
|
||||
static const char kml_coord_fmt[] =
|
||||
" %12.7f, %12.7f, %12.7f <!-- alt %12.7f time %12.7f sats %d -->\n";
|
||||
|
||||
static const char kml_placemark_end[] =
|
||||
" </coordinates>\n"
|
||||
" </LineString>\n"
|
||||
" </Placemark>\n";
|
||||
|
||||
static const char kml_footer[] =
|
||||
" </coordinates>\n"
|
||||
" </LineString>\n"
|
||||
" </Placemark>\n"
|
||||
"</Document>\n"
|
||||
"</kml>\n";
|
||||
|
||||
static unsigned
|
||||
gps_daytime(struct cc_gpselt *gps)
|
||||
{
|
||||
return ((gps->hour * 60 +
|
||||
gps->minute) * 60 +
|
||||
gps->second) * 1000;
|
||||
}
|
||||
|
||||
int
|
||||
daytime_hour(unsigned daytime)
|
||||
{
|
||||
return daytime / 1000 / 60 / 60;
|
||||
}
|
||||
|
||||
int
|
||||
daytime_minute(unsigned daytime)
|
||||
{
|
||||
return (daytime / 1000 / 60) % 60;
|
||||
}
|
||||
|
||||
int
|
||||
daytime_second(unsigned daytime)
|
||||
{
|
||||
return (daytime / 1000) % 60;
|
||||
}
|
||||
|
||||
int
|
||||
daytime_millisecond(unsigned daytime)
|
||||
{
|
||||
return daytime % 1000;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
compute_daytime_ms(double time, struct cc_gpsdata *gps)
|
||||
{
|
||||
int i;
|
||||
unsigned gps_start_daytime, gps_stop_daytime;
|
||||
|
||||
if (time <= gps->data[0].time) {
|
||||
gps_stop_daytime = gps_daytime(&gps->data[0]);
|
||||
return gps_stop_daytime - (gps->data[0].time - time) * 10;
|
||||
}
|
||||
for (i = 0; i < gps->num - 1; i++)
|
||||
if (time > gps->data[i].time)
|
||||
break;
|
||||
gps_start_daytime = gps_daytime(&gps->data[i]);
|
||||
if (i == gps->num - 1) {
|
||||
return gps_start_daytime + (time - gps->data[i].time) * 10;
|
||||
} else {
|
||||
unsigned gps_period_daytime;
|
||||
double gps_period_time;
|
||||
double time_since_start;
|
||||
|
||||
gps_stop_daytime = gps_daytime(&gps->data[i + 1]);
|
||||
|
||||
/* range of gps daytime values */
|
||||
gps_period_daytime = gps_stop_daytime - gps_start_daytime;
|
||||
|
||||
/* range of gps time values */
|
||||
gps_period_time = gps->data[i+1].time - gps->data[i].time;
|
||||
|
||||
/* sample time after first gps time */
|
||||
time_since_start = time - gps->data[i].time;
|
||||
|
||||
return gps_start_daytime +
|
||||
gps_period_daytime * time_since_start / gps_period_time;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
analyse_flight(struct cc_flightraw *f, FILE *summary_file, FILE *detail_file,
|
||||
FILE *raw_file, char *plot_name, FILE *gps_file, FILE *kml_file)
|
||||
{
|
||||
double height;
|
||||
double accel;
|
||||
double speed;
|
||||
double avg_speed;
|
||||
double boost_start, boost_stop;
|
||||
double min_pres;
|
||||
int i;
|
||||
int pres_i, accel_i, speed_i;
|
||||
int boost_start_set = 0;
|
||||
int boost_stop_set = 0;
|
||||
enum ao_flight_state state;
|
||||
double state_start, state_stop;
|
||||
struct cc_flightcooked *cooked;
|
||||
double apogee;
|
||||
char buf[128];
|
||||
|
||||
if (kml_file) {
|
||||
snprintf(buf, sizeof (buf), "AO Flight#%d S/N: %03d", f->flight, f->serial);
|
||||
fprintf(kml_file, kml_header_start, buf);
|
||||
}
|
||||
|
||||
fprintf(summary_file,
|
||||
"Serial: %9d\n"
|
||||
"Flight: %9d\n",
|
||||
f->serial, f->flight);
|
||||
|
||||
if (f->year) {
|
||||
snprintf(buf, sizeof (buf),
|
||||
"Date: %04d-%02d-%02d\n",
|
||||
f->year, f->month, f->day);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
if (f->gps.num) {
|
||||
snprintf(buf, sizeof (buf),
|
||||
"Time: %2d:%02d:%02d\n",
|
||||
f->gps.data[0].hour,
|
||||
f->gps.data[0].minute,
|
||||
f->gps.data[0].second);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
boost_start = f->accel.data[0].time;
|
||||
boost_stop = f->accel.data[f->accel.num-1].time;
|
||||
for (i = 0; i < f->state.num; i++) {
|
||||
if (f->state.data[i].value == ao_flight_boost && !boost_start_set) {
|
||||
boost_start = f->state.data[i].time;
|
||||
boost_start_set = 1;
|
||||
}
|
||||
if (f->state.data[i].value > ao_flight_boost && !boost_stop_set) {
|
||||
boost_stop = f->state.data[i].time;
|
||||
boost_stop_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pres_i = cc_timedata_min(&f->pres, f->pres.data[0].time,
|
||||
f->pres.data[f->pres.num-1].time);
|
||||
if (pres_i >= 0)
|
||||
{
|
||||
min_pres = f->pres.data[pres_i].value;
|
||||
height = cc_barometer_to_altitude(min_pres) -
|
||||
cc_barometer_to_altitude(f->ground_pres);
|
||||
apogee = f->pres.data[pres_i].time;
|
||||
snprintf(buf, sizeof (buf), "Max height: %9.2fm %9.2fft %9.2fs\n",
|
||||
height, height * 100 / 2.54 / 12,
|
||||
(f->pres.data[pres_i].time - boost_start) / 100.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
|
||||
cooked = cc_flight_cook(f);
|
||||
if (cooked) {
|
||||
speed_i = cc_perioddata_max(&cooked->accel_speed, boost_start, boost_stop);
|
||||
if (speed_i >= 0) {
|
||||
speed = cooked->accel_speed.data[speed_i];
|
||||
snprintf(buf, sizeof (buf), "Max speed: %9.2fm/s %9.2fft/s %9.2fs\n",
|
||||
speed, speed * 100 / 2.4 / 12.0,
|
||||
(cooked->accel_speed.start + speed_i * cooked->accel_speed.step - boost_start) / 100.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
}
|
||||
accel_i = cc_timedata_min(&f->accel, boost_start, boost_stop);
|
||||
if (accel_i >= 0)
|
||||
{
|
||||
accel = cc_accelerometer_to_acceleration(f->accel.data[accel_i].value,
|
||||
f->ground_accel);
|
||||
snprintf(buf, sizeof (buf), "Max accel: %9.2fm/s² %9.2fg %9.2fs\n",
|
||||
accel, accel / 9.80665,
|
||||
(f->accel.data[accel_i].time - boost_start) / 100.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
|
||||
if (kml_file)
|
||||
fprintf(kml_file, "%s", kml_header_end);
|
||||
|
||||
for (i = 0; i < f->state.num; i++) {
|
||||
state = f->state.data[i].value;
|
||||
state_start = f->state.data[i].time;
|
||||
while (i < f->state.num - 1 && f->state.data[i+1].value == state)
|
||||
i++;
|
||||
if (i < f->state.num - 1)
|
||||
state_stop = f->state.data[i + 1].time;
|
||||
else
|
||||
state_stop = f->accel.data[f->accel.num-1].time;
|
||||
fprintf(summary_file, "State: %s\n", state_names[state]);
|
||||
fprintf(summary_file, "\tStart: %9.2fs\n", (state_start - boost_start) / 100.0);
|
||||
fprintf(summary_file, "\tDuration: %9.2fs\n", (state_stop - state_start) / 100.0);
|
||||
if (kml_file) {
|
||||
fprintf(kml_file, kml_style_start, state_names[state], kml_state_colours[state]);
|
||||
fprintf(kml_file, "\tState: %s\n", state_names[state]);
|
||||
fprintf(kml_file, "\tStart: %9.2fs\n", (state_start - boost_start) / 100.0);
|
||||
fprintf(kml_file, "\tDuration: %9.2fs\n", (state_stop - state_start) / 100.0);
|
||||
}
|
||||
|
||||
accel_i = cc_timedata_min(&f->accel, state_start, state_stop);
|
||||
if (accel_i >= 0)
|
||||
{
|
||||
accel = cc_accelerometer_to_acceleration(f->accel.data[accel_i].value,
|
||||
f->ground_accel);
|
||||
snprintf(buf, sizeof (buf), "\tMax accel: %9.2fm/s² %9.2fg %9.2fs\n",
|
||||
accel, accel / 9.80665,
|
||||
(f->accel.data[accel_i].time - boost_start) / 100.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
|
||||
if (cooked) {
|
||||
if (state < ao_flight_drogue) {
|
||||
speed_i = cc_perioddata_max_mag(&cooked->accel_speed, state_start, state_stop);
|
||||
if (speed_i >= 0)
|
||||
speed = cooked->accel_speed.data[speed_i];
|
||||
avg_speed = cc_perioddata_average(&cooked->accel_speed, state_start, state_stop);
|
||||
} else {
|
||||
speed_i = cc_perioddata_max_mag(&cooked->pres_speed, state_start, state_stop);
|
||||
if (speed_i >= 0)
|
||||
speed = cooked->pres_speed.data[speed_i];
|
||||
avg_speed = cc_perioddata_average(&cooked->pres_speed, state_start, state_stop);
|
||||
}
|
||||
if (speed_i >= 0)
|
||||
{
|
||||
snprintf(buf, sizeof (buf), "\tMax speed: %9.2fm/s %9.2fft/s %9.2fs\n",
|
||||
speed, speed * 100 / 2.4 / 12.0,
|
||||
(cooked->accel_speed.start + speed_i * cooked->accel_speed.step - boost_start) / 100.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
|
||||
snprintf(buf, sizeof (buf), "\tAvg speed: %9.2fm/s %9.2fft/s\n",
|
||||
avg_speed, avg_speed * 100 / 2.4 / 12.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
}
|
||||
pres_i = cc_timedata_min(&f->pres, state_start, state_stop);
|
||||
if (pres_i >= 0)
|
||||
{
|
||||
min_pres = f->pres.data[pres_i].value;
|
||||
height = cc_barometer_to_altitude(min_pres) -
|
||||
cc_barometer_to_altitude(f->ground_pres);
|
||||
snprintf(buf, sizeof (buf), "\tMax height: %9.2fm %9.2fft %9.2fs\n",
|
||||
height, height * 100 / 2.54 / 12,
|
||||
(f->pres.data[pres_i].time - boost_start) / 100.0);
|
||||
fprintf(summary_file, "%s", buf);
|
||||
if (kml_file) fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
if (kml_file) fprintf(kml_file, "%s", kml_style_end);
|
||||
}
|
||||
if (cooked && detail_file) {
|
||||
double max_height = 0;
|
||||
int i;
|
||||
double *times;
|
||||
|
||||
fprintf(detail_file, "%9s %9s %9s %9s %9s\n",
|
||||
"time", "height", "speed", "accel", "daytime");
|
||||
for (i = 0; i < cooked->pres_pos.num; i++) {
|
||||
double clock_time = cooked->accel_accel.start + i * cooked->accel_accel.step;
|
||||
double time = (clock_time - boost_start) / 100.0;
|
||||
double accel = cooked->accel_accel.data[i];
|
||||
double pos = cooked->pres_pos.data[i];
|
||||
double speed;
|
||||
unsigned daytime;
|
||||
if (cooked->pres_pos.start + cooked->pres_pos.step * i < apogee)
|
||||
speed = cooked->accel_speed.data[i];
|
||||
else
|
||||
speed = cooked->pres_speed.data[i];
|
||||
if (f->gps.num)
|
||||
daytime = compute_daytime_ms(clock_time, &f->gps);
|
||||
else
|
||||
daytime = 0;
|
||||
fprintf(detail_file, "%9.2f %9.2f %9.2f %9.2f %02d:%02d:%02d.%03d\n",
|
||||
time, pos, speed, accel,
|
||||
daytime_hour(daytime),
|
||||
daytime_minute(daytime),
|
||||
daytime_second(daytime),
|
||||
daytime_millisecond(daytime));
|
||||
}
|
||||
}
|
||||
if (raw_file) {
|
||||
fprintf(raw_file, "%9s %9s %9s %9s\n",
|
||||
"time", "height", "accel", "daytime");
|
||||
for (i = 0; i < cooked->pres.num; i++) {
|
||||
double time = cooked->pres.data[i].time;
|
||||
double pres = cooked->pres.data[i].value;
|
||||
double accel = cooked->accel.data[i].value;
|
||||
unsigned daytime;
|
||||
if (f->gps.num)
|
||||
daytime = compute_daytime_ms(time, &f->gps);
|
||||
else
|
||||
daytime = 0;
|
||||
fprintf(raw_file, "%9.2f %9.2f %9.2f %02d:%02d:%02d.%03d\n",
|
||||
time, pres, accel,
|
||||
daytime_hour(daytime),
|
||||
daytime_minute(daytime),
|
||||
daytime_second(daytime),
|
||||
daytime_millisecond(daytime));
|
||||
}
|
||||
}
|
||||
if (gps_file || kml_file) {
|
||||
int j = 0, baro_pos;
|
||||
double baro_offset;
|
||||
double baro = 0.0;
|
||||
int state_idx = 0;
|
||||
|
||||
if (gps_file)
|
||||
fprintf(gps_file, "%2s %2s %2s %9s %12s %12s %9s %8s %5s\n",
|
||||
"hr", "mn", "sc",
|
||||
"time", "lat", "lon", "alt", "baro", "nsat");
|
||||
if (kml_file)
|
||||
fprintf(kml_file, kml_placemark_start,
|
||||
state_names[(int)f->state.data[state_idx].value],
|
||||
state_names[(int)f->state.data[state_idx].value]);
|
||||
|
||||
if (f->gps.num)
|
||||
baro_offset = f->gps.data[0].alt;
|
||||
else
|
||||
baro_offset = 0;
|
||||
baro_pos = 0;
|
||||
for (i = 0; i < f->gps.num; i++) {
|
||||
int nsat = 0;
|
||||
int k;
|
||||
while (j < f->gps.numsats - 1) {
|
||||
if (f->gps.sats[j].sat[0].time <= f->gps.data[i].time &&
|
||||
f->gps.data[i].time < f->gps.sats[j+1].sat[0].time)
|
||||
break;
|
||||
j++;
|
||||
}
|
||||
if (cooked) {
|
||||
while (baro_pos < cooked->pres_pos.num) {
|
||||
double baro_time = cooked->accel_accel.start + baro_pos * cooked->accel_accel.step;
|
||||
if (baro_time >= f->gps.data[i].time)
|
||||
break;
|
||||
baro_pos++;
|
||||
}
|
||||
if (baro_pos < cooked->pres_pos.num)
|
||||
baro = cooked->pres_pos.data[baro_pos];
|
||||
}
|
||||
if (gps_file)
|
||||
fprintf(gps_file, "%2d %2d %2d %12.7f %12.7f %12.7f %7.1f %7.1f",
|
||||
f->gps.data[i].hour,
|
||||
f->gps.data[i].minute,
|
||||
f->gps.data[i].second,
|
||||
(f->gps.data[i].time - boost_start) / 100.0,
|
||||
f->gps.data[i].lat,
|
||||
f->gps.data[i].lon,
|
||||
f->gps.data[i].alt,
|
||||
baro + baro_offset);
|
||||
|
||||
nsat = 0;
|
||||
if (f->gps.sats) {
|
||||
for (k = 0; k < f->gps.sats[j].nsat; k++) {
|
||||
if (f->gps.sats[j].sat[k].svid != 0)
|
||||
nsat++;
|
||||
}
|
||||
if (gps_file) {
|
||||
fprintf(gps_file, " %4d", nsat);
|
||||
for (k = 0; k < f->gps.sats[j].nsat; k++) {
|
||||
if (f->gps.sats[j].sat[k].svid != 0) {
|
||||
fprintf (gps_file, " %3d(%4.1f)",
|
||||
f->gps.sats[j].sat[k].svid,
|
||||
(double) f->gps.sats[j].sat[k].c_n);
|
||||
}
|
||||
}
|
||||
fprintf(gps_file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (kml_file) {
|
||||
snprintf(buf, sizeof (buf), kml_coord_fmt,
|
||||
f->gps.data[i].lon,
|
||||
f->gps.data[i].lat,
|
||||
baro + baro_offset,
|
||||
f->gps.data[i].alt,
|
||||
(f->gps.data[i].time - boost_start) / 100.0,
|
||||
nsat);
|
||||
fprintf(kml_file, "%s", buf);
|
||||
if (state_idx + 1 < f->state.num && f->state.data[state_idx + 1].time <= f->gps.data[i].time) {
|
||||
state_idx++;
|
||||
if (f->state.data[state_idx - 1].value != f->state.data[state_idx].value) {
|
||||
fprintf(kml_file, "%s", kml_placemark_end);
|
||||
fprintf(kml_file, kml_placemark_start,
|
||||
state_names[(int)f->state.data[state_idx].value],
|
||||
state_names[(int)f->state.data[state_idx].value]);
|
||||
fprintf(kml_file, "%s", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (kml_file)
|
||||
fprintf(kml_file, "%s", kml_footer);
|
||||
}
|
||||
if (cooked && plot_name) {
|
||||
struct cc_perioddata *speed;
|
||||
plsdev("svgcairo");
|
||||
plsfnam(plot_name);
|
||||
#define PLOT_DPI 96
|
||||
plspage(PLOT_DPI, PLOT_DPI, 8 * PLOT_DPI, 8 * PLOT_DPI, 0, 0);
|
||||
plscolbg(0xff, 0xff, 0xff);
|
||||
plscol0(1,0,0,0);
|
||||
plstar(2, 3);
|
||||
speed = merge_data(&cooked->accel_speed, &cooked->pres_speed, apogee);
|
||||
|
||||
plot_perioddata(&cooked->pres_pos, "meters", "Height",
|
||||
-1e10, 1e10, PLOT_HEIGHT);
|
||||
plot_perioddata(&cooked->pres_pos, "meters", "Height to Apogee",
|
||||
boost_start, apogee + (apogee - boost_start) / 10.0, PLOT_HEIGHT);
|
||||
plot_perioddata(speed, "meters/second", "Speed",
|
||||
-1e10, 1e10, PLOT_SPEED);
|
||||
plot_perioddata(speed, "meters/second", "Speed to Apogee",
|
||||
boost_start, apogee + (apogee - boost_start) / 10.0, PLOT_SPEED);
|
||||
plot_perioddata(&cooked->accel_accel, "meters/second²", "Acceleration",
|
||||
-1e10, 1e10, PLOT_ACCEL);
|
||||
/* plot_perioddata(&cooked->accel_accel, "meters/second²", "Acceleration during Boost",
|
||||
boost_start, boost_stop + (boost_stop - boost_start) / 2.0, PLOT_ACCEL); */
|
||||
plot_timedata(&cooked->accel, "meters/second²", "Acceleration during Boost",
|
||||
boost_start, boost_stop + (boost_stop - boost_start) / 2.0, PLOT_ACCEL);
|
||||
free(speed->data);
|
||||
free(speed);
|
||||
plend();
|
||||
}
|
||||
if (cooked)
|
||||
cc_flightcooked_free(cooked);
|
||||
}
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "summary", .has_arg = 2, .val = 's' },
|
||||
{ .name = "detail", .has_arg = 2, .val = 'd' },
|
||||
{ .name = "plot", .has_arg = 2, .val = 'p' },
|
||||
{ .name = "raw", .has_arg = 2, .val = 'r' },
|
||||
{ .name = "gps", .has_arg = 2, .val = 'g' },
|
||||
{ .name = "kml", .has_arg = 2, .val = 'k' },
|
||||
{ .name = "all", .has_arg = 0, .val = 'a' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s\n"
|
||||
"\t[--all] [-a]\n"
|
||||
"\t[--summary=<summary-file>] [-s <summary-file>]\n"
|
||||
"\t[--detail=<detail-file] [-d <detail-file>]\n"
|
||||
"\t[--raw=<raw-file> -r <raw-file]\n"
|
||||
"\t[--plot=<plot-file> -p <plot-file>]\n"
|
||||
"\t[--gps=<gps-file> -g <gps-file>]\n"
|
||||
"\t[--kml=<kml-file> -k <kml-file>]\n"
|
||||
"\t{flight-log} ...\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *
|
||||
replace_extension(char *file, char *extension)
|
||||
{
|
||||
char *slash;
|
||||
char *dot;
|
||||
char *new;
|
||||
int newlen;
|
||||
|
||||
slash = strrchr(file, '/');
|
||||
dot = strrchr(file, '.');
|
||||
if (!dot || (slash && dot < slash))
|
||||
dot = file + strlen(file);
|
||||
newlen = (dot - file) + strlen (extension) + 1;
|
||||
new = malloc (newlen);
|
||||
strncpy (new, file, dot - file);
|
||||
new[dot-file] = '\0';
|
||||
strcat (new, extension);
|
||||
return new;
|
||||
}
|
||||
|
||||
FILE *
|
||||
open_output(char *outname, char *inname, char *extension)
|
||||
{
|
||||
char *o;
|
||||
FILE *out;
|
||||
|
||||
if (outname)
|
||||
o = outname;
|
||||
else
|
||||
o = replace_extension(inname, extension);
|
||||
out = fopen(o, "w");
|
||||
if (!out) {
|
||||
perror (o);
|
||||
exit(1);
|
||||
}
|
||||
if (o != outname)
|
||||
free(o);
|
||||
return out;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
FILE *file;
|
||||
FILE *summary_file = NULL;
|
||||
FILE *detail_file = NULL;
|
||||
FILE *raw_file = NULL;
|
||||
FILE *gps_file = NULL;
|
||||
FILE *kml_file = NULL;
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct cc_flightraw *raw;
|
||||
int c;
|
||||
int serial;
|
||||
char *s;
|
||||
char *summary_name = NULL;
|
||||
char *detail_name = NULL;
|
||||
char *raw_name = NULL;
|
||||
char *plot_name = NULL;
|
||||
char *gps_name = NULL;
|
||||
char *kml_name = NULL;
|
||||
int has_summary = 0;
|
||||
int has_detail = 0;
|
||||
int has_plot = 0;
|
||||
int has_raw = 0;
|
||||
int has_gps = 0;
|
||||
int has_kml = 0;
|
||||
char *this_plot_name = NULL;;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "s:d:p:r:g:k:a", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
summary_name = optarg;
|
||||
has_summary = 1;
|
||||
break;
|
||||
case 'd':
|
||||
detail_name = optarg;
|
||||
has_detail = 1;
|
||||
break;
|
||||
case 'p':
|
||||
plot_name = optarg;
|
||||
has_plot = 1;
|
||||
break;
|
||||
case 'r':
|
||||
raw_name = optarg;
|
||||
has_raw = 1;
|
||||
break;
|
||||
case 'g':
|
||||
gps_name = optarg;
|
||||
has_gps = 1;
|
||||
break;
|
||||
case 'k':
|
||||
kml_name = optarg;
|
||||
has_kml = 1;
|
||||
break;
|
||||
case 'a':
|
||||
has_summary = has_detail = has_plot = has_raw = has_gps = has_kml = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_summary)
|
||||
summary_file = stdout;
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (!file) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
if (has_summary && !summary_file)
|
||||
summary_file = open_output(summary_name, argv[i], ".summary");
|
||||
if (has_detail && !detail_file)
|
||||
detail_file = open_output(detail_name, argv[i], ".detail");
|
||||
if (has_plot) {
|
||||
if (plot_name)
|
||||
this_plot_name = plot_name;
|
||||
else
|
||||
this_plot_name = replace_extension(argv[i], ".plot");
|
||||
}
|
||||
if (has_raw && !raw_file)
|
||||
raw_file = open_output(raw_name, argv[i], ".raw");
|
||||
if (has_gps && !gps_file)
|
||||
gps_file = open_output(gps_name, argv[i], ".gps");
|
||||
if (has_kml && !kml_file)
|
||||
kml_file = open_output(kml_name, argv[i], ".kml");
|
||||
s = strstr(argv[i], "-serial-");
|
||||
if (s)
|
||||
serial = atoi(s + 8);
|
||||
else
|
||||
serial = 0;
|
||||
raw = cc_log_read(file);
|
||||
if (!raw) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
if (!raw->serial)
|
||||
raw->serial = serial;
|
||||
analyse_flight(raw, summary_file, detail_file, raw_file, this_plot_name, gps_file, kml_file);
|
||||
cc_flightraw_free(raw);
|
||||
if (has_summary && !summary_name) {
|
||||
fclose(summary_file); summary_file = NULL;
|
||||
}
|
||||
if (has_detail && !detail_name) {
|
||||
fclose(detail_file); detail_file = NULL;
|
||||
}
|
||||
if (this_plot_name && this_plot_name != plot_name) {
|
||||
free (this_plot_name); this_plot_name = NULL;
|
||||
}
|
||||
if (has_raw && !raw_name) {
|
||||
fclose(raw_file); raw_file = NULL;
|
||||
}
|
||||
if (has_gps && !gps_name) {
|
||||
fclose(gps_file); gps_file = NULL;
|
||||
}
|
||||
if (has_kml && !kml_name) {
|
||||
fclose(kml_file); kml_file = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
1
ao-tools/ao-rawload/.gitignore
vendored
Normal file
1
ao-tools/ao-rawload/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ccload
|
12
ao-tools/ao-rawload/Makefile.am
Normal file
12
ao-tools/ao-rawload/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-rawload
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_RAWLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_rawload_DEPENDENCIES = $(AO_RAWLOAD_LIBS)
|
||||
|
||||
ao_rawload_LDADD=$(AO_RAWLOAD_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_rawload_SOURCES = ao-rawload.c
|
||||
|
||||
man_MANS=ao-rawload.1
|
65
ao-tools/ao-rawload/ao-rawload.1
Normal file
65
ao-tools/ao-rawload/ao-rawload.1
Normal file
@@ -0,0 +1,65 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-RAWLOAD 1 "ao-rawload" ""
|
||||
.SH NAME
|
||||
ao-rawload \- flash a program to a AltOS device
|
||||
.SH SYNOPSIS
|
||||
.B "ao-rawload"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
\fIfile.ihx\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-rawload
|
||||
loads the specified .ihx file, without modification, into the target
|
||||
device flash or ram (depending on the base address of the .ihx file).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
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
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMetrum:2
|
||||
.br
|
||||
TeleMetrum
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\-r | --run
|
||||
After the file has been loaded, set the PC to the base address of the
|
||||
image and resume execution there.
|
||||
the .ihx file.
|
||||
.SH USAGE
|
||||
.I ao-rawload
|
||||
reads the specified .ihx file into memory. It then connects to the
|
||||
specified target device and writes the program to the target device
|
||||
memory and, optionally, starts the program executing.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
118
ao-tools/ao-rawload/ao-rawload.c
Normal file
118
ao-tools/ao-rawload/ao-rawload.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright © 2008 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "ccdbg.h"
|
||||
#include "cc.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "run", .has_arg = 0, .val = 'r' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--run] file.ihx\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct ccdbg *dbg;
|
||||
struct ao_hex_file *hex;
|
||||
struct ao_hex_image *image;
|
||||
char *filename;
|
||||
FILE *file;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
int c;
|
||||
int run = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "rT:D:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
run = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
filename = argv[optind];
|
||||
if (filename == NULL) {
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
hex = ao_hex_file_read(file, filename);
|
||||
fclose(file);
|
||||
if (!hex)
|
||||
exit (1);
|
||||
image = ao_hex_image_create(hex);
|
||||
if (!image) {
|
||||
fprintf(stderr, "image create failed\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
ao_hex_file_free(hex);
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TIDongle");
|
||||
dbg = ccdbg_open(tty);
|
||||
if (!dbg)
|
||||
exit (1);
|
||||
|
||||
ccdbg_add_debug(CC_DEBUG_FLASH);
|
||||
|
||||
ccdbg_debug_mode(dbg);
|
||||
ccdbg_halt(dbg);
|
||||
if (image->address == 0xf000) {
|
||||
printf("Loading %d bytes to execute from RAM\n",
|
||||
image->length);
|
||||
ccdbg_write_hex_image(dbg, image, 0);
|
||||
} else if (image->address == 0x0000) {
|
||||
printf("Loading %d bytes to execute from FLASH\n",
|
||||
image->length);
|
||||
ccdbg_flash_hex_image(dbg, image);
|
||||
} else {
|
||||
printf("Cannot load code to 0x%04x\n",
|
||||
image->address);
|
||||
ao_hex_image_free(image);
|
||||
ccdbg_close(dbg);
|
||||
exit(1);
|
||||
}
|
||||
if (run) {
|
||||
ccdbg_set_pc(dbg, image->address);
|
||||
ccdbg_resume(dbg);
|
||||
}
|
||||
ccdbg_close(dbg);
|
||||
exit (0);
|
||||
}
|
12
ao-tools/ao-send-telem/Makefile.am
Normal file
12
ao-tools/ao-send-telem/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-send-telem
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_send_telem_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS)
|
||||
|
||||
ao_send_telem_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_send_telem_SOURCES = ao-send-telem.c
|
||||
|
||||
man_MANS = ao-send-telem.1
|
64
ao-tools/ao-send-telem/ao-send-telem.1
Normal file
64
ao-tools/ao-send-telem/ao-send-telem.1
Normal file
@@ -0,0 +1,64 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-SEND-TELEM 1 "ao-send-telem" ""
|
||||
.SH NAME
|
||||
ao-send-telem \- Re-transmit stored telemetry file
|
||||
.SH SYNOPSIS
|
||||
.B "ao-send-telem"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\-F \fIfrequency (kHz)\fP]
|
||||
[\--frequency \fIfrequency (kHz)\fP]
|
||||
[\-R]
|
||||
[\--realtime]
|
||||
<flight.telem>
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
This selects which tty device ao-dumplog uses to communicate with
|
||||
the target device.
|
||||
.TP
|
||||
\-D AltOS-device | --device AltOS-device
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleDongle:2
|
||||
.br
|
||||
TeleDongle
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\-F kHz | --frequency kHz
|
||||
This selects which frequency to send the specified packets on.
|
||||
.TP
|
||||
\-R | --realtime
|
||||
This makes the program delay between packets in pad mode. Normally,
|
||||
pad mode packets are sent as quickly as possible.
|
||||
.SH DESCRIPTION
|
||||
.I ao-send-telem
|
||||
reads the specified flight telemetry log and re-transmits it via the
|
||||
specified ground station device
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
295
ao-tools/ao-send-telem/ao-send-telem.c
Normal file
295
ao-tools/ao-send-telem/ao-send-telem.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright © 2011 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "cc.h"
|
||||
#include "cc-usb.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "frequency", .has_arg = 1, .val = 'F' },
|
||||
{ .name = "realtime", .has_arg = 0, .val = 'R' },
|
||||
{ .name = "verbose", .has_arg = 0, .val = 'v' },
|
||||
{ .name = "fake", .has_arg = 0, .val = 'f' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--frequency <kHz>] [--realtime] [--verbose] [--fake] file.telem ...\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define bool(b) ((b) ? "true" : "false")
|
||||
|
||||
struct ao_telem_list {
|
||||
struct ao_telem_list *next;
|
||||
union ao_telemetry_all telem;
|
||||
};
|
||||
|
||||
static struct ao_telem_list *telem_list, **telem_last;
|
||||
|
||||
static void
|
||||
trim_telem(uint16_t time)
|
||||
{
|
||||
while (telem_list && (int16_t) (time - telem_list->telem.generic.tick) > 0) {
|
||||
struct ao_telem_list *next = telem_list->next;
|
||||
free(telem_list);
|
||||
telem_list = next;
|
||||
}
|
||||
if (!telem_list)
|
||||
telem_last = &telem_list;
|
||||
}
|
||||
|
||||
static void
|
||||
add_telem(union ao_telemetry_all *telem)
|
||||
{
|
||||
struct ao_telem_list *new = malloc (sizeof (struct ao_telem_list));
|
||||
trim_telem((uint16_t) (telem->generic.tick - 20 * 100));
|
||||
new->telem = *telem;
|
||||
new->next = 0;
|
||||
*telem_last = new;
|
||||
telem_last = &new->next;
|
||||
}
|
||||
|
||||
static enum ao_flight_state cur_state = ao_flight_invalid;
|
||||
static enum ao_flight_state last_state = ao_flight_invalid;
|
||||
|
||||
static enum ao_flight_state
|
||||
packet_state(union ao_telemetry_all *telem)
|
||||
{
|
||||
switch (telem->generic.type) {
|
||||
case AO_TELEMETRY_SENSOR_TELEMETRUM:
|
||||
case AO_TELEMETRY_SENSOR_TELEMINI:
|
||||
case AO_TELEMETRY_SENSOR_TELENANO:
|
||||
cur_state = telem->sensor.state;
|
||||
break;
|
||||
case AO_TELEMETRY_MEGA_DATA:
|
||||
cur_state = telem->mega_data.state;
|
||||
break;
|
||||
case AO_TELEMETRY_METRUM_SENSOR:
|
||||
cur_state = telem->metrum_sensor.state;
|
||||
break;
|
||||
case AO_TELEMETRY_MINI:
|
||||
cur_state = telem->mini.state;
|
||||
break;
|
||||
}
|
||||
return cur_state;
|
||||
}
|
||||
|
||||
static const char *state_names[] = {
|
||||
"startup",
|
||||
"idle",
|
||||
"pad",
|
||||
"boost",
|
||||
"fast",
|
||||
"coast",
|
||||
"drogue",
|
||||
"main",
|
||||
"landed",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
static void
|
||||
send_telem(struct cc_usb *cc, union ao_telemetry_all *telem)
|
||||
{
|
||||
int i;
|
||||
uint8_t *b;
|
||||
|
||||
packet_state(telem);
|
||||
if (cur_state != last_state) {
|
||||
if (0 <= cur_state && cur_state < sizeof(state_names) / sizeof (state_names[0]))
|
||||
printf ("%s\n", state_names[cur_state]);
|
||||
last_state = cur_state;
|
||||
}
|
||||
cc_usb_printf(cc, "S 20\n");
|
||||
b = (uint8_t *) telem;
|
||||
for (i = 0; i < 0x20; i++)
|
||||
cc_usb_printf(cc, "%02x", b[i]);
|
||||
cc_usb_sync(cc);
|
||||
}
|
||||
|
||||
static void
|
||||
do_delay(uint16_t now, uint16_t then)
|
||||
{
|
||||
int16_t delay = (int16_t) (now - then);
|
||||
|
||||
if (delay > 0 && delay < 1000)
|
||||
usleep(delay * 10 * 1000);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
send_queued(struct cc_usb *cc, int pause)
|
||||
{
|
||||
struct ao_telem_list *next;
|
||||
uint16_t tick = 0;
|
||||
int started = 0;
|
||||
|
||||
while (telem_list) {
|
||||
if (started && pause)
|
||||
do_delay(telem_list->telem.generic.tick, tick);
|
||||
tick = telem_list->telem.generic.tick;
|
||||
started = 1;
|
||||
send_telem(cc, &telem_list->telem);
|
||||
|
||||
next = telem_list->next;
|
||||
free(telem_list);
|
||||
telem_list = next;
|
||||
}
|
||||
return tick;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct cc_usb *cc;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
char line[80];
|
||||
int c, i, ret = 0;
|
||||
int freq = 434550;
|
||||
FILE *file;
|
||||
uint16_t last_tick;
|
||||
int started;
|
||||
int realtime = 0;
|
||||
int verbose = 0;
|
||||
int fake = 0;
|
||||
int rate = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "vRfT:D:F:r:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
realtime = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'f':
|
||||
fake++;
|
||||
break;
|
||||
case 'r':
|
||||
rate = atoi(optarg);
|
||||
switch (rate) {
|
||||
case 38400:
|
||||
rate = 0;
|
||||
break;
|
||||
case 9600:
|
||||
rate = 1;
|
||||
break;
|
||||
case 2400:
|
||||
rate = 2;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Rate %d isn't 38400, 9600 or 2400\n", rate);
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleDongle");
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyACM0";
|
||||
cc = cc_usb_open(tty);
|
||||
if (!cc)
|
||||
exit (1);
|
||||
|
||||
cc_usb_printf(cc, "m 0\n");
|
||||
cc_usb_printf(cc, "c F %d\n", freq);
|
||||
cc_usb_printf(cc, "c T %d\n", rate);
|
||||
|
||||
if (fake) {
|
||||
union ao_telemetry_all telem;
|
||||
int i;
|
||||
|
||||
memset(&telem, '\0', sizeof (telem));
|
||||
telem.generic.serial = 1;
|
||||
telem.generic.type = 0;
|
||||
for (i = 0; i < sizeof (telem.generic.payload); i++)
|
||||
telem.generic.payload[i] = i & 7;
|
||||
for (;;) {
|
||||
telem.generic.tick += 50;
|
||||
send_telem(cc, &telem);
|
||||
do_delay(50, 0);
|
||||
}
|
||||
} else {
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (!file) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
started = 0;
|
||||
last_tick = 0;
|
||||
while (fgets(line, sizeof (line), file)) {
|
||||
union ao_telemetry_all telem;
|
||||
|
||||
if (cc_telemetry_parse(line, &telem)) {
|
||||
/*
|
||||
* Skip packets with CRC errors.
|
||||
*/
|
||||
if ((telem.generic.status & (1 << 7)) == 0)
|
||||
continue;
|
||||
|
||||
if (verbose)
|
||||
printf ("type %4d\n", telem.generic.type);
|
||||
|
||||
if (started || realtime) {
|
||||
do_delay(telem.generic.tick, last_tick);
|
||||
last_tick = telem.generic.tick;
|
||||
send_telem(cc, &telem);
|
||||
} else {
|
||||
enum ao_flight_state state = packet_state(&telem);
|
||||
printf ("\tstate %4d\n", state);
|
||||
add_telem(&telem);
|
||||
if (ao_flight_pad < state && state < ao_flight_landed) {
|
||||
printf ("started\n");
|
||||
started = 1;
|
||||
last_tick = send_queued(cc, realtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
18
ao-tools/ao-sky-flash/Makefile.am
Normal file
18
ao-tools/ao-sky-flash/Makefile.am
Normal file
@@ -0,0 +1,18 @@
|
||||
bin_PROGRAMS=ao-sky-flash
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_SKY_FLASH_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_sky_flash_DEPENDENCIES = $(AO_SKY_FLASH_LIBS)
|
||||
|
||||
ao_sky_flash_LDADD=$(AO_SKY_FLASH_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_sky_flash_SOURCES = \
|
||||
sky_bin.c \
|
||||
sky_debug.c \
|
||||
sky_flash.c \
|
||||
sky_flash.h \
|
||||
sky_serial.c \
|
||||
sky_srec.c
|
||||
|
||||
man_MANS = ao-sky-flash.1
|
Binary file not shown.
Binary file not shown.
85
ao-tools/ao-sky-flash/ao-sky-flash.1
Normal file
85
ao-tools/ao-sky-flash/ao-sky-flash.1
Normal file
@@ -0,0 +1,85 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-SKY-FLASH 1 "ao-sky-flash" ""
|
||||
.SH NAME
|
||||
ao-sky-flash \- flash GPS firmware program to a SkyTraq GPS chip
|
||||
.SH SYNOPSIS
|
||||
.B "ao-sky-flash"
|
||||
[\-T \fItty-device\fP]
|
||||
[\--tty \fItty-device\fP]
|
||||
[\-D \fIaltos-device\fP]
|
||||
[\--device \fIaltos-device\fP]
|
||||
[\--loader \fIboot-loader\fP]
|
||||
[\--firmware \fIgps-firmware\fP]
|
||||
[\--query]
|
||||
[\--quiet]
|
||||
[\--raw]
|
||||
.SH DESCRIPTION
|
||||
.I ao-sky-flash
|
||||
loads the specified GPS firmware file into the target GPS chip flash
|
||||
memory using the specified boot loader.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-T tty-device | --tty tty-device
|
||||
This selects which tty device the debugger uses to communicate with
|
||||
the target device.
|
||||
.TP
|
||||
\-D AltOS-device | --device AltOS-device
|
||||
Search for a connected device. This requires an argument of one of the
|
||||
following forms:
|
||||
.IP
|
||||
TeleMetrum:2
|
||||
.br
|
||||
TeleMetrum
|
||||
.br
|
||||
2
|
||||
.IP
|
||||
Leaving out the product name will cause the tool to select a suitable
|
||||
product, leaving out the serial number will cause the tool to match
|
||||
one of the available devices.
|
||||
.TP
|
||||
\--loader boot-loader
|
||||
This specifies the desired boot loader to use for reflashing the
|
||||
device. You should use srec_115200.bin unless you have a good reason
|
||||
not to. This should be in S record format.
|
||||
.TP
|
||||
\--firmware gps-firmware
|
||||
This specifies the new GPS firmware image to load onto the target GPS
|
||||
chip. No checking is done on this device at all; flash garbage and the
|
||||
GPS chip will probably fail to boot.
|
||||
.TP
|
||||
\--query
|
||||
Instead of loading new firmware, query the current version of firmware
|
||||
running on the target device.
|
||||
.TP
|
||||
\--quiet
|
||||
Normally, ao-spy-flash is quite chatty. This shuts it up, except for
|
||||
error messages.
|
||||
.TP
|
||||
\--raw
|
||||
The expected target for reflashing is an Altus Metrum product with the
|
||||
GPS chip connected to the CPU on that board and not directly to the
|
||||
USB serial port. This option says that the target GPS chip is directly
|
||||
connected, which changes how things are initialized a bit.
|
||||
.SH USAGE
|
||||
.I ao-sky-flash
|
||||
loads the specified bootloader into device RAM and then uses that to
|
||||
load new firmware to flash.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
74
ao-tools/ao-sky-flash/sky_bin.c
Normal file
74
ao-tools/ao-sky-flash/sky_bin.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "sky_flash.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FLASHBYTES 8192
|
||||
|
||||
int
|
||||
skytraq_send_bin(int fd, const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
char buf[FLASHBYTES];
|
||||
int count;
|
||||
unsigned char cksum;
|
||||
int c;
|
||||
long size;
|
||||
long pos;
|
||||
char message[1024];
|
||||
int ret;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
perror(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compute checksum, figure out how long the file */
|
||||
cksum = 0;
|
||||
while ((c = getc(file)) != EOF)
|
||||
cksum += (unsigned char) c;
|
||||
size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
sprintf(message, "BINSIZE = %ld Checksum = %d Loopnumber = %d ", size, cksum, 1);
|
||||
|
||||
ret = skytraq_cmd_wait(fd, message, strlen(message) + 1, "OK", 20000);
|
||||
if (ret < 0)
|
||||
printf ("waitstatus failed %d\n", ret);
|
||||
|
||||
pos = 0;
|
||||
for (;;) {
|
||||
count = fread(buf, 1, sizeof (buf), file);
|
||||
if (count < 0) {
|
||||
perror("fread");
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
if (count == 0)
|
||||
break;
|
||||
skytraq_dbg_printf (0, "%7d of %7d ", pos + count, size);
|
||||
pos += count;
|
||||
ret = skytraq_cmd_wait(fd, buf, count, "OK", 20000);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return skytraq_waitstatus(fd, "END", 30000);
|
||||
}
|
112
ao-tools/ao-sky-flash/sky_debug.c
Normal file
112
ao-tools/ao-sky-flash/sky_debug.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include "sky_flash.h"
|
||||
|
||||
static int dbg_input;
|
||||
static int dbg_newline = 1;
|
||||
|
||||
int
|
||||
skytraq_millis(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
static void
|
||||
skytraq_dbg_time(void)
|
||||
{
|
||||
int delta = skytraq_millis() - skytraq_open_time;
|
||||
|
||||
if (!skytraq_verbose)
|
||||
return;
|
||||
printf ("%4d.%03d ", delta / 1000, delta % 1000);
|
||||
}
|
||||
|
||||
void
|
||||
skytraq_dbg_newline(void)
|
||||
{
|
||||
if (!skytraq_verbose)
|
||||
return;
|
||||
if (!dbg_newline) {
|
||||
putchar('\n');
|
||||
dbg_newline = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
skytraq_dbg_set(int input)
|
||||
{
|
||||
if (!skytraq_verbose)
|
||||
return;
|
||||
if (input != dbg_input) {
|
||||
skytraq_dbg_newline();
|
||||
if (input)
|
||||
putchar('\t');
|
||||
dbg_input = input;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
skytraq_dbg_char(int input, char c)
|
||||
{
|
||||
if (!skytraq_verbose)
|
||||
return;
|
||||
skytraq_dbg_set(input);
|
||||
if (dbg_newline)
|
||||
skytraq_dbg_time();
|
||||
if (c < ' ' || c > '~')
|
||||
printf ("\\%02x", (unsigned char) c);
|
||||
else
|
||||
putchar(c);
|
||||
dbg_newline = 0;
|
||||
if (c == '\n')
|
||||
dbg_input = 2;
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
skytraq_dbg_buf(int input, const char *buf, int len)
|
||||
{
|
||||
if (!skytraq_verbose)
|
||||
return;
|
||||
while (len--)
|
||||
skytraq_dbg_char(input, *buf++);
|
||||
}
|
||||
|
||||
void
|
||||
skytraq_dbg_printf(int input, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (!skytraq_verbose)
|
||||
return;
|
||||
skytraq_dbg_set(input);
|
||||
if (dbg_newline)
|
||||
skytraq_dbg_time();
|
||||
va_start (ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
dbg_newline = 0;
|
||||
}
|
250
ao-tools/ao-sky-flash/sky_flash.c
Normal file
250
ao-tools/ao-sky-flash/sky_flash.c
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "sky_flash.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include "cc.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "tty", .has_arg = 1, .val = 'T' },
|
||||
{ .name = "device", .has_arg = 1, .val = 'D' },
|
||||
{ .name = "firmware", .has_arg = 1, .val = 'f' },
|
||||
{ .name = "query", .has_arg = 0, .val = 'q' },
|
||||
{ .name = "raw", .has_arg = 0, .val = 'r' },
|
||||
{ .name = "quiet", .has_arg = 0, .val = 'Q' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static uint8_t query_version[] = {
|
||||
0xa0, 0xa1, 0x00, 0x02, 0x02, 0x01, 0x03, 0x0d, 0x0a
|
||||
};
|
||||
|
||||
static void
|
||||
usage(char *program)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [--tty <tty-name>]\n"
|
||||
" [--device <device-name>]\n"
|
||||
" [--firmware <binary firmware file>]\n"
|
||||
" [--query]\n"
|
||||
" [--quiet]\n"
|
||||
" [--raw]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
skytraq_expect(int fd, uint8_t want, int timeout) {
|
||||
int c;
|
||||
|
||||
c = skytraq_waitchar(fd, timeout);
|
||||
if (c < 0)
|
||||
return -1;
|
||||
if (c == want)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
skytraq_wait_reply(int fd, uint8_t reply, uint8_t *buf, uint8_t reply_len) {
|
||||
|
||||
for(;;) {
|
||||
uint8_t a, b;
|
||||
uint8_t cksum_computed;
|
||||
int len;
|
||||
switch (skytraq_expect(fd, 0xa0, 10000)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
continue;
|
||||
case 1:
|
||||
break;
|
||||
}
|
||||
switch (skytraq_expect(fd, 0xa1, 1000)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
continue;
|
||||
}
|
||||
a = skytraq_waitchar(fd, 1000);
|
||||
b = skytraq_waitchar(fd, 1000);
|
||||
switch (skytraq_expect(fd, reply, 1000)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
continue;
|
||||
}
|
||||
len = (a << 16) | b;
|
||||
if (len != reply_len)
|
||||
continue;
|
||||
*buf++ = reply;
|
||||
len--;
|
||||
cksum_computed = reply;
|
||||
while (len--) {
|
||||
a = skytraq_waitchar(fd, 1000);
|
||||
if (a < 0)
|
||||
return a;
|
||||
cksum_computed ^= a;
|
||||
*buf++ = a;
|
||||
}
|
||||
switch (skytraq_expect(fd, cksum_computed, 1000)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
continue;
|
||||
}
|
||||
switch (skytraq_expect(fd, 0x0d, 1000)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
continue;
|
||||
}
|
||||
switch (skytraq_expect(fd, 0x0a, 1000)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
int c;
|
||||
char *tty = NULL;
|
||||
char *device = NULL;
|
||||
char *file = NULL;
|
||||
int query = 0;
|
||||
int raw = 0;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "T:D:l:f:qQr", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'T':
|
||||
tty = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
file = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
case 'Q':
|
||||
skytraq_verbose = 0;
|
||||
break;
|
||||
case 'r':
|
||||
raw = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tty)
|
||||
tty = cc_usbdevs_find_by_arg(device, "TeleMetrum");
|
||||
if (!tty)
|
||||
tty = getenv("ALTOS_TTY");
|
||||
if (!tty)
|
||||
tty="/dev/ttyACM0";
|
||||
fd = skytraq_open(tty);
|
||||
if (fd < 0)
|
||||
exit(1);
|
||||
|
||||
if (raw) {
|
||||
/* Set the baud rate to 115200 */
|
||||
skytraq_setcomm(fd, 115200);
|
||||
sleep(1);
|
||||
skytraq_setspeed(fd, 115200);
|
||||
} else {
|
||||
/* Connect TM to the device */
|
||||
skytraq_write(fd, "U\n", 2);
|
||||
}
|
||||
|
||||
/* Wait for the device to stabilize after baud rate changes */
|
||||
for (c = 0; c < 6; c++) {
|
||||
skytraq_flush(fd);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
if (query) {
|
||||
uint8_t query_reply[14];
|
||||
|
||||
uint8_t software_type;
|
||||
uint32_t kernel_version;
|
||||
uint32_t odm_version;
|
||||
uint32_t revision;
|
||||
|
||||
skytraq_write(fd, query_version, 9);
|
||||
if (skytraq_wait_reply(fd, 0x80, query_reply, sizeof (query_reply)) != 0) {
|
||||
fprintf(stderr, "query reply failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define i8(o) query_reply[(o)-1]
|
||||
#define i32(o) ((i8(o) << 24) | (i8(o+1) << 16) | (i8(o+2) << 8) | (i8(o+3)))
|
||||
software_type = i8(2);
|
||||
kernel_version = i32(3);
|
||||
odm_version = i32(7);
|
||||
revision = i32(11);
|
||||
skytraq_dbg_printf(0, "\n");
|
||||
printf ("Software Type %d. Kernel Version %d.%d.%d. ODM Version %d.%d.%d. Revision %d.%d.%d.\n",
|
||||
software_type,
|
||||
kernel_version >> 16 & 0xff,
|
||||
kernel_version >> 8 & 0xff,
|
||||
kernel_version >> 0 & 0xff,
|
||||
odm_version >> 16 & 0xff,
|
||||
odm_version >> 8 & 0xff,
|
||||
odm_version >> 0 & 0xff,
|
||||
revision >> 16 & 0xff,
|
||||
revision >> 8 & 0xff,
|
||||
revision >> 0 & 0xff);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!file)
|
||||
usage(argv[0]);
|
||||
|
||||
ret = skytraq_send_srec(fd, "srec_115200.bin");
|
||||
skytraq_dbg_printf (0, "srec ret %d\n", ret);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// ret = skytraq_send_bin(fd, "STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin");
|
||||
ret = skytraq_send_bin(fd, "STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin");
|
||||
|
||||
printf ("bin ret %d\n", ret);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
return 0;
|
||||
}
|
74
ao-tools/ao-sky-flash/sky_flash.h
Normal file
74
ao-tools/ao-sky-flash/sky_flash.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* sky_serial.c */
|
||||
|
||||
extern int skytraq_open_time;
|
||||
extern int skytraq_verbose;
|
||||
|
||||
int
|
||||
skytraq_open(const char *path);
|
||||
|
||||
int
|
||||
skytraq_setspeed(int fd, int baud);
|
||||
|
||||
int
|
||||
skytraq_setcomm(int fd, int baudrate);
|
||||
|
||||
int
|
||||
skytraq_write(int fd, const void *data, int len);
|
||||
|
||||
int
|
||||
skytraq_waitchar(int fd, int timeout);
|
||||
|
||||
int
|
||||
skytraq_waitstatus(int fd, const char *status, int timeout);
|
||||
|
||||
void
|
||||
skytraq_flush(int fd);
|
||||
|
||||
int
|
||||
skytraq_millis(void);
|
||||
|
||||
void
|
||||
skytraq_dbg_newline(void);
|
||||
|
||||
int
|
||||
skytraq_cmd_wait(int fd, const char *message, int len, const char *status, int timeout);
|
||||
|
||||
int
|
||||
skytraq_cmd_nowait(int fd, const char *message, int len);
|
||||
|
||||
/* sky_debug.c */
|
||||
|
||||
void
|
||||
skytraq_dbg_printf(int input, const char *fmt, ...);
|
||||
|
||||
void
|
||||
skytraq_dbg_buf(int input, const char *buf, int len);
|
||||
|
||||
void
|
||||
skytraq_dbg_char(int input, char c);
|
||||
|
||||
/* sky_srec.c */
|
||||
int
|
||||
skytraq_send_srec(int fd, const char *file);
|
||||
|
||||
/* sky_bin.c */
|
||||
int
|
||||
skytraq_send_bin(int fd, const char *filename);
|
256
ao-tools/ao-sky-flash/sky_serial.c
Normal file
256
ao-tools/ao-sky-flash/sky_serial.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 _DEFAULT_SOURCE 1
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include "sky_flash.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int skytraq_verbose = 1;
|
||||
|
||||
int
|
||||
skytraq_setspeed(int fd, int baud)
|
||||
{
|
||||
int b;
|
||||
int ret;
|
||||
struct termios term;
|
||||
|
||||
switch (baud) {
|
||||
case 9600:
|
||||
b = B9600;
|
||||
break;
|
||||
case 38400:
|
||||
b = B38400;
|
||||
break;
|
||||
case 115200:
|
||||
b = B115200;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "Invalid baudrate %d\n", baud);
|
||||
return -1;
|
||||
}
|
||||
ret = tcgetattr(fd, &term);
|
||||
cfmakeraw(&term);
|
||||
#ifdef USE_POLL
|
||||
term.c_cc[VMIN] = 1;
|
||||
term.c_cc[VTIME] = 0;
|
||||
#else
|
||||
term.c_cc[VMIN] = 0;
|
||||
term.c_cc[VTIME] = 1;
|
||||
#endif
|
||||
|
||||
cfsetspeed(&term, b);
|
||||
|
||||
ret = tcsetattr(fd, TCSAFLUSH, &term);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int skytraq_open_time;
|
||||
|
||||
int
|
||||
skytraq_open(const char *path)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
fd = open(path, O_RDWR | O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
perror (path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = skytraq_setspeed(fd, 9600);
|
||||
if (ret < 0) {
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
skytraq_open_time = skytraq_millis();
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
#define BAUD 57600
|
||||
#define BPS (BAUD/10 * 9/10)
|
||||
#define US_PER_CHAR (1000000 / BPS)
|
||||
|
||||
int
|
||||
skytraq_write(int fd, const void *d, int len)
|
||||
{
|
||||
const char *data = d;
|
||||
int r;
|
||||
|
||||
skytraq_dbg_printf (0, "%4d: ", len);
|
||||
if (len < 70)
|
||||
skytraq_dbg_buf(0, data, len);
|
||||
while (len) {
|
||||
int this_time = len;
|
||||
if (this_time > 128)
|
||||
this_time = 128;
|
||||
skytraq_dbg_printf(0, ".");
|
||||
fflush(stdout);
|
||||
r = write(fd, data, this_time);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
usleep(r * US_PER_CHAR);
|
||||
data += r;
|
||||
len -= r;
|
||||
}
|
||||
skytraq_dbg_newline();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
skytraq_setcomm(int fd, int baudrate)
|
||||
{
|
||||
uint8_t msg[11];
|
||||
int i;
|
||||
uint8_t cksum;
|
||||
|
||||
int target_baudrate = 0;
|
||||
switch(baudrate)
|
||||
{
|
||||
case 4800:
|
||||
target_baudrate=0;
|
||||
break;
|
||||
case 9600:
|
||||
target_baudrate=1;
|
||||
break;
|
||||
case 19200:
|
||||
target_baudrate=2;
|
||||
break;
|
||||
case 38400:
|
||||
target_baudrate=3;
|
||||
break;
|
||||
case 57600:
|
||||
target_baudrate=4;
|
||||
break;
|
||||
case 115200:
|
||||
target_baudrate=5;
|
||||
break;
|
||||
case 230400:
|
||||
target_baudrate=6;
|
||||
break;
|
||||
}
|
||||
msg[0] = 0xa0; /* header */
|
||||
msg[1] = 0xa1;
|
||||
msg[2] = 0x00; /* length */
|
||||
msg[3] = 0x04;
|
||||
msg[4] = 0x05; /* configure serial port */
|
||||
msg[5] = 0x00; /* COM 1 */
|
||||
msg[6] = target_baudrate;
|
||||
msg[7] = 0x00; /* update to SRAM only */
|
||||
|
||||
cksum = 0;
|
||||
for (i = 4; i < 8; i++)
|
||||
cksum ^= msg[i];
|
||||
msg[8] = cksum;
|
||||
msg[9] = 0x0d;
|
||||
msg[10] = 0x0a;
|
||||
return skytraq_write(fd, msg, 11);
|
||||
}
|
||||
|
||||
int
|
||||
skytraq_waitchar(int fd, int timeout)
|
||||
{
|
||||
struct pollfd fds[1];
|
||||
int ret;
|
||||
unsigned char c;
|
||||
|
||||
for (;;) {
|
||||
fds[0].fd = fd;
|
||||
fds[0].events = POLLIN;
|
||||
ret = poll(fds, 1, timeout);
|
||||
if (ret >= 1) {
|
||||
if (fds[0].revents & POLLIN) {
|
||||
ret = read(fd, &c, 1);
|
||||
if (ret == 1) {
|
||||
skytraq_dbg_char(1, c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
} else if (ret == 0)
|
||||
return -2;
|
||||
else {
|
||||
perror("poll");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
skytraq_waitstatus(int fd, const char *status, int timeout)
|
||||
{
|
||||
const char *s;
|
||||
int c;
|
||||
|
||||
for (;;) {
|
||||
c = skytraq_waitchar(fd, timeout);
|
||||
if (c < 0) {
|
||||
skytraq_dbg_newline();
|
||||
return c;
|
||||
}
|
||||
if ((char) c == *status) {
|
||||
s = status + 1;
|
||||
for (;;) {
|
||||
c = skytraq_waitchar(fd, timeout);
|
||||
if (c < 0) {
|
||||
skytraq_dbg_newline();
|
||||
return c;
|
||||
}
|
||||
if ((char) c != *s)
|
||||
break;
|
||||
if (!*s) {
|
||||
skytraq_dbg_newline();
|
||||
return 0;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
skytraq_flush(int fd)
|
||||
{
|
||||
while (skytraq_waitchar(fd, 1) >= 0)
|
||||
;
|
||||
}
|
||||
|
||||
int
|
||||
skytraq_cmd_wait(int fd, const char *message, int len, const char *status, int timeout)
|
||||
{
|
||||
skytraq_flush(fd);
|
||||
skytraq_write(fd, message, len);
|
||||
return skytraq_waitstatus(fd, status, timeout);
|
||||
}
|
||||
|
||||
int
|
||||
skytraq_cmd_nowait(int fd, const char *message, int len)
|
||||
{
|
||||
skytraq_flush(fd);
|
||||
return skytraq_write(fd, message, len);
|
||||
}
|
61
ao-tools/ao-sky-flash/sky_srec.c
Normal file
61
ao-tools/ao-sky-flash/sky_srec.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "sky_flash.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char loader_start[] = "$LOADER DOWNLOAD";
|
||||
|
||||
int
|
||||
skytraq_send_srec(int fd, const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
int ret;
|
||||
char line[1024];
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
perror(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = skytraq_cmd_wait(fd, loader_start, strlen(loader_start) + 1, "OK", 1000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (;;) {
|
||||
char *s;
|
||||
int len;
|
||||
|
||||
s = fgets(line, sizeof(line), file);
|
||||
if (!s)
|
||||
break;
|
||||
len = strlen(s);
|
||||
if (len < 3) /* Terminated with \r\n */
|
||||
break;
|
||||
s[len-2] = '\n'; /* Smash \r */
|
||||
s[len-1] = '\0'; /* Smash \n */
|
||||
skytraq_cmd_nowait(fd, s, len);
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
ret = skytraq_waitstatus(fd, "END", 10000);
|
||||
skytraq_dbg_newline();
|
||||
return ret;
|
||||
}
|
346
ao-tools/ao-sky-flash/srec_115200.bin
Normal file
346
ao-tools/ao-sky-flash/srec_115200.bin
Normal file
@@ -0,0 +1,346 @@
|
||||
S0130000666C6173683131353230302E73726563DA
|
||||
S31550000000033FFFF7821063209DE380011920000013
|
||||
S31550000010D2030000173FFFF79612E3E4AC07BFF890
|
||||
S31550000020D225800BD005800B133FFFC0900A0009E4
|
||||
S3155000003090122977D0230000E00320901B0800136C
|
||||
S31550000040C0232090D20320149E136018D225800B13
|
||||
S31550000050D005800B1300180090120009900A3FF04B
|
||||
S31550000060D0232014D20300001100003FD225800B6C
|
||||
S31550000070D405800B901223FF940A800813043E0087
|
||||
S3155000008094128009D4230000D003C0009A13601C38
|
||||
S31550000090D025800BD205800B11004000902A4008D5
|
||||
S315500000A0D023C000D403400011000040D425800B5B
|
||||
S315500000B0D205800BA00C204092124008A13C20068D
|
||||
S315500000C011140005E02A2180D2234000B8102000E8
|
||||
S315500000D0400004C890102005130004004000017031
|
||||
S315500000E090102001213FFFF84000036F90058010CB
|
||||
S315500000F0A014200A92058010B6102000B4102000DB
|
||||
S31550000100A6102000AE10200096102000D00A400005
|
||||
S3155000011080A2202002800006920260019602E00131
|
||||
S3155000012080A2E06324BFFFFBD00A40009810200055
|
||||
S3155000013080A3000B1680000F113FFFF89012200A83
|
||||
S31550000140940580089810000B912CE0029002001341
|
||||
S31550000150D20A8000912A200190020009A6023FD0BF
|
||||
S3155000016098833FFF12BFFFF99402A0019810000B2D
|
||||
S315500001709205800C113FFFF894024008961020001B
|
||||
S315500001809002800BD20A201680A2602002800007BF
|
||||
S3155000019080A2E0009602E00180A2E06304BFFFFA6D
|
||||
S315500001A09002800B80A2E0000480000F113FFFF800
|
||||
S315500001B09205800C9012201698024008900DE0FF90
|
||||
S315500001C0932A2002D40B000092024008932A600121
|
||||
S315500001D094028009AE02BFD09682FFFF12BFFFF88D
|
||||
S315500001E098032001133FFFF794126384921263869B
|
||||
S315500001F090078009400001A89207800A80A220003B
|
||||
S3155000020002800122153FFFF79012A386D21780086D
|
||||
S3155000021080A2601C0280010E9012A384113FFFF74A
|
||||
S31550000220961223849012238692102037D237800854
|
||||
S31550000230941020B5D437800B900F2001213FFFF743
|
||||
S31550000240AB2A201392142386110001E1D41780099A
|
||||
S3155000025090122154A2142384A4054008D617801165
|
||||
S3155000026090100012400002289210202080A22000F8
|
||||
S31550000270028000CA11140005B0100010B21000110F
|
||||
S31550000280A0102000113FFFEA80A420000280000445
|
||||
S315500002909212225511000015921221AA912A60102D
|
||||
S315500002A0A8162386A3322010D617801990048010E2
|
||||
S315500002B0D417801492102002400001DA98100011D1
|
||||
S315500002C080A22000028000B511140005D0148010C1
|
||||
S315500002D080A44008128000B0A004200280A420030D
|
||||
S315500002E004BFFFEA113FFFEA213FFFF79214238430
|
||||
S315500002F0D617800990100012D417801440000202BD
|
||||
S3155000030092102020170001DF9012E3F8D20200006D
|
||||
S31550000310941423E4D225800AA01423E0C02580102B
|
||||
S31550000320D005800A80A23FFF228000BB9012E3FCDA
|
||||
S31550000330113FFFF7A2122384A0122386110001C198
|
||||
S31550000340D417801090122154D61780119210202065
|
||||
S31550000350400001ED90054008110001E9D4178010C6
|
||||
S3155000036090122154D617801192102020400001E699
|
||||
S3155000037090054008110001F1D417801090122154B5
|
||||
S31550000380D617801192102020400001DF90054008BA
|
||||
S31550000390133FFFF8D00D800980A220421280000B37
|
||||
S315500003A0A410001392058009D00A600180A220494A
|
||||
S315500003B03280000721140005D00A600280A2204E28
|
||||
S315500003C022800008D417801021140005400002F640
|
||||
S315500003D09014202890142028400002F39E03FCF02D
|
||||
S315500003E090102000D6178011400001C792100013BC
|
||||
S315500003F080A2200022800069111400051114000506
|
||||
S31550000400400002E990122030400000BE010000007A
|
||||
S3155000041011000007A81223FFB010001480A4801406
|
||||
S31550000420148000031300000892100012113FFFF8C9
|
||||
S315500004304000036F90058008A2922000028000734E
|
||||
S31550000440A010200080A40011B40680111A8000214B
|
||||
S31550000450A4248011333FFFF71100003FAA1223FF57
|
||||
S31550000460BA1663849810001092102000A00420023F
|
||||
S31550000470173FFFF89005800CD40A000B932A6008AA
|
||||
S315500004809803200180A3001006BFFFFB9212400A7A
|
||||
S31550000490912A60109932201080A300150280000A1C
|
||||
S315500004A090166386D417800892102002D617801DA6
|
||||
S315500004B04000015C9010001B80A220000280003793
|
||||
S315500004C01114000580A400110ABFFFE7B606E0022A
|
||||
S315500004D0900E801880A0000892603FFF80A0001206
|
||||
S315500004E090603FFF809240080280000680A68013ED
|
||||
S315500004F011140005400002AC9012203080A68013E3
|
||||
S3155000050012BFFFC880A480149410200080A28013CC
|
||||
S315500005101680000996102000D21280009132600891
|
||||
S315500005209002C0089402A00280A2801306BFFFFB6F
|
||||
S3155000053096020009920AE0FF900DE0FF80A2400863
|
||||
S31550000540028000041114000510BFFFA49012203839
|
||||
S31550000550153FFFF79012A3E0D205800880A26001F4
|
||||
S31550000560128000109212A3849012A386D41780088A
|
||||
S3155000057098102A01D6178009110001DF901223FC2A
|
||||
S31550000580400001289210200280A22000128000060E
|
||||
S31550000590211400051114000510BFFF909012202061
|
||||
S315500005A02114000540000280901420404000027E35
|
||||
S315500005B090142040901020F013080013D0302000E3
|
||||
S315500005C092126020D012400015200000900A3FFE83
|
||||
S315500005D0D03240009612A04C90102010D022C0006D
|
||||
S315500005E0D802C0009412A0B813080004D822800084
|
||||
S315500005F092126014D0024000900A3FFED022400072
|
||||
S3155000060010800000010000001114000510BFFF7398
|
||||
S3155000061090122048D20200001102807FD225800A13
|
||||
S31550000620901223FFD0258010D205800AD005801065
|
||||
S3155000063080A2400832BFFF40113FFFF790102001C3
|
||||
S31550000640D025801010BFFF3C113FFFF7D61780080A
|
||||
S31550000650921AE0B980A0000994603FFF901AE0DA40
|
||||
S3155000066080A0000892603FFF8092800902BFFEED95
|
||||
S31550000670113FFFF780A2E0DA22BFFEF0B81020014A
|
||||
S3155000068010BFFEEF900F20012114000540000246D6
|
||||
S315500006909014205030BFFFFE01000000941020F04F
|
||||
S315500006A019080013D430200098132020170800048E
|
||||
S315500006B0D41300008212E01417200000940ABFFEE3
|
||||
S315500006C09A12E0B8D4330000900A20FF9612E04CFC
|
||||
S315500006D0D222C00080A22001128000070100000033
|
||||
S315500006E0D202C000D2234000D0004000900A3FFE04
|
||||
S315500006F0D02040000100000081C3E0080100000046
|
||||
S315500007001308000492126014D00240009012200187
|
||||
S31550000710D02240000100000081C3E0080100000023
|
||||
S315500007209C03BF90D233A066D213A06696100008E1
|
||||
S31550000730920A6080D012000080A0000994402000E8
|
||||
S31550000740900A208080A000089240200080A2400A93
|
||||
S315500007500280000D01000000D012C000808A2020C7
|
||||
S315500007601280000901000000D012C000900A2080BB
|
||||
S3155000077080A000089240200080A2400A12BFFFF7D6
|
||||
S3155000078001000000D012C000900A208080A000080E
|
||||
S3155000079090402000901A000A901A20010100000093
|
||||
S315500007A081C3E0089C23BF909DE3BF90B20E60FFCB
|
||||
S315500007B0A0100018C027BFF480A660BA14800006A7
|
||||
S315500007C080A660DA80A660B916800006153FFFEA5B
|
||||
S315500007D080A660B512800027B0102000153FFFEAB2
|
||||
S315500007E096102AAA9412A2AA13000015D432C00059
|
||||
S315500007F09212615598102554113FFFE0D2330000F4
|
||||
S3155000080090122080D032C000D432C000D2330000C3
|
||||
S315500008101100000C2300003F90122030130000C33B
|
||||
S31550000820D0340000A412613FB21463FF921463FFE8
|
||||
S315500008307FFFFFBC90100010B0100008D007BFF427
|
||||
S3155000084090022001D027BFF4D214000080A64009A0
|
||||
S315500008500280000880A620011280000601000000D8
|
||||
S31550000860D007BFF480A2001208BFFFF2921463FFB4
|
||||
S31550000870D007BFF4130000C39212613F80A2400814
|
||||
S3155000088094403FFFB00E000A0100000081C7E00807
|
||||
S3155000089081E80000153FFFEA98102AAA9412A2AAEE
|
||||
S315500008A0D4330000170000159612E155153FFFE4AA
|
||||
S315500008B0D63025549412A090D4330000D61022007E
|
||||
S315500008C09A100008960AE0FFD6320000901030F0D9
|
||||
S315500008D0D0330000D613400098100009901AE03724
|
||||
S315500008E080A0000894603FFF901AE01C80A000088A
|
||||
S315500008F092603FFF8092800912800007821020008C
|
||||
S3155000090080A2E0C20280000480A2E0201280004251
|
||||
S3155000091090102000113FFFEA94102AAA901222AAA2
|
||||
S31550000920D03280001300001592126155113FFFE43A
|
||||
S31550000930D230255490122090D0328000D21022020C
|
||||
S31550000940901030F0920A60FFD2330000D03280000F
|
||||
S31550000950D013400080A220370280002A80A2202097
|
||||
S31550000960D41300000280001D912AA0109002BF47A8
|
||||
S31550000970912A201091322010952AA01080A2200290
|
||||
S315500009809532A01092602000901AA0B580A0000861
|
||||
S31550000990920A600190603FFF809240083280000BBF
|
||||
S315500009A08210200180A2A0B90280000A80A2A0BABB
|
||||
S315500009B00280000880A2A0EF0280000680A2A0DA82
|
||||
S315500009C02280000282102001108000139010000136
|
||||
S315500009D010BFFFFE821020019132201080A220EE1F
|
||||
S315500009E012BFFFE49002BF479010201CD033400046
|
||||
S315500009F0921020B9D233000010BFFFDD941020B9F9
|
||||
S31550000A00D413000080A2A03402BFFFF880A2202099
|
||||
S31550000A1030BFFFD50100000081C3E008010000008F
|
||||
S31550000A209DE3BF88B72EE010C037BFF4B736E0104D
|
||||
S31550000A30A0100018C027BFEC80A6E0BA14800006AC
|
||||
S31550000A4080A6E0DA80A6E0B916800006113FFFEADC
|
||||
S31550000A5080A6E0B512800023B0102000113FFFEAB7
|
||||
S31550000A6094102AAA901222AAD032800013000015A0
|
||||
S31550000A7092126155113FFFE8D2302554901220A0B2
|
||||
S31550000A80D0328000F837BFF2D017BFF2130000C340
|
||||
S31550000A90D0340000B612613FD217BFF27FFFFF215C
|
||||
S31550000AA090100010B0100008D007BFEC9002200143
|
||||
S31550000AB0D027BFECD2140000D017BFF280A2000995
|
||||
S31550000AC00280000880A62001128000060100000066
|
||||
S31550000AD0D007BFEC80A2001B08BFFFF0010000004A
|
||||
S31550000AE0D007BFEC130000C39212613F80A24008AA
|
||||
S31550000AF094403FFFB00E000A0100000081C7E00895
|
||||
S31550000B0081E800009DE3BF9811140005D4022150DE
|
||||
S31550000B10A210200080A4400AA410001B9A102000A6
|
||||
S31550000B20A0102000A610200116800012961020005A
|
||||
S31550000B30912EA010B5322010932EE0109810000A76
|
||||
S31550000B40111400059332601094122060D002A00C4C
|
||||
S31550000B5080A2001A22800048D002A0109602E0011E
|
||||
S31550000B6080A2C00C06BFFFFA9402A05011140005D3
|
||||
S31550000B70D202215080A2C009028000449010200168
|
||||
S31550000B8080A6200008800016912AE0029002000BF1
|
||||
S31550000B9013140005B4126060992A20049E10200197
|
||||
S31550000BA0912C200290020010912A200290030008F6
|
||||
S31550000BB09002001AD4022004A2046001D202200836
|
||||
S31550000BC080A4400A932BC0099A034009A0643FFFB2
|
||||
S31550000BD080A6000D18BFFFF4912C200280A660005D
|
||||
S31550000BE00480001F932AE0029202400BB60CA0FF2D
|
||||
S31550000BF011140005A4122060B52A60049210001B3F
|
||||
S31550000C007FFFFEEA90100018932C200292024010AB
|
||||
S31550000C10932A6002920680099402401280A2200014
|
||||
S31550000C2002800013A2046001D202A0089010200195
|
||||
S31550000C30912A000980A64008B00600080680000ADE
|
||||
S31550000C40B2264008D002A00480A44008A0643FFF0A
|
||||
S31550000C5080A6600014BFFFEB9210001B1080000BA3
|
||||
S31550000C6090100013108000099010200110BFFFFC57
|
||||
S31550000C70A610200080A2000932BFFFBA9602E001FA
|
||||
S31550000C8010BFFFBC1114000581C7E00891E80008A9
|
||||
S31550000C9013140005D40A61801708000013000013CE
|
||||
S31550000CA09212630C952AA00294028009D202C00ABD
|
||||
S31550000CB0941000089132601F80A22001028000002B
|
||||
S31550000CC09132601D808A20012280000490102001FC
|
||||
S31550000CD0C022800030800002D022800081C3E0080C
|
||||
S31550000CE09010000911140005D20A21801508000041
|
||||
S31550000CF0110000139012230C932A600292024008AE
|
||||
S31550000D00D20280099132601F80A220010280000029
|
||||
S31550000D100100000081C3E008901000099DE3BF90D8
|
||||
S31550000D2011140005E00A2180B00E20FF11140005B1
|
||||
S31550000D3090122154B12E2002E2020018A12C20025A
|
||||
S31550000D40110000139012230CA00400087FFFFFD15E
|
||||
S31550000D509007BFF4D207BFF411060000932A601E15
|
||||
S31550000D60921240112308000092124008D2244010DB
|
||||
S31550000D707FFFFFC89007BFF4D207BFF411070000EA
|
||||
S31550000D80932A601E92124008D22440107FFFFFC162
|
||||
S31550000D909007BFF4D207BFF411030000932A601ED8
|
||||
S31550000DA092124008D22440107FFFFFBA9007BFF43A
|
||||
S31550000DB0D207BFF41104000090122003932A601E3C
|
||||
S31550000DC092124008D22440107FFFFFB29007BFF422
|
||||
S31550000DD0D207BFF411050000932A601E92124008F4
|
||||
S31550000DE0D22440107FFFFFC0010000000100000028
|
||||
S31550000DF081C7E00881E800009DE3BF90111400050B
|
||||
S31550000E00E00A218025080000110000139012230CDF
|
||||
S31550000E10A12C2002A00400087FFFFF9E9007BFF47C
|
||||
S31550000E20D207BFF411050000932A601E92124008A3
|
||||
S31550000E30D22480107FFFFF979007BFF4A2100008BE
|
||||
S31550000E40D007BFF427040000912A201E90120013E9
|
||||
S31550000E50D02480107FFFFF8F9007BFF4D207BFF4D6
|
||||
S31550000E6011040004932A601E92124008D224801066
|
||||
S31550000E707FFFFF889007BFF4D007BFF4A20C60FF36
|
||||
S31550000E80912A201E9012001190120013D024801027
|
||||
S31550000E907FFFFF95010000000100000081C7E008B8
|
||||
S31550000EA081E800009DE3BF9011140005D20A21800D
|
||||
S31550000EB02708000011000013932A60029012230C99
|
||||
S31550000EC09202400893326002AC100009AB2A6002CD
|
||||
S31550000ED0AE1000097FFFFF6F9007BFF4D007BFF435
|
||||
S31550000EE023030000912A201E90120011D024C01511
|
||||
S31550000EF07FFFFF7D0100000091322016A08A200F4F
|
||||
S31550000F0032800011A2102000A4100011A32DA002BF
|
||||
S31550000F107FFFFF609007BFF4D207BFF4932A601E8D
|
||||
S31550000F2092124012D224C0117FFFFF6F01000000C1
|
||||
S31550000F3091322016A08A200F02BFFFF60100000052
|
||||
S31550000F40A210200080A440101ABFFFE3A52DE00296
|
||||
S31550000F50290100007FFFFF4F9007BFF4D007BFF471
|
||||
S31550000F60A2046001912A201E90120014D024C012AF
|
||||
S31550000F707FFFFF5D01000000D02E0000808A20FF19
|
||||
S31550000F8002800006B006200180A440100ABFFFF27E
|
||||
S31550000F900100000030BFFFD00100000081C7E0080B
|
||||
S31550000FA081E800009DE3BF9011140005D20A21800C
|
||||
S31550000FB025080000D40E000011000013932A600289
|
||||
S31550000FC09012230C80A2A000028000849202400856
|
||||
S31550000FD0AD2A60109135A012A72A2002AA10000847
|
||||
S31550000FE0A81000137FFFFF2B9007BFF4D007BFF464
|
||||
S31550000FF021030000912A201E90120010D024801345
|
||||
S315500010007FFFFF3901000000900A200680A22006CB
|
||||
S315500010100280001001000000A2100010A12D6002F5
|
||||
S315500010207FFFFF1C9007BFF4D207BFF4932A601EC0
|
||||
S3155000103092124011D22480107FFFFF2B0100000036
|
||||
S31550001040900A200680A2200612BFFFF6010000007B
|
||||
S315500010507FFFFF109007BFF4D007BFF4D20E0000F9
|
||||
S31550001060912A201E90120009D02480147FFFFF1E63
|
||||
S31550001070B0062001D00E000080A2200012BFFFDA79
|
||||
S31550001080010000009135A010D404800880A2A00071
|
||||
S315500010900680004C010000009132A01D808A20017C
|
||||
S315500010A00280004690102001C027BFF4D007BFF43D
|
||||
S315500010B013030000912A201E901200099335A010A8
|
||||
S315500010C0D0248009D404800980A2A0000680003470
|
||||
S315500010D0900AA00680A22006028000169135A01222
|
||||
S315500010E09A1000089E102001972A2002190300002A
|
||||
S315500010F09132A01D808A2001128000039210200098
|
||||
S315500011009210000F912A601E9012000CD024800B72
|
||||
S31550001110D404800B80A2A0000680001A900AA00674
|
||||
S3155000112080A2200612BFFFF49132A01DD227BFF431
|
||||
S315500011309132A01D808A200102800010901020015B
|
||||
S31550001140C027BFF4D007BFF49335A010912A201EB4
|
||||
S31550001150D0248009D404800980A2A00016800021E2
|
||||
S3155000116090100009D404800880A2A00006BFFFFE9C
|
||||
S31550001170010000003080001B10BFFFF3D027BFF4E2
|
||||
S31550001180912B6002D404800880A2A00006BFFFFE07
|
||||
S315500011900100000010BFFFE3900AA006901000095E
|
||||
S315500011A0D404800880A2A00006BFFFFE0100000004
|
||||
S315500011B010BFFFC9900AA00610BFFFBDD027BFF4CD
|
||||
S315500011C0D404800880A2A00006BFFFFE01000000E4
|
||||
S315500011D010BFFFB39132A01D10BFFFABAD2A6010F8
|
||||
S315500011E00100000081C7E00881E800009DE3BF9838
|
||||
S315500011F035140005F60EA180921000183500001324
|
||||
S31550001200B416A30CB72EE002B606C01A992EE010FB
|
||||
S31550001210B53320129B2EA002A210001AA610001958
|
||||
S315500012203B080000961020009410000DA410001AE0
|
||||
S31550001230F807400D80A7200006800064B137201DB6
|
||||
S31550001240B00E200180A00018B0603FFFB12E201EC6
|
||||
S3155000125033030000B0160019F027400AF807400A79
|
||||
S3155000126080A7200006800052B1372016B48E200F7A
|
||||
S315500012701280001A82102000B3332012310003D09E
|
||||
S31550001280901000199E162240B32E600237030000BC
|
||||
S3155000129080A0400F8200600118800053B0102000DB
|
||||
S315500012A0B137201DB00E200180A00018B0603FFF5E
|
||||
S315500012B0B12E201EB016001BF0274019F807401912
|
||||
S315500012C080A7200006800033B1372016B48E200F39
|
||||
S315500012D002BFFFF180A0400F8210200080A0401A6C
|
||||
S315500012E01ABFFFD4B1332012B72E20029010001827
|
||||
S315500012F09E10001BA0100018F807401B80A7200066
|
||||
S315500013000680001DB137201DB00E200180A00018A8
|
||||
S31550001310B0603FFFB12E201E33010000B0160019F9
|
||||
S31550001320F027400FF807400F80A720000680000CDA
|
||||
S31550001330B12C20029602E001F82A400080A2C01388
|
||||
S3155000134002800029B010000B8200600180A0401A74
|
||||
S315500013500ABFFFEA9202600130BFFFB6F807401895
|
||||
S3155000136080A7200006BFFFFE0100000010BFFFF35C
|
||||
S315500013709602E001B12A2002F807401880A7200003
|
||||
S3155000138006BFFFFE0100000010BFFFE0B137201D71
|
||||
S31550001390B12A2002F807401880A7200006BFFFFE9A
|
||||
S315500013A00100000010BFFFCAB1372016B12CA002B1
|
||||
S315500013B0F807401880A7200006BFFFFE0100000076
|
||||
S315500013C010BFFFABB1372016B12C6002F80740189A
|
||||
S315500013D080A7200006BFFFFE0100000010BFFF9946
|
||||
S315500013E0B137201D0100000081C7E00881E80000E8
|
||||
S315500013F09DE3BF987FFFFE81B00E20FF7FFFFE4822
|
||||
S3155000140081E800000100000000000000000000001C
|
||||
S315500014100000000000000000000000000000000076
|
||||
S315500014204572726F723400004572726F72330000EB
|
||||
S315500014304F4B0000000000004572726F7232000080
|
||||
S31550001440454E4400000000004572726F7235000030
|
||||
S315500014504572726F723100000000000000000000FB
|
||||
S3155000146000000000000000010000000E00000037E0
|
||||
S31550001470000000B500004000000000030000000D11
|
||||
S3155000148000000037000000B5000080000000000496
|
||||
S315500014900000000F00000037000000B500010000FA
|
||||
S315500014A00000000B0000001000000037000000B5DF
|
||||
S315500014B00000000000000007000000100000001CA3
|
||||
S315500014C0000000B900007000000000080000000F86
|
||||
S315500014D00000001C000000B9000078000000000A5F
|
||||
S315500014E00000000D0000001C000000B900007C0048
|
||||
S315500014F00000000B0000000E0000001C000000B9A8
|
||||
S31550001500000000000000000F000000100000001C4A
|
||||
S31550001510000000DA00007000000000100000000F0C
|
||||
S315500015200000001C000000DA0000700000000012ED
|
||||
S315500015300000000D0000001C000000DA00007000E2
|
||||
S31550001540000000130000000E0000001C000000DA2E
|
||||
S3155000155000000003000001AA000000D50000006A48
|
||||
S3155000156000000035000000230000001100000008B4
|
||||
S3115000157000000000000000000000000019
|
||||
S70550000000AA
|
346
ao-tools/ao-sky-flash/srec_9600.bin
Normal file
346
ao-tools/ao-sky-flash/srec_9600.bin
Normal file
@@ -0,0 +1,346 @@
|
||||
S0190000666C6173685F3139646F74355F393630302E737265638A
|
||||
S31550000000033FFFF7821063209DE380011920000013
|
||||
S31550000010D2030000173FFFF79612E3E4AC07BFF890
|
||||
S31550000020D225800BD005800B133FFFC0900A0009E4
|
||||
S3155000003090122977D0230000E00320901B0800136C
|
||||
S31550000040C0232090D20320149E136018D225800B13
|
||||
S31550000050D005800B1300180090120009900A3FF04B
|
||||
S31550000060D0232014D20300001100003FD225800B6C
|
||||
S31550000070D405800B901223FF940A800813043E0087
|
||||
S3155000008094128009D4230000D003C0009A13601C38
|
||||
S31550000090D025800BD205800B11004000902A4008D5
|
||||
S315500000A0D023C000D403400011000040D425800B5B
|
||||
S315500000B0D205800BA00C204092124008A13C20068D
|
||||
S315500000C011140005E02A2180D2234000B8102000E8
|
||||
S315500000D0400004C890102001130004004000017035
|
||||
S315500000E090102001213FFFF84000036F90058010CB
|
||||
S315500000F0A014200A92058010B6102000B4102000DB
|
||||
S31550000100A6102000AE10200096102000D00A400005
|
||||
S3155000011080A2202002800006920260019602E00131
|
||||
S3155000012080A2E06324BFFFFBD00A40009810200055
|
||||
S3155000013080A3000B1680000F113FFFF89012200A83
|
||||
S31550000140940580089810000B912CE0029002001341
|
||||
S31550000150D20A8000912A200190020009A6023FD0BF
|
||||
S3155000016098833FFF12BFFFF99402A0019810000B2D
|
||||
S315500001709205800C113FFFF894024008961020001B
|
||||
S315500001809002800BD20A201680A2602002800007BF
|
||||
S3155000019080A2E0009602E00180A2E06304BFFFFA6D
|
||||
S315500001A09002800B80A2E0000480000F113FFFF800
|
||||
S315500001B09205800C9012201698024008900DE0FF90
|
||||
S315500001C0932A2002D40B000092024008932A600121
|
||||
S315500001D094028009AE02BFD09682FFFF12BFFFF88D
|
||||
S315500001E098032001133FFFF794126384921263869B
|
||||
S315500001F090078009400001A89207800A80A220003B
|
||||
S3155000020002800122153FFFF79012A386D21780086D
|
||||
S3155000021080A2601C0280010E9012A384113FFFF74A
|
||||
S31550000220961223849012238692102037D237800854
|
||||
S31550000230941020B5D437800B900F2001213FFFF743
|
||||
S31550000240AB2A201392142386110001E1D41780099A
|
||||
S3155000025090122154A2142384A4054008D617801165
|
||||
S3155000026090100012400002289210202080A22000F8
|
||||
S31550000270028000CA11140005B0100010B21000110F
|
||||
S31550000280A0102000113FFFEA80A420000280000445
|
||||
S315500002909212225511000015921221AA912A60102D
|
||||
S315500002A0A8162386A3322010D617801990048010E2
|
||||
S315500002B0D417801492102002400001DA98100011D1
|
||||
S315500002C080A22000028000B511140005D0148010C1
|
||||
S315500002D080A44008128000B0A004200280A420030D
|
||||
S315500002E004BFFFEA113FFFEA213FFFF79214238430
|
||||
S315500002F0D617800990100012D417801440000202BD
|
||||
S3155000030092102020170001DF9012E3F8D20200006D
|
||||
S31550000310941423E4D225800AA01423E0C02580102B
|
||||
S31550000320D005800A80A23FFF228000BB9012E3FCDA
|
||||
S31550000330113FFFF7A2122384A0122386110001C198
|
||||
S31550000340D417801090122154D61780119210202065
|
||||
S31550000350400001ED90054008110001E9D4178010C6
|
||||
S3155000036090122154D617801192102020400001E699
|
||||
S3155000037090054008110001F1D417801090122154B5
|
||||
S31550000380D617801192102020400001DF90054008BA
|
||||
S31550000390133FFFF8D00D800980A220421280000B37
|
||||
S315500003A0A410001392058009D00A600180A220494A
|
||||
S315500003B03280000721140005D00A600280A2204E28
|
||||
S315500003C022800008D417801021140005400002F640
|
||||
S315500003D09014202890142028400002F39E03FCF02D
|
||||
S315500003E090102000D6178011400001C792100013BC
|
||||
S315500003F080A2200022800069111400051114000506
|
||||
S31550000400400002E990122030400000BE010000007A
|
||||
S3155000041011000007A81223FFB010001480A4801406
|
||||
S31550000420148000031300000892100012113FFFF8C9
|
||||
S315500004304000036F90058008A2922000028000734E
|
||||
S31550000440A010200080A40011B40680111A8000214B
|
||||
S31550000450A4248011333FFFF71100003FAA1223FF57
|
||||
S31550000460BA1663849810001092102000A00420023F
|
||||
S31550000470173FFFF89005800CD40A000B932A6008AA
|
||||
S315500004809803200180A3001006BFFFFB9212400A7A
|
||||
S31550000490912A60109932201080A300150280000A1C
|
||||
S315500004A090166386D417800892102002D617801DA6
|
||||
S315500004B04000015C9010001B80A220000280003793
|
||||
S315500004C01114000580A400110ABFFFE7B606E0022A
|
||||
S315500004D0900E801880A0000892603FFF80A0001206
|
||||
S315500004E090603FFF809240080280000680A68013ED
|
||||
S315500004F011140005400002AC9012203080A68013E3
|
||||
S3155000050012BFFFC880A480149410200080A28013CC
|
||||
S315500005101680000996102000D21280009132600891
|
||||
S315500005209002C0089402A00280A2801306BFFFFB6F
|
||||
S3155000053096020009920AE0FF900DE0FF80A2400863
|
||||
S31550000540028000041114000510BFFFA49012203839
|
||||
S31550000550153FFFF79012A3E0D205800880A26001F4
|
||||
S31550000560128000109212A3849012A386D41780088A
|
||||
S3155000057098102A01D6178009110001DF901223FC2A
|
||||
S31550000580400001289210200280A22000128000060E
|
||||
S31550000590211400051114000510BFFF909012202061
|
||||
S315500005A02114000540000280901420404000027E35
|
||||
S315500005B090142040901020F013080013D0302000E3
|
||||
S315500005C092126020D012400015200000900A3FFE83
|
||||
S315500005D0D03240009612A04C90102010D022C0006D
|
||||
S315500005E0D802C0009412A0B813080004D822800084
|
||||
S315500005F092126014D0024000900A3FFED022400072
|
||||
S3155000060010800000010000001114000510BFFF7398
|
||||
S3155000061090122048D20200001102807FD225800A13
|
||||
S31550000620901223FFD0258010D205800AD005801065
|
||||
S3155000063080A2400832BFFF40113FFFF790102001C3
|
||||
S31550000640D025801010BFFF3C113FFFF7D61780080A
|
||||
S31550000650921AE0B980A0000994603FFF901AE0DA40
|
||||
S3155000066080A0000892603FFF8092800902BFFEED95
|
||||
S31550000670113FFFF780A2E0DA22BFFEF0B81020014A
|
||||
S3155000068010BFFEEF900F20012114000540000246D6
|
||||
S315500006909014205030BFFFFE01000000941020F04F
|
||||
S315500006A019080013D430200098132020170800048E
|
||||
S315500006B0D41300008212E01417200000940ABFFEE3
|
||||
S315500006C09A12E0B8D4330000900A20FF9612E04CFC
|
||||
S315500006D0D222C00080A22001128000070100000033
|
||||
S315500006E0D202C000D2234000D0004000900A3FFE04
|
||||
S315500006F0D02040000100000081C3E0080100000046
|
||||
S315500007001308000492126014D00240009012200187
|
||||
S31550000710D02240000100000081C3E0080100000023
|
||||
S315500007209C03BF90D233A066D213A06696100008E1
|
||||
S31550000730920A6080D012000080A0000994402000E8
|
||||
S31550000740900A208080A000089240200080A2400A93
|
||||
S315500007500280000D01000000D012C000808A2020C7
|
||||
S315500007601280000901000000D012C000900A2080BB
|
||||
S3155000077080A000089240200080A2400A12BFFFF7D6
|
||||
S3155000078001000000D012C000900A208080A000080E
|
||||
S3155000079090402000901A000A901A20010100000093
|
||||
S315500007A081C3E0089C23BF909DE3BF90B20E60FFCB
|
||||
S315500007B0A0100018C027BFF480A660BA14800006A7
|
||||
S315500007C080A660DA80A660B916800006153FFFEA5B
|
||||
S315500007D080A660B512800027B0102000153FFFEAB2
|
||||
S315500007E096102AAA9412A2AA13000015D432C00059
|
||||
S315500007F09212615598102554113FFFE0D2330000F4
|
||||
S3155000080090122080D032C000D432C000D2330000C3
|
||||
S315500008101100000C2300003F90122030130000C33B
|
||||
S31550000820D0340000A412613FB21463FF921463FFE8
|
||||
S315500008307FFFFFBC90100010B0100008D007BFF427
|
||||
S3155000084090022001D027BFF4D214000080A64009A0
|
||||
S315500008500280000880A620011280000601000000D8
|
||||
S31550000860D007BFF480A2001208BFFFF2921463FFB4
|
||||
S31550000870D007BFF4130000C39212613F80A2400814
|
||||
S3155000088094403FFFB00E000A0100000081C7E00807
|
||||
S3155000089081E80000153FFFEA98102AAA9412A2AAEE
|
||||
S315500008A0D4330000170000159612E155153FFFE4AA
|
||||
S315500008B0D63025549412A090D4330000D61022007E
|
||||
S315500008C09A100008960AE0FFD6320000901030F0D9
|
||||
S315500008D0D0330000D613400098100009901AE03724
|
||||
S315500008E080A0000894603FFF901AE01C80A000088A
|
||||
S315500008F092603FFF8092800912800007821020008C
|
||||
S3155000090080A2E0C20280000480A2E0201280004251
|
||||
S3155000091090102000113FFFEA94102AAA901222AAA2
|
||||
S31550000920D03280001300001592126155113FFFE43A
|
||||
S31550000930D230255490122090D0328000D21022020C
|
||||
S31550000940901030F0920A60FFD2330000D03280000F
|
||||
S31550000950D013400080A220370280002A80A2202097
|
||||
S31550000960D41300000280001D912AA0109002BF47A8
|
||||
S31550000970912A201091322010952AA01080A2200290
|
||||
S315500009809532A01092602000901AA0B580A0000861
|
||||
S31550000990920A600190603FFF809240083280000BBF
|
||||
S315500009A08210200180A2A0B90280000A80A2A0BABB
|
||||
S315500009B00280000880A2A0EF0280000680A2A0DA82
|
||||
S315500009C02280000282102001108000139010000136
|
||||
S315500009D010BFFFFE821020019132201080A220EE1F
|
||||
S315500009E012BFFFE49002BF479010201CD033400046
|
||||
S315500009F0921020B9D233000010BFFFDD941020B9F9
|
||||
S31550000A00D413000080A2A03402BFFFF880A2202099
|
||||
S31550000A1030BFFFD50100000081C3E008010000008F
|
||||
S31550000A209DE3BF88B72EE010C037BFF4B736E0104D
|
||||
S31550000A30A0100018C027BFEC80A6E0BA14800006AC
|
||||
S31550000A4080A6E0DA80A6E0B916800006113FFFEADC
|
||||
S31550000A5080A6E0B512800023B0102000113FFFEAB7
|
||||
S31550000A6094102AAA901222AAD032800013000015A0
|
||||
S31550000A7092126155113FFFE8D2302554901220A0B2
|
||||
S31550000A80D0328000F837BFF2D017BFF2130000C340
|
||||
S31550000A90D0340000B612613FD217BFF27FFFFF215C
|
||||
S31550000AA090100010B0100008D007BFEC9002200143
|
||||
S31550000AB0D027BFECD2140000D017BFF280A2000995
|
||||
S31550000AC00280000880A62001128000060100000066
|
||||
S31550000AD0D007BFEC80A2001B08BFFFF0010000004A
|
||||
S31550000AE0D007BFEC130000C39212613F80A24008AA
|
||||
S31550000AF094403FFFB00E000A0100000081C7E00895
|
||||
S31550000B0081E800009DE3BF9811140005D4022150DE
|
||||
S31550000B10A210200080A4400AA410001B9A102000A6
|
||||
S31550000B20A0102000A610200116800012961020005A
|
||||
S31550000B30912EA010B5322010932EE0109810000A76
|
||||
S31550000B40111400059332601094122060D002A00C4C
|
||||
S31550000B5080A2001A22800048D002A0109602E0011E
|
||||
S31550000B6080A2C00C06BFFFFA9402A05011140005D3
|
||||
S31550000B70D202215080A2C009028000449010200168
|
||||
S31550000B8080A6200008800016912AE0029002000BF1
|
||||
S31550000B9013140005B4126060992A20049E10200197
|
||||
S31550000BA0912C200290020010912A200290030008F6
|
||||
S31550000BB09002001AD4022004A2046001D202200836
|
||||
S31550000BC080A4400A932BC0099A034009A0643FFFB2
|
||||
S31550000BD080A6000D18BFFFF4912C200280A660005D
|
||||
S31550000BE00480001F932AE0029202400BB60CA0FF2D
|
||||
S31550000BF011140005A4122060B52A60049210001B3F
|
||||
S31550000C007FFFFEEA90100018932C200292024010AB
|
||||
S31550000C10932A6002920680099402401280A2200014
|
||||
S31550000C2002800013A2046001D202A0089010200195
|
||||
S31550000C30912A000980A64008B00600080680000ADE
|
||||
S31550000C40B2264008D002A00480A44008A0643FFF0A
|
||||
S31550000C5080A6600014BFFFEB9210001B1080000BA3
|
||||
S31550000C6090100013108000099010200110BFFFFC57
|
||||
S31550000C70A610200080A2000932BFFFBA9602E001FA
|
||||
S31550000C8010BFFFBC1114000581C7E00891E80008A9
|
||||
S31550000C9013140005D40A61801708000013000013CE
|
||||
S31550000CA09212630C952AA00294028009D202C00ABD
|
||||
S31550000CB0941000089132601F80A22001028000002B
|
||||
S31550000CC09132601D808A20012280000490102001FC
|
||||
S31550000CD0C022800030800002D022800081C3E0080C
|
||||
S31550000CE09010000911140005D20A21801508000041
|
||||
S31550000CF0110000139012230C932A600292024008AE
|
||||
S31550000D00D20280099132601F80A220010280000029
|
||||
S31550000D100100000081C3E008901000099DE3BF90D8
|
||||
S31550000D2011140005E00A2180B00E20FF11140005B1
|
||||
S31550000D3090122154B12E2002E2020018A12C20025A
|
||||
S31550000D40110000139012230CA00400087FFFFFD15E
|
||||
S31550000D509007BFF4D207BFF411060000932A601E15
|
||||
S31550000D60921240112308000092124008D2244010DB
|
||||
S31550000D707FFFFFC89007BFF4D207BFF411070000EA
|
||||
S31550000D80932A601E92124008D22440107FFFFFC162
|
||||
S31550000D909007BFF4D207BFF411030000932A601ED8
|
||||
S31550000DA092124008D22440107FFFFFBA9007BFF43A
|
||||
S31550000DB0D207BFF41104000090122003932A601E3C
|
||||
S31550000DC092124008D22440107FFFFFB29007BFF422
|
||||
S31550000DD0D207BFF411050000932A601E92124008F4
|
||||
S31550000DE0D22440107FFFFFC0010000000100000028
|
||||
S31550000DF081C7E00881E800009DE3BF90111400050B
|
||||
S31550000E00E00A218025080000110000139012230CDF
|
||||
S31550000E10A12C2002A00400087FFFFF9E9007BFF47C
|
||||
S31550000E20D207BFF411050000932A601E92124008A3
|
||||
S31550000E30D22480107FFFFF979007BFF4A2100008BE
|
||||
S31550000E40D007BFF427040000912A201E90120013E9
|
||||
S31550000E50D02480107FFFFF8F9007BFF4D207BFF4D6
|
||||
S31550000E6011040004932A601E92124008D224801066
|
||||
S31550000E707FFFFF889007BFF4D007BFF4A20C60FF36
|
||||
S31550000E80912A201E9012001190120013D024801027
|
||||
S31550000E907FFFFF95010000000100000081C7E008B8
|
||||
S31550000EA081E800009DE3BF9011140005D20A21800D
|
||||
S31550000EB02708000011000013932A60029012230C99
|
||||
S31550000EC09202400893326002AC100009AB2A6002CD
|
||||
S31550000ED0AE1000097FFFFF6F9007BFF4D007BFF435
|
||||
S31550000EE023030000912A201E90120011D024C01511
|
||||
S31550000EF07FFFFF7D0100000091322016A08A200F4F
|
||||
S31550000F0032800011A2102000A4100011A32DA002BF
|
||||
S31550000F107FFFFF609007BFF4D207BFF4932A601E8D
|
||||
S31550000F2092124012D224C0117FFFFF6F01000000C1
|
||||
S31550000F3091322016A08A200F02BFFFF60100000052
|
||||
S31550000F40A210200080A440101ABFFFE3A52DE00296
|
||||
S31550000F50290100007FFFFF4F9007BFF4D007BFF471
|
||||
S31550000F60A2046001912A201E90120014D024C012AF
|
||||
S31550000F707FFFFF5D01000000D02E0000808A20FF19
|
||||
S31550000F8002800006B006200180A440100ABFFFF27E
|
||||
S31550000F900100000030BFFFD00100000081C7E0080B
|
||||
S31550000FA081E800009DE3BF9011140005D20A21800C
|
||||
S31550000FB025080000D40E000011000013932A600289
|
||||
S31550000FC09012230C80A2A000028000849202400856
|
||||
S31550000FD0AD2A60109135A012A72A2002AA10000847
|
||||
S31550000FE0A81000137FFFFF2B9007BFF4D007BFF464
|
||||
S31550000FF021030000912A201E90120010D024801345
|
||||
S315500010007FFFFF3901000000900A200680A22006CB
|
||||
S315500010100280001001000000A2100010A12D6002F5
|
||||
S315500010207FFFFF1C9007BFF4D207BFF4932A601EC0
|
||||
S3155000103092124011D22480107FFFFF2B0100000036
|
||||
S31550001040900A200680A2200612BFFFF6010000007B
|
||||
S315500010507FFFFF109007BFF4D007BFF4D20E0000F9
|
||||
S31550001060912A201E90120009D02480147FFFFF1E63
|
||||
S31550001070B0062001D00E000080A2200012BFFFDA79
|
||||
S31550001080010000009135A010D404800880A2A00071
|
||||
S315500010900680004C010000009132A01D808A20017C
|
||||
S315500010A00280004690102001C027BFF4D007BFF43D
|
||||
S315500010B013030000912A201E901200099335A010A8
|
||||
S315500010C0D0248009D404800980A2A0000680003470
|
||||
S315500010D0900AA00680A22006028000169135A01222
|
||||
S315500010E09A1000089E102001972A2002190300002A
|
||||
S315500010F09132A01D808A2001128000039210200098
|
||||
S315500011009210000F912A601E9012000CD024800B72
|
||||
S31550001110D404800B80A2A0000680001A900AA00674
|
||||
S3155000112080A2200612BFFFF49132A01DD227BFF431
|
||||
S315500011309132A01D808A200102800010901020015B
|
||||
S31550001140C027BFF4D007BFF49335A010912A201EB4
|
||||
S31550001150D0248009D404800980A2A00016800021E2
|
||||
S3155000116090100009D404800880A2A00006BFFFFE9C
|
||||
S31550001170010000003080001B10BFFFF3D027BFF4E2
|
||||
S31550001180912B6002D404800880A2A00006BFFFFE07
|
||||
S315500011900100000010BFFFE3900AA006901000095E
|
||||
S315500011A0D404800880A2A00006BFFFFE0100000004
|
||||
S315500011B010BFFFC9900AA00610BFFFBDD027BFF4CD
|
||||
S315500011C0D404800880A2A00006BFFFFE01000000E4
|
||||
S315500011D010BFFFB39132A01D10BFFFABAD2A6010F8
|
||||
S315500011E00100000081C7E00881E800009DE3BF9838
|
||||
S315500011F035140005F60EA180921000183500001324
|
||||
S31550001200B416A30CB72EE002B606C01A992EE010FB
|
||||
S31550001210B53320129B2EA002A210001AA610001958
|
||||
S315500012203B080000961020009410000DA410001AE0
|
||||
S31550001230F807400D80A7200006800064B137201DB6
|
||||
S31550001240B00E200180A00018B0603FFFB12E201EC6
|
||||
S3155000125033030000B0160019F027400AF807400A79
|
||||
S3155000126080A7200006800052B1372016B48E200F7A
|
||||
S315500012701280001A82102000B3332012310003D09E
|
||||
S31550001280901000199E162240B32E600237030000BC
|
||||
S3155000129080A0400F8200600118800053B0102000DB
|
||||
S315500012A0B137201DB00E200180A00018B0603FFF5E
|
||||
S315500012B0B12E201EB016001BF0274019F807401912
|
||||
S315500012C080A7200006800033B1372016B48E200F39
|
||||
S315500012D002BFFFF180A0400F8210200080A0401A6C
|
||||
S315500012E01ABFFFD4B1332012B72E20029010001827
|
||||
S315500012F09E10001BA0100018F807401B80A7200066
|
||||
S315500013000680001DB137201DB00E200180A00018A8
|
||||
S31550001310B0603FFFB12E201E33010000B0160019F9
|
||||
S31550001320F027400FF807400F80A720000680000CDA
|
||||
S31550001330B12C20029602E001F82A400080A2C01388
|
||||
S3155000134002800029B010000B8200600180A0401A74
|
||||
S315500013500ABFFFEA9202600130BFFFB6F807401895
|
||||
S3155000136080A7200006BFFFFE0100000010BFFFF35C
|
||||
S315500013709602E001B12A2002F807401880A7200003
|
||||
S3155000138006BFFFFE0100000010BFFFE0B137201D71
|
||||
S31550001390B12A2002F807401880A7200006BFFFFE9A
|
||||
S315500013A00100000010BFFFCAB1372016B12CA002B1
|
||||
S315500013B0F807401880A7200006BFFFFE0100000076
|
||||
S315500013C010BFFFABB1372016B12C6002F80740189A
|
||||
S315500013D080A7200006BFFFFE0100000010BFFF9946
|
||||
S315500013E0B137201D0100000081C7E00881E80000E8
|
||||
S315500013F09DE3BF987FFFFE81B00E20FF7FFFFE4822
|
||||
S3155000140081E800000100000000000000000000001C
|
||||
S315500014100000000000000000000000000000000076
|
||||
S315500014204572726F723400004572726F72330000EB
|
||||
S315500014304F4B0000000000004572726F7232000080
|
||||
S31550001440454E4400000000004572726F7235000030
|
||||
S315500014504572726F723100000000000000000000FB
|
||||
S3155000146000000000000000010000000E00000037E0
|
||||
S31550001470000000B500004000000000030000000D11
|
||||
S3155000148000000037000000B5000080000000000496
|
||||
S315500014900000000F00000037000000B500010000FA
|
||||
S315500014A00000000B0000001000000037000000B5DF
|
||||
S315500014B00000000000000007000000100000001CA3
|
||||
S315500014C0000000B900007000000000080000000F86
|
||||
S315500014D00000001C000000B9000078000000000A5F
|
||||
S315500014E00000000D0000001C000000B900007C0048
|
||||
S315500014F00000000B0000000E0000001C000000B9A8
|
||||
S31550001500000000000000000F000000100000001C4A
|
||||
S31550001510000000DA00007000000000100000000F0C
|
||||
S315500015200000001C000000DA0000700000000012ED
|
||||
S315500015300000000D0000001C000000DA00007000E2
|
||||
S31550001540000000130000000E0000001C000000DA2E
|
||||
S3155000155000000003000001FB000000FD0000007EBB
|
||||
S315500015600000003F0000002A000000150000000A9D
|
||||
S3115000157000000000000000000000000019
|
||||
S70550000000AA
|
1
ao-tools/ao-stmload/.gitignore
vendored
Normal file
1
ao-tools/ao-stmload/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-stmload
|
16
ao-tools/ao-stmload/Makefile.am
Normal file
16
ao-tools/ao-stmload/Makefile.am
Normal file
@@ -0,0 +1,16 @@
|
||||
if LIBSTLINK
|
||||
|
||||
bin_PROGRAMS=ao-stmload
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(STLINK_CFLAGS) $(LIBUSB_CFLAGS)
|
||||
AO_STMLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_stmload_DEPENDENCIES = $(AO_STMLOAD_LIBS)
|
||||
|
||||
ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(STLINK_LIBS) $(LIBUSB_LIBS) -lelf
|
||||
|
||||
ao_stmload_SOURCES=ao-stmload.c ao-stmload.h
|
||||
|
||||
man_MANS = ao-stmload.1
|
||||
|
||||
endif
|
61
ao-tools/ao-stmload/ao-stmload.1
Normal file
61
ao-tools/ao-stmload/ao-stmload.1
Normal file
@@ -0,0 +1,61 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-LOAD 1 "ao-stmload" ""
|
||||
.SH NAME
|
||||
ao-stmload \- flash a program to an STM32-based AltOS device
|
||||
.SH SYNOPSIS
|
||||
.B "ao-stmload"
|
||||
[\-D \fI/dev/sgX\fP]
|
||||
[\--device \fI/dev/sgX\fP]
|
||||
[\--cal \fIradio-calibration\fP]
|
||||
[\--serial \fserial-number\fP]
|
||||
\fIfile.elf\fP
|
||||
.SH DESCRIPTION
|
||||
.I ao-stmload
|
||||
loads the specified .elf file into the target device flash memory,
|
||||
using either existing serial number and radio calibration values or
|
||||
taking either of those from the command line.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-D /dev/sgX | --device /dev/sgX
|
||||
This targets an STlinkV1 connection rather than STlinkV2
|
||||
.TP
|
||||
\-s serial-number | --serial serial-number
|
||||
This programs the device serial number into the image. If no serial
|
||||
number is specified, then the existing serial number, if any, will be
|
||||
read from the device.
|
||||
.TP
|
||||
\-c radio-calibration | --cal radio-calibration This programs the
|
||||
radio calibration value into the image for hardware which doesn't have
|
||||
any eeprom storage for this value. If no calibration value is
|
||||
specified, an existing calibration value will be used. The value here
|
||||
can be computed given the current radio calibration value, the
|
||||
measured frequency and the desired frequency:
|
||||
.IP
|
||||
cal' = cal * (desired/measured)
|
||||
.IP
|
||||
The default calibration value is 7119667.
|
||||
.SH USAGE
|
||||
.I ao-stmload
|
||||
reads the specified .elf file into memory, edits the image to
|
||||
customize it using the specified serial number and radio calibration
|
||||
values. It then connects to the debug dongle and writes the program to
|
||||
the target device flash memory.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
338
ao-tools/ao-stmload/ao-stmload.c
Normal file
338
ao-tools/ao-stmload/ao-stmload.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright © 2012 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "stlink-common.h"
|
||||
#include "ao-elf.h"
|
||||
#include "ccdbg.h"
|
||||
#include "cc.h"
|
||||
#include "ao-stmload.h"
|
||||
#include "ao-selfload.h"
|
||||
#include "ao-verbose.h"
|
||||
#include "ao-editaltos.h"
|
||||
|
||||
|
||||
/*
|
||||
* Read a 16-bit value from the target device with arbitrary
|
||||
* alignment
|
||||
*/
|
||||
static uint16_t
|
||||
get_uint16_sl(stlink_t *sl, uint32_t addr)
|
||||
{
|
||||
const uint8_t *data = sl->q_buf;
|
||||
uint32_t actual_addr;
|
||||
int off;
|
||||
uint16_t result;
|
||||
|
||||
sl->q_len = 0;
|
||||
|
||||
|
||||
actual_addr = addr & ~3;
|
||||
|
||||
stlink_read_mem32(sl, actual_addr, 8);
|
||||
|
||||
if (sl->q_len != 8)
|
||||
abort();
|
||||
|
||||
off = addr & 3;
|
||||
result = data[off] | (data[off + 1] << 8);
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
get_uint16(stlink_t *sl, uint32_t addr)
|
||||
{
|
||||
uint16_t result;
|
||||
result = get_uint16_sl(sl, addr);
|
||||
printf ("read 0x%08x = 0x%04x\n", addr, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 32-bit value from the target device with arbitrary
|
||||
* alignment
|
||||
*/
|
||||
static uint32_t
|
||||
get_uint32_sl(stlink_t *sl, uint32_t addr)
|
||||
{
|
||||
const uint8_t *data = sl->q_buf;
|
||||
uint32_t actual_addr;
|
||||
int off;
|
||||
uint32_t result;
|
||||
|
||||
sl->q_len = 0;
|
||||
|
||||
printf ("read 0x%x\n", addr);
|
||||
|
||||
actual_addr = addr & ~3;
|
||||
|
||||
stlink_read_mem32(sl, actual_addr, 8);
|
||||
|
||||
if (sl->q_len != 8)
|
||||
abort();
|
||||
|
||||
off = addr & 3;
|
||||
result = data[off] | (data[off + 1] << 8) | (data[off+2] << 16) | (data[off+3] << 24);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 32-bit value from the target device with arbitrary
|
||||
* alignment
|
||||
*/
|
||||
static uint32_t
|
||||
get_uint32(stlink_t *sl, uint32_t addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = get_uint32_sl(sl, addr);
|
||||
printf ("read 0x%08x = 0x%08x\n", addr, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if the target device has been
|
||||
* flashed with a similar firmware image before
|
||||
*
|
||||
* This is done by looking for the same romconfig version,
|
||||
* which should be at the same location as the linker script
|
||||
* places this at 0x100 from the start of the rom section
|
||||
*/
|
||||
static int
|
||||
check_flashed(stlink_t *sl)
|
||||
{
|
||||
uint16_t romconfig_version = get_uint16(sl, AO_ROMCONFIG_VERSION);
|
||||
uint16_t romconfig_check = get_uint16(sl, AO_ROMCONFIG_CHECK);
|
||||
|
||||
if (romconfig_version != (uint16_t) ~romconfig_check) {
|
||||
fprintf (stderr, "Device has not been flashed before\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "v1", .has_arg = 0, .val = '1' },
|
||||
{ .name = "raw", .has_arg = 0, .val = 'r' },
|
||||
{ .name = "cal", .has_arg = 1, .val = 'c' },
|
||||
{ .name = "serial", .has_arg = 1, .val = 's' },
|
||||
{ .name = "verbose", .has_arg = 1, .val = 'v' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--v1] [--raw] [--verbose=<verbose>] [--cal=<radio-cal>] [--serial=<serial>] file.{elf,ihx}\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
done(stlink_t *sl, int code)
|
||||
{
|
||||
stlink_reset(sl);
|
||||
stlink_run(sl);
|
||||
stlink_exit_debug_mode(sl);
|
||||
stlink_close(sl);
|
||||
exit (code);
|
||||
}
|
||||
|
||||
static int
|
||||
ends_with(char *whole, char *suffix)
|
||||
{
|
||||
int whole_len = strlen(whole);
|
||||
int suffix_len = strlen(suffix);
|
||||
|
||||
if (suffix_len > whole_len)
|
||||
return 0;
|
||||
return strcmp(whole + whole_len - suffix_len, suffix) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int stlink_v1 = 0;
|
||||
int raw = 0;
|
||||
char *filename;
|
||||
Elf *e;
|
||||
char *serial_end;
|
||||
unsigned int serial = 0;
|
||||
char *serial_ucs2;
|
||||
int serial_ucs2_len;
|
||||
char serial_int[2];
|
||||
unsigned int s;
|
||||
int i;
|
||||
int string_num;
|
||||
uint32_t cal = 0;
|
||||
char cal_int[4];
|
||||
char *cal_end;
|
||||
int c;
|
||||
stlink_t *sl = NULL;
|
||||
int was_flashed = 0;
|
||||
struct ao_hex_image *load;
|
||||
int tries;
|
||||
int success;
|
||||
int verbose = 0;
|
||||
struct ao_sym *file_symbols;
|
||||
int num_file_symbols;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "1rc:s:v:", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case '1':
|
||||
stlink_v1 = 1;
|
||||
break;
|
||||
case 'r':
|
||||
raw = 1;
|
||||
break;
|
||||
case 'c':
|
||||
cal = strtoul(optarg, &cal_end, 10);
|
||||
if (cal_end == optarg || *cal_end != '\0')
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 's':
|
||||
serial = strtoul(optarg, &serial_end, 10);
|
||||
if (serial_end == optarg || *serial_end != '\0')
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ao_verbose = verbose;
|
||||
|
||||
if (verbose > 1)
|
||||
ccdbg_add_debug(CC_DEBUG_BITBANG);
|
||||
|
||||
filename = argv[optind];
|
||||
if (filename == NULL)
|
||||
usage(argv[0]);
|
||||
|
||||
if (ends_with (filename, ".elf")) {
|
||||
load = ao_load_elf(filename, &file_symbols, &num_file_symbols);
|
||||
} else if (ends_with (filename, ".ihx")) {
|
||||
load = ao_hex_load(filename, &file_symbols, &num_file_symbols);
|
||||
} else
|
||||
usage(argv[0]);
|
||||
|
||||
if (!raw) {
|
||||
if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) {
|
||||
fprintf(stderr, "Cannot find required symbols\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect to the programming dongle
|
||||
*/
|
||||
|
||||
for (tries = 0; tries < 3; tries++) {
|
||||
if (stlink_v1) {
|
||||
sl = stlink_v1_open(50);
|
||||
} else {
|
||||
sl = stlink_open_usb(50);
|
||||
|
||||
}
|
||||
if (!sl) {
|
||||
fprintf (stderr, "No STLink devices present\n");
|
||||
done (sl, 1);
|
||||
}
|
||||
|
||||
if (sl->chip_id != 0)
|
||||
break;
|
||||
stlink_reset(sl);
|
||||
stlink_close(sl);
|
||||
sl = NULL;
|
||||
}
|
||||
if (!sl) {
|
||||
fprintf (stderr, "Debugger connection failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Verify that the loaded image fits entirely within device flash
|
||||
*/
|
||||
if (load->address < sl->flash_base ||
|
||||
sl->flash_base + sl->flash_size < load->address + load->length) {
|
||||
fprintf (stderr, "\%s\": Invalid memory range 0x%08x - 0x%08x\n", filename,
|
||||
load->address, load->address + load->length);
|
||||
done(sl, 1);
|
||||
}
|
||||
|
||||
/* Enter debugging mode
|
||||
*/
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE)
|
||||
stlink_exit_dfu_mode(sl);
|
||||
|
||||
if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
|
||||
stlink_enter_swd_mode(sl);
|
||||
|
||||
|
||||
if (!raw) {
|
||||
/* Go fetch existing config values
|
||||
* if available
|
||||
*/
|
||||
was_flashed = check_flashed(sl);
|
||||
|
||||
if (!serial) {
|
||||
if (!was_flashed) {
|
||||
fprintf (stderr, "Must provide serial number\n");
|
||||
done(sl, 1);
|
||||
}
|
||||
serial = get_uint16(sl, AO_SERIAL_NUMBER);
|
||||
if (!serial || serial == 0xffff) {
|
||||
fprintf (stderr, "Invalid existing serial %d\n", serial);
|
||||
done(sl, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cal && AO_RADIO_CAL && was_flashed) {
|
||||
cal = get_uint32(sl, AO_RADIO_CAL);
|
||||
if (!cal || cal == 0xffffffff) {
|
||||
fprintf (stderr, "Invalid existing rf cal %d\n", cal);
|
||||
done(sl, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ao_editaltos(load, serial, cal))
|
||||
done(sl, 1);
|
||||
}
|
||||
|
||||
/* And flash the resulting image to the device
|
||||
*/
|
||||
|
||||
success = (stlink_write_flash(sl, load->address, load->data, load->length) >= 0);
|
||||
|
||||
if (!success) {
|
||||
fprintf (stderr, "\"%s\": Write failed\n", filename);
|
||||
done(sl, 1);
|
||||
}
|
||||
|
||||
done(sl, 0);
|
||||
}
|
37
ao-tools/ao-stmload/ao-stmload.h
Normal file
37
ao-tools/ao-stmload/ao-stmload.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright © 2013 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#ifndef _AO_STMLOAD_H_
|
||||
#define _AO_STMLOAD_H_
|
||||
|
||||
#include "ao-elf.h"
|
||||
|
||||
#define AO_BOOT_APPLICATION_BASE 0x08001000
|
||||
|
||||
extern struct ao_sym ao_symbols[];
|
||||
|
||||
extern int ao_num_symbols;
|
||||
extern int ao_num_required_symbols;
|
||||
|
||||
void
|
||||
ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]);
|
||||
|
||||
void
|
||||
ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]);
|
||||
|
||||
#endif /* _AO_STMLOAD_H_ */
|
1
ao-tools/ao-telem/.gitignore
vendored
Normal file
1
ao-tools/ao-telem/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-telem
|
12
ao-tools/ao-telem/Makefile.am
Normal file
12
ao-tools/ao-telem/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
bin_PROGRAMS=ao-telem
|
||||
|
||||
AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS)
|
||||
AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a
|
||||
|
||||
ao_telem_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS)
|
||||
|
||||
ao_telem_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
ao_telem_SOURCES = ao-telem.c
|
||||
|
||||
man_MANS = ao-telem.1
|
36
ao-tools/ao-telem/ao-telem.1
Normal file
36
ao-tools/ao-telem/ao-telem.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.\"
|
||||
.\" 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; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\"
|
||||
.TH AO-TELEM 1 "ao-telem" ""
|
||||
.SH NAME
|
||||
ao-telem \- Analyze a telemetry log
|
||||
.SH SYNOPSIS
|
||||
.B "ao-telem"
|
||||
[\--crc]
|
||||
{flight.telem} ...
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-c | --crc
|
||||
This option makes ao-telem analyze records with CRC errors. By
|
||||
default, these records are skipped.
|
||||
.SH DESCRIPTION
|
||||
.I ao-telem
|
||||
reads the specified telemetry log and display the contents of each
|
||||
record.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
255
ao-tools/ao-telem/ao-telem.c
Normal file
255
ao-tools/ao-telem/ao-telem.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright © 2011 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "cc.h"
|
||||
|
||||
static const struct option options[] = {
|
||||
{ .name = "crc", .has_arg = 0, .val = 'c' },
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static void usage(char *program)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [--crc] {flight.telem} ...\n",program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define bool(b) ((b) ? "true" : "false")
|
||||
|
||||
static int ignore_crc;
|
||||
|
||||
static void
|
||||
process(FILE *file)
|
||||
{
|
||||
char line[1024];
|
||||
int c;
|
||||
|
||||
while (fgets(line, sizeof (line), file)) {
|
||||
union ao_telemetry_all telem;
|
||||
char call[AO_MAX_CALLSIGN+1];
|
||||
char version[AO_MAX_VERSION+1];
|
||||
|
||||
if (cc_telemetry_parse(line, &telem)) {
|
||||
int rssi = (int8_t) telem.generic.rssi / 2 - 74;
|
||||
|
||||
printf ("serial %5d rssi %d status %02x tick %5d type %3d ",
|
||||
telem.generic.serial, rssi, telem.generic.status,
|
||||
telem.generic.tick, telem.generic.type);
|
||||
if (!ignore_crc && (telem.generic.status & (1 << 7)) == 0) {
|
||||
printf ("CRC error\n");
|
||||
continue;
|
||||
}
|
||||
switch (telem.generic.type) {
|
||||
case AO_TELEMETRY_SENSOR_TELEMETRUM:
|
||||
case AO_TELEMETRY_SENSOR_TELEMINI:
|
||||
case AO_TELEMETRY_SENSOR_TELENANO:
|
||||
printf ("state %1d accel %5d pres %5d ",
|
||||
telem.sensor.state, telem.sensor.accel, telem.sensor.pres);
|
||||
printf ("accel %6.2f speed %6.2f height %5d ",
|
||||
telem.sensor.acceleration / 16.0,
|
||||
telem.sensor.speed / 16.0,
|
||||
telem.sensor.height);
|
||||
printf ("ground_pres %5d ground_accel %5d accel_plus %5d accel_minus %5d\n",
|
||||
telem.sensor.ground_pres,
|
||||
telem.sensor.ground_accel,
|
||||
telem.sensor.accel_plus_g,
|
||||
telem.sensor.accel_minus_g);
|
||||
break;
|
||||
case AO_TELEMETRY_CONFIGURATION:
|
||||
memcpy(call, telem.configuration.callsign, AO_MAX_CALLSIGN);
|
||||
memcpy(version, telem.configuration.version, AO_MAX_VERSION);
|
||||
call[AO_MAX_CALLSIGN] = '\0';
|
||||
version[AO_MAX_CALLSIGN] = '\0';
|
||||
printf ("device %3d flight %5d config %3d.%03d delay %2d main %4d log_max %5d",
|
||||
telem.configuration.device,
|
||||
telem.configuration.flight,
|
||||
telem.configuration.config_major,
|
||||
telem.configuration.config_minor,
|
||||
telem.configuration.apogee_delay,
|
||||
telem.configuration.main_deploy,
|
||||
telem.configuration.flight_log_max);
|
||||
printf (" call %8s version %8s\n", call, version);
|
||||
break;
|
||||
case AO_TELEMETRY_LOCATION:
|
||||
printf ("sats %d flags %s%s%s%s",
|
||||
telem.location.flags & 0xf,
|
||||
(telem.location.flags & (1 << 4)) ? "valid" : "invalid",
|
||||
(telem.location.flags & (1 << 5)) ? ",running" : "",
|
||||
(telem.location.flags & (1 << 6)) ? ",date" : "",
|
||||
(telem.location.flags & (1 << 7)) ? ",course" : "");
|
||||
printf (" alt %5d lat %12.7f lon %12.7f",
|
||||
AO_TELEMETRY_LOCATION_ALTITUDE(&telem.location),
|
||||
telem.location.latitude / 1e7,
|
||||
telem.location.longitude / 1e7);
|
||||
if ((telem.location.flags & (1 << 6)) != 0) {
|
||||
printf (" year %2d month %2d day %2d",
|
||||
telem.location.year,
|
||||
telem.location.month,
|
||||
telem.location.day);
|
||||
printf (" hour %2d minute %2d second %2d",
|
||||
telem.location.hour,
|
||||
telem.location.minute,
|
||||
telem.location.second);
|
||||
}
|
||||
printf (" pdop %3.1f hdop %3.1f vdop %3.1f mode %d",
|
||||
telem.location.pdop / 5.0,
|
||||
telem.location.hdop / 5.0,
|
||||
telem.location.vdop / 5.0,
|
||||
telem.location.mode);
|
||||
if ((telem.location.flags & (1 << 7)) != 0)
|
||||
printf (" ground_speed %6.2f climb_rate %6.2f course %d",
|
||||
telem.location.ground_speed / 100.0,
|
||||
telem.location.climb_rate / 100.0,
|
||||
telem.location.course * 2);
|
||||
printf ("\n");
|
||||
break;
|
||||
case AO_TELEMETRY_SATELLITE:
|
||||
printf ("sats %d", telem.satellite.channels);
|
||||
for (c = 0; c < 12 && c < telem.satellite.channels; c++) {
|
||||
printf (" sat %d svid %d c_n_1 %d",
|
||||
c,
|
||||
telem.satellite.sats[c].svid,
|
||||
telem.satellite.sats[c].c_n_1);
|
||||
}
|
||||
printf ("\n");
|
||||
break;
|
||||
case AO_TELEMETRY_MEGA_SENSOR_MPU:
|
||||
case AO_TELEMETRY_MEGA_SENSOR_BMX160:
|
||||
printf ("orient %3d accel %5d pres %9d temp %5d accel_x %5d accel_y %5d accel_z %5d gyro_x %5d gyro_y %5d gyro_z %5d mag_x %5d mag_y %5d mag_z %5d\n",
|
||||
telem.mega_sensor.orient,
|
||||
telem.mega_sensor.accel,
|
||||
telem.mega_sensor.pres,
|
||||
telem.mega_sensor.temp,
|
||||
telem.mega_sensor.accel_x,
|
||||
telem.mega_sensor.accel_y,
|
||||
telem.mega_sensor.accel_z,
|
||||
telem.mega_sensor.gyro_x,
|
||||
telem.mega_sensor.gyro_y,
|
||||
telem.mega_sensor.gyro_z,
|
||||
telem.mega_sensor.mag_x,
|
||||
telem.mega_sensor.mag_y,
|
||||
telem.mega_sensor.mag_z);
|
||||
break;
|
||||
case AO_TELEMETRY_COMPANION:
|
||||
printf("board_id %3d update_period %3d channels %2d",
|
||||
telem.companion.board_id,
|
||||
telem.companion.update_period,
|
||||
telem.companion.channels);
|
||||
for (c = 0; c < telem.companion.channels; c++)
|
||||
printf(" %6d", telem.companion.companion_data[c]);
|
||||
printf("\n");
|
||||
break;
|
||||
case AO_TELEMETRY_MEGA_DATA:
|
||||
printf ("state %1d v_batt %5d v_pyro %5d ",
|
||||
telem.mega_data.state,
|
||||
telem.mega_data.v_batt,
|
||||
telem.mega_data.v_pyro);
|
||||
for (c = 0; c < 6; c++)
|
||||
printf ("s%1d %5d ", c,
|
||||
telem.mega_data.sense[c] |
|
||||
(telem.mega_data.sense[c] << 8));
|
||||
|
||||
printf ("ground_pres %5d ground_accel %5d accel_plus %5d accel_minus %5d ",
|
||||
telem.mega_data.ground_pres,
|
||||
telem.mega_data.ground_accel,
|
||||
telem.mega_data.accel_plus_g,
|
||||
telem.mega_data.accel_minus_g);
|
||||
|
||||
printf ("accel %6.2f speed %6.2f height %5d\n",
|
||||
telem.mega_data.acceleration / 16.0,
|
||||
telem.mega_data.speed / 16.0,
|
||||
telem.mega_data.height);
|
||||
|
||||
break;
|
||||
case AO_TELEMETRY_METRUM_SENSOR:
|
||||
printf ("state %1d accel %5d pres %9d temp %6.2f acceleration %6.2f speed %6.2f height %5d v_batt %5d sense_a %5d sense_m %5d\n",
|
||||
telem.metrum_sensor.state,
|
||||
telem.metrum_sensor.accel,
|
||||
telem.metrum_sensor.pres,
|
||||
telem.metrum_sensor.temp / 100.0,
|
||||
telem.metrum_sensor.acceleration / 16.0,
|
||||
telem.metrum_sensor.speed / 16.0,
|
||||
telem.metrum_sensor.height,
|
||||
telem.metrum_sensor.v_batt,
|
||||
telem.metrum_sensor.sense_a,
|
||||
telem.metrum_sensor.sense_m);
|
||||
break;
|
||||
case AO_TELEMETRY_METRUM_DATA:
|
||||
printf ("ground_pres %9d ground_accel %5d accel_plus %5d accel_minus %5d\n",
|
||||
telem.metrum_data.ground_pres,
|
||||
telem.metrum_data.ground_accel,
|
||||
telem.metrum_data.accel_plus_g,
|
||||
telem.metrum_data.accel_minus_g);
|
||||
break;
|
||||
case AO_TELEMETRY_MINI:
|
||||
printf ("state %1d v_batt %5d sense_a %5d sense_m %5d pres %9d temp %6.2f acceleration %6.2f speed %6.2f height %5d ground_pres %9d\n",
|
||||
telem.mini.state,
|
||||
telem.mini.v_batt,
|
||||
telem.mini.sense_a,
|
||||
telem.mini.sense_m,
|
||||
telem.mini.pres,
|
||||
telem.mini.temp / 100.0,
|
||||
telem.mini.acceleration / 16.0,
|
||||
telem.mini.speed / 16.0,
|
||||
telem.mini.height,
|
||||
telem.mini.ground_pres);
|
||||
break;
|
||||
default:
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c, i, ret = 0;
|
||||
FILE *file;
|
||||
while ((c = getopt_long(argc, argv, "c", options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
ignore_crc = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (!file) {
|
||||
perror(argv[i]);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
process(file);
|
||||
fclose (file);
|
||||
|
||||
}
|
||||
} else
|
||||
process(stdin);
|
||||
return ret;
|
||||
}
|
1
ao-tools/ao-test-baro/.gitignore
vendored
Normal file
1
ao-tools/ao-test-baro/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ao-test-baro
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user